{"id":20513675,"url":"https://github.com/webreflection/domtagger","last_synced_at":"2025-07-26T19:11:36.907Z","repository":{"id":57215056,"uuid":"159478635","full_name":"WebReflection/domtagger","owner":"WebReflection","description":"The hyperHTML's template literal parser","archived":false,"fork":false,"pushed_at":"2023-04-05T14:28:56.000Z","size":133,"stargazers_count":45,"open_issues_count":6,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-15T08:56:37.335Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WebReflection.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-11-28T09:42:57.000Z","updated_at":"2025-04-17T07:40:46.000Z","dependencies_parsed_at":"2024-02-01T16:28:02.588Z","dependency_job_id":"ee88f8fa-18f4-4c9e-8908-3202236178b8","html_url":"https://github.com/WebReflection/domtagger","commit_stats":{"total_commits":92,"total_committers":5,"mean_commits":18.4,"dds":"0.48913043478260865","last_synced_commit":"4bb67d341c90a9619df2dfff714e6069350a3162"},"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"purl":"pkg:github/WebReflection/domtagger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebReflection%2Fdomtagger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebReflection%2Fdomtagger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebReflection%2Fdomtagger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebReflection%2Fdomtagger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WebReflection","download_url":"https://codeload.github.com/WebReflection/domtagger/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebReflection%2Fdomtagger/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265509903,"owners_count":23779451,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T21:12:34.899Z","updated_at":"2025-07-26T19:11:36.887Z","avatar_url":"https://github.com/WebReflection.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# domtagger\n\n[![Build Status](https://travis-ci.com/WebReflection/domtagger.svg?branch=master)](https://travis-ci.com/WebReflection/domtagger) [![Coverage Status](https://coveralls.io/repos/github/WebReflection/domtagger/badge.svg?branch=master)](https://coveralls.io/github/WebReflection/domtagger?branch=master) [![Greenkeeper badge](https://badges.greenkeeper.io/WebReflection/domtagger.svg)](https://greenkeeper.io/) ![WebReflection status](https://offline.report/status/webreflection.svg)\n\nThe [hyperHTML](https://github.com/WebReflection/hyperHTML#hyperhtml)'s template literal parser, used to handle all repeated updates per each attribute or node.\n\n  * CDN as global utility, via https://unpkg.com/domtagger\n  * ESM via `import domtagger from 'domtagger'`\n  * CJS via `const domtagger = require('domtagger')`\n\n[Live test](https://webreflection.github.io/domtagger/test/)\n\n### Example\n\nThe tagger accepts a configuration object with mandatory methods that should return a function to invoke per each update.\n\nOptionally, the object could have a `type` property, as either `html` or `svg` string, and a `transform` method that must return some string as content, after receiving the markup that is going to be used.\n\n```js\nvar html = domtagger({\n\n  // can be html or svg\n  type: 'html',\n\n  // how to handle attributes\n  // Note: this callback is simplified for example purpose.\n  // The node is the attribute owner\n  attribute: function (node, name, attribute) {\n    return function (value) {\n      var type = typeof value;\n      if (type === 'boolean' || type === 'function')\n        node[name] = value;\n      else if (value == null)\n        node.removeAttribute(name);\n      else\n        node.setAttribute(name, value);\n    }\n  },\n\n  // how to handle generic content\n  // Note: this callback is simplified for example purpose.\n  // The comment node is the hole placeholder\n  // use domdiff or other techniques to handle nodes\n  any: function (comment, childNodes) {\n    var parentNode = comment.parentNode;\n    return function (html) {\n      parentNode.innerHTML = html;\n    };\n  },\n\n  // how to handle cases where content\n  // can only be some text\n  // The node is one that can only have text\n  text: function (node) {\n    return function (textContent) {\n      node.textContent = textContent;\n    };\n  },\n\n  // OPTIONAL\n  // a man in the middle for the output\n  // The html string is what will be used to generate the content\n  // this is always invoked after sanitizing the template parts\n  transform: function (html) {\n    // it must return the eventually transformed html\n    return html;\n  },\n\n  // for adventurous 3rd parts libraries only:\n  // previously internally known as `sanitize`,\n  // it will run before transform and it must return a *string*\n  // that contains domconstants.UID/UIDC in the right place\n  // or the whole library will break\n  convert: function (template) {\n    // see domsanitizer logic\n    // https://github.com/WebReflection/domsanitizer/blob/master/esm/index.js\n    // or see a possible wrap solution/hint/workaround\n    // https://github.com/WebReflection/domtagger/issues/17#issuecomment-526151473\n    return template.join(domconstants.UIDC).replace(sani, tize);\n  }\n\n});\n\ndocument.body.appendChild(\n  render({\n    onclick: function (e) {\n      alert(e.currentTarget.outerHTML);\n    },\n    html: 'Hello \u003cstrong\u003edomtagger\u003c/strong\u003e!',\n    text: \"isn't this cool?\"\n  })\n);\n\n// render example\nfunction render(model) {\n  return html`\n    \u003cdiv onclick=${model.onclick}\u003e\n      \u003c!--/* html is sanitized as text automatically */--\u003e\n      \u003cdiv\u003e${model.html}\u003c/div\u003e\n      \u003c!--👻 textarea can use value=... or its content --\u003e\n      \u003ctextarea\u003e${model.text}\u003c/textarea\u003e\n    \u003c/div\u003e\n  `;\n}\n```\n\n#### About devs-only comments\n\nIf you'd like to create a dev only comment that will be removed at runtime once parsed, you can either start the comment with a ghost emoji 👻 or use `/*` and `*/` right at the boundaries of the comment.\n\n```html\n\u003c!--👻 dev only --\u003e\n\u003c!--/* also dev only */--\u003e\n\u003c!-- any other regular comment --\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebreflection%2Fdomtagger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebreflection%2Fdomtagger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebreflection%2Fdomtagger/lists"}