uhtml
Version:
A minimalistic library to create fast and reactive Web pages
2 lines (1 loc) • 3.73 kB
JavaScript
const{freeze:t}=Object,e=new Set(["plaintext","script","style","textarea","title","xmp"]),s=new Set(["area","base","br","col","embed","hr","img","input","keygen","link","menuitem","meta","param","source","track","wbr"]),n=t({}),r=t([]),i=(t,e)=>(t.children===r&&(t.children=[]),t.children.push(e),e.parent=t,e),o=(t,e,s)=>{t.props===n&&(t.props={}),t.props[e]=s},c=(t,e,s)=>{t!==e&&s.push(t)};class a{constructor(t){this.type=t,this.parent=null}toJSON(){return[this.type,this.data]}}class l extends a{constructor(t){super(8),this.data=t}toString(){return`\x3c!--${this.data}--\x3e`}}class h extends a{constructor(t){super(10),this.data=t}toString(){return`<!${this.data}>`}}class p extends a{constructor(t){super(3),this.data=t}toString(){return this.data}}class d extends a{constructor(){super(42),this.name="template",this.props=n,this.children=r}toJSON(){const t=[42];return c(this.props,n,t),c(this.children,r,t),t}toString(){let t="";for(const e in this.props){const s=this.props[e];null!=s&&("boolean"==typeof s?s&&(t+=` ${e}`):t+=` ${e}="${s}"`)}return`<template${t}>${this.children.join("")}</template>`}}class u extends a{constructor(t,e=!1){super(1),this.name=t,this.xml=e,this.props=n,this.children=r}toJSON(){const t=[1,this.name,+this.xml];return c(this.props,n,t),c(this.children,r,t),t}toString(){const{xml:t,name:n,props:r,children:i}=this,{length:o}=i;let c=`<${n}`;for(const e in r){const s=r[e];null!=s&&("boolean"==typeof s?s&&(c+=t?` ${e}=""`:` ${e}`):c+=` ${e}="${s}"`)}if(o){c+=">";for(let s=!t&&e.has(n),r=0;r<o;r++)c+=s?i[r].data:i[r];c+=`</${n}>`}else c+=t?" />":s.has(n)?">":`></${n}>`;return c}}class m extends a{constructor(){super(11),this.name="#fragment",this.children=r}toJSON(){const t=[11];return c(this.children,r,t),t}toString(){return this.children.join("")}}const f="\0",x=`"${f}"`,g=`'${f}'`,w=/\x00|<[^><\s]+/g,$=/([^\s/>=]+)(?:=(\x00|(?:(['"])[\s\S]*?\3)))?/g,S=(t,e,s,n,r)=>[e,s,n],b=t=>{const e=[];for(;t.parent;){switch(t.type){case 42:case 1:"template"===t.name&&e.push(-1)}e.push(t.parent.children.indexOf(t)),t=t.parent}return e},y=(t,e)=>{do{t=t.parent}while(e.has(t));return t};var O=({Comment:t=l,DocumentType:n=h,Text:c=p,Fragment:a=m,Element:O=u,Component:j=d,update:v=S})=>(l,h,p)=>{const d=l.join(f).trim(),u=new Set,m=[];let S=new a,J=0,N=0,k=0,C=r;for(const a of d.matchAll(w)){if(0<N){N--;continue}const l=a[0],w=a.index;if(J<w&&i(S,new c(d.slice(J,w))),l===f){"table"===S.name&&(S=i(S,new O("tbody",p)),u.add(S));const e=i(S,new t("◦"));m.push(v(e,8,b(e),"",h[k++])),J=w+1}else if(l.startsWith("<!")){const e=d.indexOf(">",w+2);if("--\x3e"===d.slice(e-2,e+1)){const s=d.slice(w+4,e-2);"!"===s[0]&&i(S,new t(s.slice(1).replace(/!$/,"")))}else i(S,new n(d.slice(w+2,e)));J=e+1}else if(l.startsWith("</")){const t=d.indexOf(">",w+2);p&&"svg"===S.name&&(p=!1),S=y(S,u),J=t+1}else{const t=w+l.length,n=d.indexOf(">",t),a=l.slice(1);let W=a;if(a===f?(W="template",S=i(S,new j),C=b(S).slice(1),m.push(v(S,42,C,"",h[k++]))):(p||(W=W.toLowerCase(),"table"!==S.name||"tr"!==W&&"td"!==W||(S=i(S,new O("tbody",p)),u.add(S)),"tbody"===S.name&&"td"===W&&(S=i(S,new O("tr",p)),u.add(S))),S=i(S,new O(W,!!p&&"svg"!==W)),C=r),t<n){let e=!1;for(const[s,i,c]of d.slice(t,n).matchAll($))if(c===f||c===x||c===g||(e=i.endsWith(f))){const t=C===r?C=b(S):C;m.push(v(S,2,t,e?i.slice(0,-1):i,h[k++])),e=!1,N++}else o(S,i,!c||c.slice(1,-1));C=r}J=n+1;const A=0<n&&"/"===d[n-1];if(p)A&&(S=S.parent);else if(A||s.has(W))S=A?y(S,u):S.parent;else if("svg"===W)p=!0;else if(e.has(W)){const t=d.indexOf(`</${a}>`,J),e=d.slice(J,t);e.trim()===f?(N++,m.push(v(S,3,b(S),"",h[k++]))):i(S,new c(e)),S=S.parent,J=t+a.length+3,N++;continue}}}return J<d.length&&i(S,new c(d.slice(J))),[S,m]};export{O as default};