-const Config={t:"DooHTML",o:"data-bind",l:"data-template",p:{i:-1,T:0,m:1},u:{BEG:"{{",END:"}}"},N:"data-key",A:"key"},version="v0.97.5",getItemValue=(e,t)=>t.includes(".")?t.split(".").reduce(((e,t)=>e&&void 0!==e[t]?e[t]:""),e):e[t]?e[t]:"",isTable=e=>["TABLE","TBODY","THEAD","TFOOT","TR","TH"].includes(e.tagName),render=(e,t,o=0)=>{0!==t.length?renderHTML(e,t,o):e.textContent=""},renderHTML=(e,t,o=0,a=null)=>{let l,n,d=t.length,s=e.place[0],c=a?o+d:d-o;c>d&&(c=d);let r=s.C.length;const p=(e,o)=>{for(let a=0;a<r;a++)n=getNode(e,s.C[a][1],0),n?"textContent"===s.C[a][2]?n.textContent=t[o][s.C[a][0]]:n.setAttribute(s.C[a][2],t[o][s.C[a][0]]):console.info("Field:"+s.C[a][0]+" does not exist")},i=s.h;for(let e=o;e<c;e++)l=s.D,p(l,e),s.appendChild(l.cloneNode(!0))[Config.A]=getItemValue(t[e],i)},getNode=(e,t,o)=>{let a=t[o];return e.childNodes[a]?getNode(e.childNodes[a],t,++o):e},append=(e,t,o=0)=>{renderHTML(e,t,o,t.length-o)},dooParse=e=>{let t=e.cloneNode(!0);t.removeAttribute(Config.o),t.removeAttribute("data-key");let o=t.outerHTML.replace(/\t/g,"").replace(/\n/g,""),a=o;["src","selected","checked","disabled","readonly"].forEach((e=>{o=o.replace(new RegExp(" "+e+'="{{(.+)}}"',"g")," doo-"+e+'="{{$1}}"')}));let l=a===o,n=document.createElement("template");n.innerHTML=o;let d=[];const s=(e,t,o)=>{let a=[],l=e;for(;l!==n.firstElementChild;){let e=l.previousSibling,t=0;for(;e;)t++,e=e.previousSibling;l=l.parentNode,l&&a.unshift(t)}d.push([t,a.slice(1),o])},c=document.createTreeWalker(n.content,NodeFilter.SHOW_TEXT,{acceptNode:()=>NodeFilter.FILTER_ACCEPT});let r=c.nextNode(),p=[];for(;r;){let e=r.wholeText.trim();if(0===e.indexOf("{{")&&e.lastIndexOf("}}")===e.length-2);else{let t=e.replace(/{{/g,"<span>{{").replace(/}}/g,"}}</span>");p.push({node:r.parentNode,L:e,v:t})}r=c.nextNode()}for(let e=0,t=p.length;e<t;e++)p[e].node.innerHTML=p[e].node.innerHTML.replace(p[e].L,p[e].v);let i=n.content.cloneNode(!0);const T=document.createTreeWalker(i,NodeFilter.SHOW_TEXT,{acceptNode:()=>NodeFilter.FILTER_ACCEPT});let m=T.nextNode();for(;m;){const e=m.nodeValue.match(/\{\{(.*?)\}\}/g);if(e){const t=m.parentNode;e.forEach((e=>{const o=e.replace(/\{\{|\}\}/g,"").trim(),a=document.createTextNode(o);m.textContent="";const l=t.appendChild(a);s(l,o,"textContent")}))}m=T.nextNode()}const f=document.createTreeWalker(i,NodeFilter.SHOW_ELEMENT,{acceptNode:()=>NodeFilter.FILTER_ACCEPT});for(m=f.nextNode();m;){for(const e of[...m.attributes])e.nodeValue.includes("{{")&&s(m,e.nodeValue.replace("{{","").replace("}}",""),e.name);m=f.nextNode()}let g=i.firstElementChild.outerHTML;return d.forEach((e=>{let t="{{"+e[0]+"}}";g=g.replace(new RegExp(t,"g"),"")})),i.outerHTML=g,{D:i.firstElementChild,H:l,C:d}},fetchTemplate=e=>new Promise(((t,o)=>{const a=new XMLHttpRequest;a.open("GET",e),a.onload=()=>t(a.responseText),a.onerror=()=>o(a.statusText),a.send()})),setReactiveDataNodes=e=>{const t=[],o=e=>{let t=0;for(;e.parentElement;)e=e.parentElement,t++;return t};e.innerHTML=e.innerHTML.replace(/\$\{(.+?)\}/gm,((t,o)=>isNaN(o)?e.getAttribute(o)||"":Config.u.BEG+e.R?.[o-1]+Config.u.END||""));const a=e.content.querySelectorAll(`[${Config.o}]`);a.forEach((t=>{t.hasAttribute("data-src")||t.setAttribute("data-src",e.hasAttribute("doo-dispatch")?"DooX":Config.o),t.removeAttribute("data-src")})),(e=>{[...e].map((e=>({I:e,level:o(e),F:e.getAttribute("data-src")?.startsWith("this.parent"),M:e.hasAttribute("data-norepeat")}))).sort(((e,t)=>t.level-e.level)).forEach((({I:e,level:o,F:a,M:l},n)=>{const d="|STYLE|LINK|".includes(`|${e.tagName}|`)?e:(e.parentElement&&"|DL|UL|TBODY|THEAD|TFOOT|TR|SELECT|SECTION|".includes(`|${e.parentElement.tagName}|`),e.parentElement),s=dooParse(e);Object.assign(d,{h:e.getAttribute(Config.o),D:s.D,H:s.H,C:s.C,name:n,level:o,F:a,M:l,O:isTable(d)}),"DATA"!==d.tagName&&"STYLE"!==d.tagName&&"LINK"!==d.tagName||e.parentElement?.replaceChild(d,e)||console.warn("Templates should only have one child node"),t.push(d)}))})(a),e.place=t},setNodeValues=(e,t)=>{for(let o=0;o<len;o++){const a=getNode(e,place.C[o][1],0);a?"textContent"===place.C[o][2]?a.textContent=data[t][place.C[o][0]]:a.setAttribute(place.C[o][2],data[t][place.C[o][0]]):console.info("Field:"+place.C[o][0]+" does not exist")}if(this.S){let e=place.querySelectorAll(place.D.tagName);for(let t=start;t<stop;t++){let o=e.item(t);const a=o||place.D;setNodeValues(a,t),o||(place.appendChild(a.cloneNode(!0))[Config.A]=getItemValue(data[t],this.h))}}else for(let e=start;e<stop;e++){const t=place.D;setNodeValues(t,e),place.appendChild(t.cloneNode(!0))[Config.A]=getItemValue(data[e],this.h)}},prefetchTemplate=async e=>{if(e&&(e.startsWith("./")||e.startsWith("../")||e.startsWith("http"))){return await fetchTemplate(e)}return null},createTemplate=async(e,t=[],o=null)=>{let a=o?await prefetchTemplate(o):"";a||(a=e.startsWith("<")?e:e.startsWith("#")?document.querySelector(e).outerHTML:document.querySelector("#"+e).outerHTML);const l=document.createElement("div");l.innerHTML=a,l.querySelector("template")&&(l.innerHTML=l.querySelector("template")?a:`<template><center><pre>The template you are trying to import does not have a <template> tag</pre><div style="color:red">${a}</div></center></template>`);const n=l.querySelector("template").cloneNode(!0),d=document.createElement("template");n.removeAttribute("id"),d.innerHTML=n.innerHTML,setReactiveDataNodes(d);const s=`[data-template="${e}"]`;return document.querySelector(s).parentElement.replaceChild(d.content,document.querySelector(s)),render(d.place[0],t,0),d};export{createTemplate,append,render,Config,version,prefetchTemplate};
0 commit comments