-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhtml-ttl.min.js
5 lines (5 loc) · 2.69 KB
/
html-ttl.min.js
1
2
3
4
5
/*
HTML Tagged Template Literals 3.0
Author: Anshu Krishna <anshu.krishna5@gmail.com>
*/
const placeholder="~internal_-_placeholder_-_",splitPattern=new RegExp(`${placeholder}[0-9]+`,"g"),groupsPattern=new RegExp(`(?<replace>${placeholder}(?<index>[0-9]+))`,"g"),groupsMapper=({groups:e})=>(e.index=Number(e.index),e),trueObject=e=>"object"==typeof e&&!Array.isArray(e);function stringify(e){if(e instanceof HTMLElement)return String(e.textContent);if(e instanceof Text)return String(e.nodeValue);switch(typeof e){case"object":return JSON.stringify(e);break;case"function":return stringify(e());break}return String(e)}function nodify(e){if(e instanceof HTMLElement||e instanceof Text||e instanceof DocumentFragment)return e;switch(typeof e){case"object":return Array.isArray(e)?e.map(nodify):document.createTextNode(JSON.stringify(e));break;case"function":return nodify(e());break}return document.createTextNode(String(e))}function findTargets(e){const t=[],r=[];for(let n of e?.attributes??[]){const o=[...n.value.matchAll(groupsPattern)];o.length&&t.push({node:n,value:n.value,match:o.map(groupsMapper)});const a=[...n.name.matchAll(groupsPattern)];a.length&&r.push({element:e,attr:n,match:a.map(groupsMapper)})}const n=Array.from(e.childNodes);for(let e of n){if(3!==e.nodeType)continue;const r=[...e.nodeValue.matchAll(groupsPattern)];0!==r.length&&t.push({node:e,value:e.nodeValue,match:r.map(groupsMapper)})}for(let n of e.children){const[e,o]=findTargets(n);for(let r of e)t.push(r);for(let e of o)r.push(e)}return[t,r]}export function HTML(e,...t){const r=[e[0]];for(let n=0,o=t.length;n<o;n++)r.push(`${placeholder}${n}${e[n+1]}`);const n=(e=>{const t=document.createElement("template");return t.innerHTML=e,t.content})(r.join("")),[o,a]=findTargets(n);for(let e of o)switch(e.node.nodeType){case 2:{let r=String(e.value);for(let n of e.match)r=r.replace(n.replace,stringify(t[n.index]));e.node.nodeValue=r}break;case 3:{let r=e.value.split(splitPattern).map((e=>document.createTextNode(e))),n=e.node.parentNode;n.insertBefore(r[0],e.node);for(let o=0,a=e.match.length;o<a;o++){let a=nodify(t[e.match[o].index]);if(Array.isArray(a))for(let t of a)n.insertBefore(t,e.node);else n.insertBefore(a,e.node);n.insertBefore(r[o+1],e.node)}n.removeChild(e.node)}break}for(let e of a){const r=e.element,n=e.attr.nodeValue;let o=e.attr.name;if(1!==e.match.length||("object"!=typeof(i=t[e.match[0].index])||Array.isArray(i))||""!==o.replace(e.match[0].replace,"")){for(let r of e.match)o=o.replace(r.replace,stringify(t[r.index]));r.removeAttribute(e.attr.name),o&&r.setAttribute(o,n)}else{r.removeAttribute(o);for(let[n,o]of Object.entries(t[e.match[0].index]))r.setAttribute(n,o)}}var i;return n.normalize(),1===n.childNodes.length?n.childNodes[0]:n}