solarite 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,13 @@
1
- // Version 2025.7.20.0141
1
+ // Version 2025.12.26.2040
2
2
  // License: MIT
3
3
  // http://vorticode.github.io/solarite
4
- let lastObjectId=1,objectIds=new WeakMap;function getObjectId(t){let e=objectIds.get(t);return e||(e="~\f"+lastObjectId++,objectIds.set(t,e)),e}let isHashing=!0;function toJSON(){return isHashing?getObjectId(this):this}function getObjectHash(t){let e;Node.prototype.toJSON!==toJSON&&(Node.prototype.toJSON=toJSON,(()=>{}).toJSON!==toJSON&&(Function.prototype.toJSON=toJSON)),isHashing=!0;try{e=JSON.stringify(t)}catch(l){e=getObjectHashCircular(t)}return isHashing=!1,e}function getObjectHashCircular(t){const e=new Set;return JSON.stringify(t,((t,l)=>{if("object"==typeof l&&null!==l){if(e.has(l))return getObjectId(l);e.add(l)}return l}))}var Globals;function reset(){Globals={t:new WeakMap,connected:new WeakSet,l:null,div:document.createElement("div"),i:{},o:{},h:new WeakMap,u:new WeakMap,p:new WeakMap,m:new WeakSet,v:new WeakSet,P:new WeakMap,reset,count:0}}reset();var Globals$1=Globals;function delve(t,e,l=d){let s=l!==d,i=e.length;if(!t&&!s&&i)return;let r=0;for(let o of e){if(void 0===t[o]){if(!s)return;i-1>r&&(t[o]=(e[r+1]+"").match(/^\d+$/)?[]:{})}s&&r===i-1&&(t[o]=l),t=t[o],r++}return t}let d={},Util={$(t,e){let l=t.length;if(l!==e.length)return!1;for(let s=0;l>s;s++)if(t[s]!==e[s])return!1;return!0},N(t,e){let l=e.getAttribute("data-id")||e.getAttribute("id");if(l){if(t[l]&&!(t[l]instanceof Node))throw Error(`${t.constructor.name}.${l} already has a value. Can't set it as a reference to <${e.tagName.toLowerCase()} id="${l}">`);delve(t,l.split(/\./g),e)}},T(t,e){let l=e.getAttribute("data-style");l||(e.constructor.G||(e.constructor.G=1),l=e.constructor.G++,e.setAttribute("data-style",l));let s=e.tagName.toLowerCase();for(let e of t.childNodes)if(3===e.nodeType){let t=e.textContent,i=t.replace(/:host(?=[^a-z0-9_])/gi,`${s}[data-style="${l}"]`);t!==i&&(e.textContent=i)}},A:t=>(t=(t=(t=t.replace(/([a-z0-9])([A-Z])/g,"$1-$2")).replace(/([A-Z])([A-Z][a-z])/g,"$1-$2")).replace(/([a-zA-Z])([0-9])/g,"$1-$2")).toLowerCase(),S:t=>t.replace(/-([a-z])/g,(t=>t[1].toUpperCase())),H:t=>"checkbox"===t.type||"radio"===t.type?t.checked:"file"===t.type?[...t.files]:"number"===t.type||"range"===t.type?t.valueAsNumber:"date"===t.type||"time"===t.type||"datetime-local"===t.type?t.valueAsDate:"select-multiple"===t.type?[...t.selectedOptions].map((t=>t.value)):t.value,O:t=>t.startsWith("on")&&t in Globals$1.div,C(t,e){let l=t.tagName+"."+e,s=Globals$1.o[l];if(void 0===s){let i=Object.getPrototypeOf(t);for(;i;){const t=i.constructor.name;if(t.startsWith("HTML")&&t.endsWith("Element"))break;i=Object.getPrototypeOf(i)}Globals$1.o[l]=s=!!i&&!!Object.getOwnPropertyDescriptor(i,e)?.set}return s},k:t=>Array.isArray(t)&&t.length>=2&&("object"==typeof t[0]||void 0===t[0])&&!t.slice(1).find((t=>"string"!=typeof t&&"number"!=typeof t)),M:t=>void 0===t||!1===t||null===t,j:t=>"function"==typeof t?Util.j(t()):t instanceof Date?t.toISOString().replace(/T/," "):Array.isArray(t)||"object"==typeof t?"":t,U(t,e,l){let s=t.get(e);s?s.push(l):(s=[l],t.set(e,s))},I(t){const e=t=>t.nodeType!==Node.ELEMENT_NODE&&(t.nodeType!==Node.TEXT_NODE||""===t.textContent.trim()),l=[...t];for(;l.length>0&&e(l[0]);)l.shift();for(;l.length>0&&e(l[l.length-1]);)l.pop();return l}};class MultiValueMap{data={};add(t,e){let l=this.data,s=l[t];s||(s=new Set,l[t]=s),s.add(e)}F(){for(let t in this.data)return!0;return!1}getAll(t){return this.data[t]||[]}delete(t,e=void 0){let l,s=this.data,i=s[t];if(i)return void 0===e?([l]=i,i.delete(l)):(i.delete(e),l=e),0===i.size&&delete s[t],l}R(t){let e,l=this.data,s=l[t];if(s)return[e]=s,s.delete(e),0===s.size&&delete l[t],e}V(t,e){let l,s=this.data,i=s[t];if(i)return i.delete(e),l=e,0===i.size&&delete s[t],l}J(t){let e=this.data,l=[];for(let s in e)e[s].has(t)&&l.push(s);return l}}const udomdiff=(t,e,l,s)=>{const i=l.length;let r=e.length,o=i,a=0,n=0,h=null;for(;r>a||o>n;)if(r===a){const e=i>o?n?l[n-1].nextSibling:l[o-n]:s;for(;o>n;){let s=l[n++];t.insertBefore(s,e)}}else if(o===n)for(;r>a;){let l=e[a];h&&h.has(l)||t.removeChild(l),a++}else if(e[a]===l[n])a++,n++;else if(e[r-1]===l[o-1])r--,o--;else if(e[a]===l[o-1]&&l[n]===e[r-1]){const s=e[--r].nextSibling;let i=l[n++],h=e[a++];t.insertBefore(i,h.nextSibling);let f=l[--o];t.insertBefore(f,s),e[r]=l[o]}else{if(!h){h=new Map;let t=n;for(;o>t;)h.set(l[t],t++)}if(h.has(e[a])){const s=h.get(e[a]);if(s>n&&o>s){let i=a,f=1;for(;++i<r&&o>i&&h.get(e[i])===s+f;)f++;if(f>s-n){const i=e[a];for(;s>n;){let e=l[n++];t.insertBefore(e,i)}}else{let s=e[a++],i=l[n++];t.replaceChild(i,s)}}else a++}else{let l=e[a++];t.removeChild(l)}}return l};class ExprPath{type;attrName;L;W;D;_;B;u=[];K;Z;q;X;Y;tt=void 0;constructor(t,e,l=ExprPathType.et,s=null,i=null){this.D=t,this._=e,this.type=l,this.attrName=s,this.L=i,l===ExprPathType.lt&&(this.W=new Set)}apply(t,e=!0){switch(this.type){case 1:this.st(t[0],e);break;case 2:this.it(this._,t[0]);break;case 5:break;case 6:this.rt(this._,t[0],this.B.ot.root);break;default:this.nt(this._,t)}}st(t,e=!0){let l=this;e&&l.ht();let s=[],i=l.u,r=[];l.u=[],l.ft(t,s,r);let o=!1;if(r.length){for(let[t,e]of r){let i=l.ut(s[t],!1),r=i.ct();1===r.length?s[t]=r[0]:(s[t]=r,o=!0),l.u[e]=i}o&&(s=s.flat())}let a=l.ct();if(!Util.$(a,s)){l.K=s,this.B.dt&&this.B.dt.bt(),a.length&&!s.length&&l.yt()||udomdiff(l._.parentNode,a,s,l._);for(let t of i)t.gt.parentNode||t.vt();for(let t of s)if(t instanceof HTMLElement){t.hasAttribute("solarite-placeholder")&&this.B.Et(t);for(let e of t.querySelectorAll("[solarite-placeholder]"))this.B.Et(e)}}}Pt(t){let e=Math.min(t.$t,t.items.length),l=t.$t-e;for(let l=0;e>l;l++){let e=this.u[t.index+l],s=(this.Y||this.X)(t.items[l]);this.Nt(s,(s=>{let i=this.ut(s,!0);if(i&&i===e);else{i||(i=this.ut(s,!1)),this.u[t.index+l]=i;let r=e.gt;for(let t of i.ct())r.parentNode.insertBefore(t,r);i!==e&&e.vt()}}))}if(l>0){for(let s=0;l>s;s++)this.u[t.index+e+s].vt();this.u.splice(t.index+e,l)}else{let l=t.items.slice(e),s=this.u[t.index+e]?.gt||this._;for(let t=0;l.length>t;t++){let e=this.Y(l[t]),i=this.ut(e,!0);i||(i=this.ut(e,!1)),this.u.push(i);for(let t of i.ct())s.parentNode.insertBefore(t,s)}}this.K=null}Nt(t,e){if(Array.isArray(t))for(let l of t)this.Nt(l,e);else if("function"==typeof t)Globals$1.l=this,this.X=t,t=t(),Globals$1.l=null,this.Nt(t,e);else if(t instanceof Template||t instanceof Node)e(t);else{void 0===t||!1===t||null===t?t="":"string"!=typeof t&&(t+="");let l=new Template([t],[]);this.Nt(l,e)}}ft(t,e,l){if(t instanceof Template){let s=this.ut(t,!0);s?(e.push(...s.ct()),this.u.push(s)):(l.push([e.length,this.u.length]),e.push(t),this.u.push(null))}else t instanceof Node?t instanceof DocumentFragment?e.push(...t.childNodes):e.push(t):this.Nt(t,(t=>{this.ft(t,e,l)}))}it(t,e){Array.isArray(e)&&(e=e.flat().join(" "));let l=this.W;if(this.W=new Set,e){"function"==typeof e&&(Globals$1.l=this,this.X=e,e=e(),Globals$1.l=null);let l=(e+"").split(/([\w-]+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s]+))/g).map((t=>t.trim())).filter((t=>t.length));for(let e of l){let[l,s]=e.split(/\s*=\s*/);s=(s||"").replace(/^(['"])(.*)\1$/,"$2"),t.setAttribute(l,s),this.W.add(l)}}for(let e of l)this.W.has(e)||t.removeAttribute(e)}rt(t,e,l){let s,i=this.attrName.slice(2),r=[];if(Array.isArray(e)&&"function"==typeof e[0])s=e[0],r=e.slice(1);else{if("function"!=typeof e)throw Error(`Invalid event binding: <${t.tagName.toLowerCase()} ${this.attrName}=\${${JSON.stringify(e)}}>`);s=e}this.Tt(t,l,i,i,s,r)}Tt(t,e,l,s,i,r,o=!1){let a=Globals$1.h.get(t);a||(a={[l]:[,,,]},Globals$1.h.set(t,a));let n=a[l];if(n||(a[l]=n=[,,,]),"function"!=typeof i)throw Error(`Solarite cannot bind to <${t.tagName.toLowerCase()} ${this.attrName}=\${${i}}> because it's not a function.`);if(n[0]!==i){let[l,r,a]=n;l&&t.removeEventListener(s,r,o);let h=i,f=l=>h.call(e,...n[2],l,t);n[0]=h,n[1]=f,t.addEventListener(s,f,o)}a[l][2]=r}nt(t,e){let l=e[0];if(Util.k(l)){let[e,s]=[l[0],l.slice(1)];if(!e)throw Error(`Solarite cannot bind to <${t.tagName.toLowerCase()} ${this.attrName}=\${[${l.map((t=>t?`'${t}'`:t+"")).join(", ")}]}>.`);let i=delve(e,s);if("value"===this.attrName&&"select-multiple"===t.type&&Array.isArray(i)){let e=i.map((t=>t+""));for(let l of t.options)l.selected=e.includes(l.value)}else{let e=Util.M(i)?"":i;e!==t[this.attrName]&&(t[this.attrName]=e)}let r=()=>{let l="value"===this.attrName?Util.H(t):t[this.attrName];delve(e,s,l)};this.Tt(t,s[0],this.attrName,"input",r,[],!0)}else{let s=this.tt;void 0===s&&(s=this.tt=Util.C(t,this.attrName));let i=this.L;if(!i){if(Globals$1.l=this,"function"==typeof l){if(4===this.type)return;this.X=l,l=l()}else l=Util.j(l);Globals$1.l=null}if(i||void 0!==l&&!1!==l&&null!==l)if(i||!0!==l){let r;if(i){let t=[];for(let l=0;this.L.length>l;l++)if(t.push(this.L[l]),this.L.length-1>l){Globals$1.l=this;let s=Util.j(e[l]);Globals$1.l=null,Util.M(s)||t.push(s)}r=t.join("")}else r=l;(s?t[this.attrName]:t.getAttribute(this.attrName))!==r&&(s&&(t[this.attrName]=r),t.setAttribute(this.attrName,r))}else s&&(t[this.attrName]=!0),t.setAttribute(this.attrName,"");else s&&(t[this.attrName]=!1),t.removeAttribute(this.attrName)}}clone(t,e=0){let l,s,i=t,r=e?this.q.slice(0,-e):this.q;for(let t=r.length-1;t>0;t--)i=i.childNodes[r[t]];let o=i.childNodes;return l=r.length?o[r[0]]:t,this.D&&(s=o[this.Z]),new ExprPath(s,l,this.type,this.attrName,this.L)}bt(){let t=this,e=this._.parentNode;for(;t&&t._.parentNode===e;)t.K=null,t=t.B?.dt}yt(){let t=this.D.parentNode;return this.D===t.firstChild&&this._===t.lastChild&&(t.innerHTML="",t.append(this.D,this._),!0)}ct(){if(this.type===ExprPathType.wt||this.type===ExprPathType.lt||this.type===ExprPathType.Gt)return[this._];let t;if(t=this.K,t)return t;t=[];let e=this.D.nextSibling,l=this._;for(;e&&e!==l;)t.push(e),e=e.nextSibling;return this.K=t,t}xt(){return this._.parentNode}ut(t,e=!0){let l,s=this.At;if(e){if(l=s.R(t.St()),l||(s=this.Ht,l=s.R(t.St())),!l)return null;s.V(t.Ot(),l)}else t.Ct.length&&(l=s.R(t.Ot()),l||(s=this.Ht,l=s.R(t.Ot())),l&&(s.V(l.kt,l),l.Mt(t.Ct),l.kt=t.St()));return l||(l=new NodeGroup(t,this)),this.jt.push(l),l}Ut(){return this.type===ExprPathType.Gt||this.attrName&&this._.tagName&&this._.tagName.includes("-")}jt=[];At=new MultiValueMap;Ht=new MultiValueMap;ht(){let t=this.At.data,e=this.Ht.data;for(let l in t){let s=e[l];if(s)for(let e of t[l])s.add(e);else e[l]=t[l]}this.At=new MultiValueMap;let l=this.At;for(let t of this.jt)l.add(t.kt,t),l.add(t.It,t);this.jt=[]}}const ExprPathType={et:1,lt:2,wt:3,Gt:4,Comment:5,Event:6};function getNodePath(t){let e=[];for(;;){let l=t.parentNode;if(!l)break;e.push([].indexOf.call(t.parentNode.childNodes,t)),t=l}return e}function resolveNodePath(t,e){for(let l=e.length-1;l>=0;l--)t=t.childNodes[e[l]];return t}class HtmlParser{constructor(){this.Ft={context:HtmlParser.Text,quote:null,buffer:"",Rt:null},this.state={...this.Ft}}reset(){return this.state={...this.Ft},this.state.context}parse(t,e=null){if(null===t)return this.reset();for(let l=0;t.length>l;l++){const s=t[l];switch(this.state.context){case HtmlParser.Text:"<"===s&&t[l+1].match(/[/a-z!]/i)&&(e?.(t,l,this.state.context,HtmlParser.Vt),this.state.context=HtmlParser.Vt,this.state.buffer="");break;case HtmlParser.Vt:if(">"===s)e?.(t,l+1,this.state.context,HtmlParser.Text),this.state.context=HtmlParser.Text,this.state.quote=null,this.state.buffer="";else{if(" "===s&&!this.state.buffer)continue;" "===s||"/"===s||"?"===s?this.state.buffer="":'"'===s||"'"===s||"="===s?(e?.(t,l,this.state.context,HtmlParser.Jt),this.state.context=HtmlParser.Jt,this.state.quote="="===s?null:s,this.state.buffer=""):this.state.buffer+=s}break;case HtmlParser.Jt:this.state.quote||this.state.buffer.length||'"'!==s&&"'"!==s?s===this.state.quote||!this.state.quote&&this.state.buffer.length?(e?.(t,l,this.state.context,HtmlParser.Vt),this.state.context=HtmlParser.Vt,this.state.quote=null,this.state.buffer=""):this.state.quote||">"!==s?" "!==s&&(this.state.buffer+=s):(e?.(t,l+1,this.state.context,HtmlParser.Text),this.state.context=HtmlParser.Text,this.state.quote=null,this.state.buffer=""):this.state.quote=s}}return e?.(t,t.length,this.state.context,null),this.state.context}}HtmlParser.Jt="Attribute",HtmlParser.Text="Text",HtmlParser.Vt="Tag";class Shell{fragment;Lt=[];Wt=[];scripts=[];zt=[];Dt=[];constructor(t=null){if(!t)return;if(1===t.length&&!t[0].match(/[<&]/))return void(this.fragment=document.createTextNode(t[0]));let e,l=Shell._t(t),s=document.createElement("template");l?s.innerHTML=l:s.content.append(document.createTextNode("")),this.fragment=s.content;let i=[],r=0;const o=document.createTreeWalker(this.fragment,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT|NodeFilter.SHOW_TEXT);for(;e=o.nextNode();)if(i.map((t=>t.remove())),i=[],1===e.nodeType)for(let t of[...e.attributes]){let l=t.name.match(/^[\ue000-\uf8ff]$/);if(l)this.Lt.push(new ExprPath(null,e,ExprPathType.lt)),r++,e.removeAttribute(l[0]);else{let l=t.value.split(/[\ue000-\uf8ff]/g);if(l.length>1){let s=2!==l.length||l[0].length||l[1].length?l:null,i=Util.O(t.name)?ExprPathType.Event:ExprPathType.wt;this.Lt.push(new ExprPath(null,e,i,t.name,s)),r+=l.length-1,e.setAttribute(t.name,l.join(""))}}}else if(8===e.nodeType&&"!✨!"===e.nodeValue){let t,l=e.previousSibling;l||(l=document.createComment("ExprPath:"+this.Lt.length),e.parentNode.insertBefore(l,e)),!e.nextSibling||8===e.nextSibling.nodeType&&"!✨!"===e.nextSibling.textContent?(t=e,t.textContent="ExprPathEnd:"+this.Lt.length):(t=e.nextSibling,i.push(e));let s=new ExprPath(l,t,ExprPathType.et);this.Lt.push(s),r++}else{if(3===e.nodeType&&"TEXTAREA"===e.parentNode?.tagName&&e.textContent.includes("\x3c!--!✨!--\x3e"))throw Error('Textarea can\'t have expressions inside them. Use <textarea value="${...}"> instead.');if(e.nodeType===Node.COMMENT_NODE){let t=e.textContent.split(/[\ue000-\uf8ff]/g);for(let l=0;t.length-1>l;l++){let t=new ExprPath(e.previousSibling,e);t.type=ExprPathType.Comment,this.Lt.push(t),r++}}else if(e.nodeType===Node.TEXT_NODE&&["SCRIPT","STYLE"].includes(e.parentNode?.nodeName)){let t=e.textContent.split(commentPlaceholder);if(t.length>1){let l=[];for(let s=0;t.length>s;s++){let i=document.createTextNode(t[s]);e.parentNode.insertBefore(i,e),s>0&&l.push(i)}for(let t,e=0;t=l[e];e++){let e=new ExprPath(t.previousSibling,t,ExprPathType.et);this.Lt.push(e),r++}i.push(e)}}}if(i.map((t=>t.remove())),r!==t.length-1)throw Error("Could not parse expressions in template. Check for duplicate attributes or malformed html: "+t.join("${...}"));for(let t of this.fragment.querySelectorAll("[is]"))t.setAttribute("_is",t.getAttribute("is"));for(let t of this.Lt)t.D&&(t.Z=[].indexOf.call(t.D.parentNode.childNodes,t.D)),t.q=getNodePath(t._),t.type===ExprPathType.wt&&1===t._.nodeType&&(t._.tagName.includes("-")||t._.hasAttribute("is"))&&(t.type=ExprPathType.Gt);this.Bt()}static _t(t){let e=[];function l(t,l){l===HtmlParser.Vt&&(t=t.replace(/^<\/?[a-z][a-z0-9]*-[a-z0-9-]+/i,(t=>t+"-solarite-placeholder solarite-placeholder"))),e.push(t)}let s=new HtmlParser;for(let i=0;t.length>i;i++){let r=0,o=s.parse(t[i],((t,e,s,i)=>{r!==e&&l(t.slice(r,e),s),r=e}));t.length-1>i&&e.push(o===HtmlParser.Text?commentPlaceholder:String.fromCharCode(attribPlaceholder+i))}return e.join("")}Bt(){this.scripts=[].map.call(this.fragment.querySelectorAll("scripts"),(t=>getNodePath(t))),this.zt=[].map.call(this.fragment.querySelectorAll("style"),(t=>getNodePath(t)));let t=this.fragment.querySelectorAll("[id],[data-id]");for(let e of t){let t=e.getAttribute("data-id")||e.getAttribute("id");if(Globals$1.div.hasOwnProperty(t))throw Error(`<${e.tagName.toLowerCase()} id="${t}"> can't override existing HTMLElement id property.`)}this.Wt=[].map.call(t,(t=>getNodePath(t)));for(let t of this.fragment.querySelectorAll("*"))(t.tagName.includes("-")||t.hasAttribute("_is"))&&(this.Lt.find((e=>e._===t))||this.Dt.push(getNodePath(t)))}static get(t){let e=Globals$1.P.get(t);return e||(e=new Shell(t),Globals$1.P.set(t,e)),e}}const commentPlaceholder="\x3c!--!✨!--\x3e",attribPlaceholder=57344;class NodeGroup{ot;dt;gt;Kt;Lt=[];kt;It;K;zt;constructor(t,e=null){if(!(this instanceof RootNodeGroup)){let[l,s]=this.init(t,e);if(l&&t.Ct.length){this.Zt(l,s.Lt);let e=this.qt(l,s);this.Xt(l,s),this.Mt(t.Ct),this.Yt(e)}else s&&this.Xt(l,s)}}init(t,e=null,l=null,s=null){if(this.kt=l||t.St(),this.It=s||t.Ot(),this.dt=e,this.ot=e?.B?.ot||this,this.Qt=t,t.te=this,this instanceof RootNodeGroup||t.Ct.length||t.ee[0].includes("<")){let e=Shell.get(t.ee),l=e.fragment.cloneNode(!0);if(l instanceof DocumentFragment){let t=l.childNodes;this.gt=t[0],this.Kt=t[t.length-1]}else this.gt=this.Kt=l;return[l,e]}{let e=document.createTextNode(t.ee[0]);return this.gt=this.Kt=e,[]}}Mt(t,e=null){let l,s=t.length-1,i=Array((e=e||this.Lt).length);for(let r,o=e.length-1;r=e[o];o--){let a=e[o-1],n=e[o+1];if(r.L?.length>2?(i[o]=t.slice(s-(r.L.length-1)+1,s+1),s-=i[o].length):(i[o]=[t[s]],s--),r._!==this.ot.root&&r.Ut()){if(n&&n.Ut()&&n._===r._||(l=o),!a||!a.Ut()||a._!==r._){let t={};for(let s=o;l>=s;s++)t[e[s].attrName]=i[s].length>1?i[s].join(""):i[s][0];this.le(r._,t);for(let t=o;l>=t;t++)e[t].apply(i[t])}}else r.apply(i[o])}this.se(),this.K=null}le(t,e){let l=getObjectHash(e),s=t.hasAttribute("solarite-placeholder"),i=t.hasAttribute("_is");if(s||i)t=this.Et(t,s,e);else if(t.ie){let l={};for(let t in e||{})l[Util.S(t)]=e[t];t.ie(l)}Globals$1.t.set(t,l)}Et(t,e=void 0,l=void 0){void 0===e&&(e=!t.hasAttribute("_is"));let s=(e?t.tagName.slice(0,-21):t.getAttribute("is")).toLowerCase(),i=customElements.get(s);if(!i)throw Error(`The custom tag name ${s} is not registered.`);let r={};for(let t in l||{})r[Util.S(t)]=l[t];if(t.attributes.length)for(let e of t.attributes){let t=Util.S(e.name);r.hasOwnProperty(t)||"solarite-placeholder"===t||(r[t]=e.value)}let o=new i(r,[...t.childNodes].filter((t=>t.nodeType!==Node.COMMENT_NODE||!t.nodeValue.startsWith("ExprPath"))));e||o.setAttribute("is",t.getAttribute("is").toLowerCase()),t.replaceWith(o);let a=t.getAttribute("data-id")||t.getAttribute("id");a&&delve(this.getRootNode(),a.split(/\./g),o);for(let e of this.Lt)e._===t&&(e._=o),e.D===t&&(e.D=o);this.gt===t&&(this.gt=o),this.Kt===t&&(this.Kt=o),o.re&&o.re();for(let e of t.attributes)"_is"!==e.name&&"solarite-placeholder"!==e.name&&o.setAttribute(e.name,e.value);for(let t in l){let e=l[t];"boolean"==typeof e?!1!==e&&null!=e&&o.setAttribute(t,""):["number","bigint","string"].includes(typeof e)&&o.setAttribute(t,e)}return o}ct(){let t=this.K;if(t)return t;t=[];let e=this.gt,l=this.Kt?.nextSibling;for(;e&&e!==l;)t.push(e),e=e.nextSibling;return this.K=t,t}xt(){return this.gt?.parentNode}getRootNode(){return this.ot.root}oe(){return this.ot}vt(){let t=document.createDocumentFragment();for(let e of this.ct())t.append(e)}Zt(t,e,l){let s=e.length;this.Lt.length=s;for(let i=0;s>i;i++){let s=e[i].clone(t,l);s.B=this,this.Lt[i]=s}}se(){if(this.zt)for(let[t,e]of this.zt)e!==t.textContent&&Util.T(t,this.oe().root)}qt(t,e,l=0){let s=[];for(let i of e.Dt){l&&(i=i.slice(0,-l));let e=resolveNodePath(t,i);t!==e&&s.push(e)}return s}Yt(t){for(let e of t)this.Et(e)}Xt(root,shell,pathOffset=0){let rootEl=this.ot.root;if(rootEl){let options=this.ot.options;if(!1!==options?.Wt)for(let t of shell.Wt){pathOffset&&(t=t.slice(0,-pathOffset));let e=resolveNodePath(root,t);Util.N(rootEl,e)}if(!1!==options?.zt){shell.zt.length&&(this.zt=new Map);for(let t of shell.zt){pathOffset&&(t=t.slice(0,-pathOffset));let e=resolveNodePath(root,t);1===rootEl.nodeType&&(Util.T(e,rootEl),this.zt.set(e,e.textContent))}}if(!1!==options?.scripts)for(let path of shell.scripts){pathOffset&&(path=path.slice(0,-pathOffset));let script=resolveNodePath(root,path);eval(script.textContent)}}}}class RootNodeGroup extends NodeGroup{root;ae=new Map;constructor(t,e,l){super(t),this.options=l,this.ot=this;let[s,i]=this.init(t);if(s instanceof Text)e&&(this.gt=e,this.Kt=e,s.nodeValue.length&&e.append(s),this.root=e),Globals$1.u.set(this.root,this);else{let l=0,r=s;if(e){let t;if(Globals$1.u.set(e,this),e.childNodes.length&&(t=document.createDocumentFragment(),t.append(...e.childNodes)),this.root=e,isReplaceEl(s,e)){e.append(...s.children[0].childNodes);for(let t of s.children[0].attributes)e.hasAttribute(t.name)||"solarite-placeholder"===t.name||e.setAttribute(t.name,t.value);l=1}else 1===s.childNodes.length&&3===s.childNodes[0].nodeType&&""===s.childNodes[0].textContent||e.append(...s.childNodes);if(t){for(let l of e.querySelectorAll("slot[name]")){let e=l.getAttribute("name");if(e){let s=t.querySelectorAll(`[slot='${e}']`);l.append(...s)}}let l=e.querySelector("slot:not([name])");l?l.append(t):e.append(t)}r=e,this.gt=e,this.Kt=e}else{let t=getSingleEl(s);this.root=t||s,Globals$1.u.set(this.root,this),t&&(r=t,l=1)}this.Zt(r,i.Lt,l);let o=this.qt(r,i,l);this.Xt(r,i,l),this.Mt(t.Ct),this.Yt(o)}}}function getSingleEl(t){let e=[];for(let l of t.childNodes)if(1===l.nodeType||3===l.nodeType&&l.textContent.trim().length){if(e.length)return null;e.push(l)}return e[0]}function isReplaceEl(t,e){return 1===t.children.length&&e.tagName.includes("-")&&t.children[0].tagName.replace("-SOLARITE-PLACEHOLDER","")===e.tagName}class Template{Ct=[];ee=[];ne;te;constructor(t,e){this.ee=t,this.Ct=e}toJSON(){return this.ne||(this.ne=[getObjectId(this.ee),this.Ct]),this.ne}ie(t=null,e={}){let l,s=!1;if(t){if(l=Globals$1.u.get(t),l||(l=new RootNodeGroup(this,t,e),Globals$1.u.set(t,l),s=!0),0===l.Lt.length&&this.Ct.length||l.Lt.length>this.Ct.length)throw Error(`Solarite Error: Parent HTMLElement ${l.Qt.ee.join("${...}")} and ${l.Lt.length} \${value} placeholders can't accomodate a Template with ${this.Ct.length} values.`)}else l=new RootNodeGroup(this,null,e),t=l.getRootNode(),Globals$1.u.set(t,l),s=!0;return s||(1!==this.ee?.length||this.ee[0]?l.Mt(this.Ct):t.innerHTML=""),l.ae=new Map,t}St(){return this.kt||(this.kt=this.Ct.length?getObjectHash(this):this.ee[0]),this.kt}Ot(){return this.It||(this.It=this.Ct.length?this.toJSON()[0]:this.ee[0]),this.It}}function h(t=void 0,...e){if(void 0===t&&!e.length&&arguments.length)throw Error("h() cannot be called with undefined.");if(!(t instanceof Node)){if(Array.isArray(t))return new Template(t,e);if("string"==typeof t||t instanceof String){if("object"==typeof e[0]){e.slice(1);let t=[],l=[];return assert(t.length===l.length+1),new Template(t,l)}t.match(/^\s^</)&&(t=t.trim());let l=document.createElement("template");l.innerHTML=t;let s=Util.I(l.content.childNodes);return 1===s.length?s[0]:l.content}if(void 0===t)return(t,...e)=>h(t,...e).ie();if(t instanceof Template)return t.ie();if("object"==typeof t){let e=t;if("Object"!==e.constructor.name)throw Error(`Solarate Web Component class ${e.constructor?.name} must extend HTMLElement.`);if(Globals$1.p.has(e))return((...t)=>{let l=h(...t).ie();Globals$1.p.set(e,l)}).bind(e);{Globals$1.p.set(e,null),e[renderF]();let t=Globals$1.p.get(e);Globals$1.p.delete(e);for(let l in e)t[l]="function"==typeof e[l]?e[l].bind(t):e[l];return t}}throw Error("Unsupported arguments.")}{let l=t,s=e[0];if(!(e[0]instanceof Template)){l.shadowRoot&&(l.innerHTML="");let t=e[0],s=(e,...s)=>(Globals$1.m.add(l),new Template(e,s).ie(l,t));return s}s.ie(l,e[1]),!l.childNodes.length&&this&&l.append(this.ot.xt())}}let renderF="render";function getArg(el,attributeName,defaultValue=void 0,type=ArgType.String,fallback=void 0){let val=defaultValue,attrVal=el.getAttribute(attributeName)||el.getAttribute(Util.A(attributeName)),result;if(null!==attrVal&&(val=attrVal),Array.isArray(type))return type.includes(val)?val:fallback;if("function"==typeof type)return type.constructor?new type(val):type(val);if(type===ArgType.he){let t="string"==typeof val?val.toLowerCase():val;return!["false","0",!1,0,null,void 0,NaN].includes(t)&&(!(!["true",!0].includes(t)&&0===parseFloat(t))||fallback)}switch(type){case ArgType.fe:return result=parseInt(val),isNaN(result)?fallback:result;case ArgType.ue:return result=parseFloat(val),isNaN(result)?fallback:result;case ArgType.String:return[void 0,null,!1].includes(val)?"":val+"";case ArgType.ce:case ArgType.de:if("string"!=typeof val||!val.length)return val;try{return type===ArgType.ce?JSON.parse(val):eval(`(${val})`)}catch(t){return val}default:return val}}function setArgs(t,e,l){for(let s in e)this[s]=getArg(t,s,e[s],l[s]||ArgType.String)}var ArgType={he:"Bool",fe:"Int",ue:"Float",String:"String",JSON:"Json",ce:"Json",de:"Eval"};function defineClass(t,e,l){if(!customElements[getName](t)){(e=e||Util.A(t.name)).includes("-")||(e+="-element");let s=null;l&&(s={pe:l}),customElements[define](e,t,s)}}function createSolarite(t=null){let e=HTMLElement;t&&!t.includes("-")&&(t=t.toLowerCase(),e=Globals$1.i[t],e||(e=document.createElement(t).constructor,Globals$1.i[t]=e));let l=new Proxy(e,{construct:(e,l,s)=>(defineClass(s,null,t),Reflect.construct(e,l,s))});return class extends l{me;be;ye;constructor(t={}){super(),!0===t.ie?this.ie():!1===t.ie&&Globals$1.m.add(this)}re(){!Globals$1.m.has(this)&&this.ie&&this.ie()}ge(){this.re(),Globals$1.connected.has(this)||(Globals$1.connected.add(this),this.be&&this.be()),this.me&&this.me()}ve(){this.ye&&this.ye()}static define(e=null){defineClass(this,e,t)}}}let define="define",getName="getName";const Solarite=new Proxy(createSolarite(),{apply:(t,e,l)=>createSolarite(...l)});export default h;export{ArgType,Globals$1 as Globals,Solarite,Util as SolariteUtil,Template,delve,getArg,h,h as r,setArgs};
4
+ let lastObjectId=1,objectIds=new WeakMap;function getObjectId(t){let e=objectIds.get(t);return e||(e="~\f"+lastObjectId++,objectIds.set(t,e)),e}let isHashing=!0;function toJSON(){return isHashing?getObjectId(this):this}function getObjectHash(t){let e;Node.prototype.toJSON!==toJSON&&(Node.prototype.toJSON=toJSON,(()=>{}).toJSON!==toJSON&&(Function.prototype.toJSON=toJSON)),isHashing=!0;try{e=JSON.stringify(t)}catch(l){e=getObjectHashCircular(t)}return isHashing=!1,e}function getObjectHashCircular(t){const e=new Set;return JSON.stringify(t,((t,l)=>{if("object"==typeof l&&null!==l){if(e.has(l))return getObjectId(l);e.add(l)}return l}))}var Globals;function reset(){Globals={t:new Map,connected:new WeakSet,l:null,div:document.createElement("div"),i:document,o:{},h:{},u:new WeakMap,p:new WeakMap,m:new WeakMap,$:new WeakSet,v:new WeakSet,P:new WeakMap,reset,count:0}}reset();var Globals$1=Globals;function delve(t,e,l=d){let s=l!==d,i=e.length;if(!t&&!s&&i)return;let r=0;for(let o of e){if(void 0===t[o]){if(!s)return;i-1>r&&(t[o]=(e[r+1]+"").match(/^\d+$/)?[]:{})}s&&r===i-1&&(t[o]=l),t=t[o],r++}return t}let d={},Util={T(t,e){let l=t.length;if(l!==e.length)return!1;for(let s=0;l>s;s++)if(t[s]!==e[s])return!1;return!0},N(t,e=null){let l={};for(let s of t.attributes)s.name!==e&&(l[Util.G(s.name)]=s.value);return l},A(t,e){let l=e.getAttribute("data-id")||e.getAttribute("id");if(l){if(t[l]&&!t[l]?.nodeType)throw Error(`${t.constructor.name}.${l} already has a value. Can't set it as a reference to <${e.tagName.toLowerCase()} id="${l}">`);delve(t,l.split(/\./g),e)}},S(t,e){let l,s,i=e.tagName.toLowerCase();if(t.hasAttribute("global")||t.hasAttribute("data-global")){l=i,s="";let r=Globals$1.i||e.ownerDocument||document;r.head.querySelector(`style[data-style="${l}"]`)?t.remove():(r.head.append(t),t.setAttribute("data-style",l))}else{let t=e.getAttribute("data-style");t||(e.constructor.C||(e.constructor.C=1),t=e.constructor.C++,e.setAttribute("data-style",t)),s=`[data-style="${t}"]`}for(let e of t.childNodes)if(3===e.nodeType){let t=e.textContent,l=t.replace(/:host(?=[^a-z0-9_])/gi,`${i}${s}`);t!==l&&(e.textContent=l)}},H:t=>(t=(t=(t=t.replace(/([a-z0-9])([A-Z])/g,"$1-$2")).replace(/([A-Z])([A-Z][a-z])/g,"$1-$2")).replace(/([a-zA-Z])([0-9])/g,"$1-$2")).toLowerCase(),G:t=>t.replace(/-([a-z])/g,(t=>t[1].toUpperCase())),O:t=>"checkbox"===t.type||"radio"===t.type?t.checked:"file"===t.type?[...t.files]:"number"===t.type||"range"===t.type?t.valueAsNumber:"date"===t.type||"time"===t.type||"datetime-local"===t.type?t.valueAsDate:"select-multiple"===t.type?[...t.selectedOptions].map((t=>t.value)):t.hasAttribute("contenteditable")?t.innerHTML:t.value,k:t=>t.startsWith("on")&&t in Globals$1.div,M(t,e){let l=t.tagName+"."+e,s=Globals$1.h[l];if(void 0===s){let i=Object.getPrototypeOf(t);for(;i;){const t=i.constructor.name;if(t.startsWith("HTML")&&t.endsWith("Element"))break;i=Object.getPrototypeOf(i)}Globals$1.h[l]=s=!!i&&!!Object.getOwnPropertyDescriptor(i,e)?.set}return s},j:t=>Array.isArray(t)&&t.length>=2&&("object"==typeof t[0]||void 0===t[0])&&!t.slice(1).find((t=>"string"!=typeof t&&"number"!=typeof t)),U:t=>void 0===t||!1===t||null===t,I:t=>"function"==typeof t?Util.I(t()):t instanceof Date?t.toISOString().replace(/T/," "):Array.isArray(t)||"object"==typeof t?"":t,F(t,e,l){let s=t.get(e);s?s.push(l):(s=[l],t.set(e,s))},J(t){const e=t=>t.nodeType!==Node.ELEMENT_NODE&&(t.nodeType!==Node.TEXT_NODE||""===t.textContent.trim()),l=[...t];for(;l.length>0&&e(l[0]);)l.shift();for(;l.length>0&&e(l[l.length-1]);)l.pop();return l}};class MultiValueMap{data={};add(t,e){let l=this.data,s=l[t];s||(s=new Set,l[t]=s),s.add(e)}R(){for(let t in this.data)return!0;return!1}getAll(t){return this.data[t]||[]}delete(t,e=void 0){let l,s=this.data,i=s[t];if(i)return void 0===e?([l]=i,i.delete(l)):(i.delete(e),l=e),0===i.size&&delete s[t],l}V(t){let e,l=this.data,s=l[t];if(s)return[e]=s,s.delete(e),0===s.size&&delete l[t],e}L(t,e){let l,s=this.data,i=s[t];if(i)return i.delete(e),l=e,0===i.size&&delete s[t],l}W(t){let e=this.data,l=[];for(let s in e)e[s].has(t)&&l.push(s);return l}}const udomdiff=(t,e,l,s)=>{const i=l.length;let r=e.length,o=i,a=0,n=0,h=null;for(;r>a||o>n;)if(r===a){const e=i>o?n?l[n-1].nextSibling:l[o-n]:s;for(;o>n;){let s=l[n++];t.insertBefore(s,e)}}else if(o===n)for(;r>a;){let l=e[a];h&&h.has(l)||t.removeChild(l),a++}else if(e[a]===l[n])a++,n++;else if(e[r-1]===l[o-1])r--,o--;else if(e[a]===l[o-1]&&l[n]===e[r-1]){const s=e[--r].nextSibling;let i=l[n++],h=e[a++];t.insertBefore(i,h.nextSibling);let f=l[--o];t.insertBefore(f,s),e[r]=l[o]}else{if(!h){h=new Map;let t=n;for(;o>t;)h.set(l[t],t++)}if(h.has(e[a])){const s=h.get(e[a]);if(s>n&&o>s){let i=a,f=1;for(;++i<r&&o>i&&h.get(e[i])===s+f;)f++;if(f>s-n){const i=e[a];for(;s>n;){let e=l[n++];t.insertBefore(e,i)}}else{let s=e[a++],i=l[n++];t.replaceChild(i,s)}}else a++}else{let l=e[a++];t.removeChild(l)}}return l};class ExprPath{type;attrName;D;_;Z;B;K;p=[];q;X;Y;tt;et;lt=void 0;constructor(t,e,l=ExprPathType.st,s=null,i=null){this.Z=t,this.B=e,this.type=l,this.attrName=s,this.D=i,l===ExprPathType.it&&(this._=new Set)}apply(t,e=!0){switch(this.type){case 1:this.rt(t[0],e);break;case 2:this.ot(this.B,t[0]);break;case 4:break;case 5:this.nt(this.B,t[0],this.K.ht.root);break;default:this.ft(this.B,t)}}rt(t,e=!0){let l=this;e&&l.ut();let s=[],i=l.p,r=[];l.p=[],l.dt(t,s,r);let o=!1;if(r.length){for(let[t,e]of r){let i=l.ct(s[t],!1),r=i.bt();1===r.length?s[t]=r[0]:(s[t]=r,o=!0),l.p[e]=i}o&&(s=s.flat())}let a=l.bt();if(!Util.T(a,s)){l.q=s,this.K.yt&&this.K.yt.gt(),a.length&&!s.length&&l.$t()||udomdiff(l.B.parentNode,a,s,l.B);for(let t of i)t.Et.parentNode||t.vt();for(let t of s)if(1===t?.nodeType){t.hasAttribute("solarite-placeholder")&&this.K.Pt(t,null,!0);for(let e of t.querySelectorAll("[solarite-placeholder]"))this.K.Pt(e,null,!0)}}}Tt(t){let e=Math.min(t.Nt,t.items.length),l=t.Nt-e;for(let l=0;e>l;l++){let e=this.p[t.index+l],s=(this.et||this.tt)(t.items[l]);this.Gt(s,(s=>{let i=this.ct(s,!0);if(i&&i===e);else{i||(i=this.ct(s,!1)),this.p[t.index+l]=i;let r=e.Et;for(let t of i.bt())r.parentNode.insertBefore(t,r);i!==e&&e.vt()}}))}if(l>0){for(let s=0;l>s;s++)this.p[t.index+e+s].vt();this.p.splice(t.index+e,l)}else{let l=t.items.slice(e),s=this.p[t.index+e]?.Et||this.B;for(let t=0;l.length>t;t++){let e=this.et(l[t]),i=this.ct(e,!0);i||(i=this.ct(e,!1)),this.p.push(i);for(let t of i.bt())s.parentNode.insertBefore(t,s)}}this.q=null}Gt(t,e){if(Array.isArray(t))for(let l of t)this.Gt(l,e);else if("function"==typeof t)Globals$1.l=this,this.tt=t,t=t(),Globals$1.l=null,this.Gt(t,e);else if(t instanceof Template||t?.nodeType)e(t);else{void 0===t||!1===t||null===t?t="":"string"!=typeof t&&(t+="");let l=new Template([t],[]);l.wt=!0,this.Gt(l,e)}}dt(t,e,l){if(t instanceof Template){let s=this.ct(t,!0);if(s){let l=s.bt();e.push(...l);let i=!1;for(let e of l)if(1===e?.nodeType){e.tagName.includes("-")&&(t.xt.find((t=>t?.B===e))?i=!0:this.K.Pt(e,null,!0));for(let l of e.querySelectorAll("*"))l.tagName.includes("-")&&(t.xt.find((t=>t?.B===l))?i=!0:this.K.Pt(l,null,!0))}return i&&s.At(t.xt),this.p.push(s),s}l.push([e.length,this.p.length]),e.push(t),this.p.push(null)}else t?.nodeType?11===t?.nodeType?e.push(...t.childNodes):e.push(t):this.Gt(t,(t=>{this.dt(t,e,l)}))}ot(t,e){Array.isArray(e)&&(e=e.flat().join(" "));let l=this._;if(this._=new Set,e)if("function"==typeof e&&(Globals$1.l=this,this.tt=e,e=e(),Globals$1.l=null),"object"==typeof e)for(let l in e){let s=e[l];void 0!==s&&!1!==s&&null!==s&&(t.setAttribute(l,s),this._.add(l))}else{let l=(e+"").split(/([\w-]+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s]+))/g).map((t=>t.trim())).filter((t=>t.length));for(let e of l){let[l,s]=e.split(/\s*=\s*/);s=(s||"").replace(/^(['"])(.*)\1$/,"$2"),t.setAttribute(l,s),this._.add(l)}}for(let e of l)this._.has(e)||t.removeAttribute(e)}nt(t,e,l){let s,i=this.attrName.slice(2),r=[];if(Array.isArray(e)&&"function"==typeof e[0])s=e[0],r=e.slice(1);else{if("function"!=typeof e)throw Error(`Invalid event binding: <${t.tagName.toLowerCase()} ${this.attrName}=\${${JSON.stringify(e)}}>`);s=e}this.St(t,l,i,i,s,r)}St(t,e,l,s,i,r,o=!1){let a=Globals$1.u.get(t);a||(a={[l]:[,,,]},Globals$1.u.set(t,a));let n=a[l];if(n||(a[l]=n=[,,,]),"function"!=typeof i)throw Error(`Solarite cannot bind to <${t.tagName.toLowerCase()} ${this.attrName}=\${${i}}> because it's not a function.`);if(n[0]!==i){let[l,r,a]=n;l&&t.removeEventListener(s,r,o);let h=i,f=l=>h.call(e,...n[2],l,t);n[0]=h,n[1]=f,t.addEventListener(s,f,o)}a[l][2]=r}ft(t,e){let l=e[0];if(Util.j(l)){let[e,s]=[l[0],l.slice(1)];if(!e)throw Error(`Solarite cannot bind to <${t.tagName.toLowerCase()} ${this.attrName}=\${[${l.map((t=>t?`'${t}'`:t+"")).join(", ")}]}>.`);let i=delve(e,s);if("value"===this.attrName&&"select-multiple"===t.type&&Array.isArray(i)){let e=i.map((t=>t+""));for(let l of t.options)l.selected=e.includes(l.value)}else{const e=Util.U(i)?"":i;"value"===this.attrName&&t.hasAttribute("contenteditable")?e!==t.innerHTML&&(t.innerHTML=e):e!==t[this.attrName]&&(t[this.attrName]=e)}let r=()=>{let l="value"===this.attrName?Util.O(t):t[this.attrName];delve(e,s,l)};this.St(t,s[0],this.attrName,"input",r,[],!0)}else{let s=this.lt;void 0===s&&(s=this.lt=Util.M(t,this.attrName));let i=this.D;if(!i){if(Globals$1.l=this,"function"==typeof l){if(this.Ct)return;this.tt=l,l=l()}else l=Util.I(l);Globals$1.l=null}if(i||void 0!==l&&!1!==l&&null!==l)if(i||!0!==l){let r;if(i){let t=[];for(let l=0;this.D.length>l;l++)if(t.push(this.D[l]),this.D.length-1>l){Globals$1.l=this;let s=Util.I(e[l]);Globals$1.l=null,Util.U(s)||t.push(s)}r=t.join("")}else r=l;(s?t[this.attrName]:t.getAttribute(this.attrName))!==r&&(s?t[this.attrName]=r:t.hasAttribute("contenteditable")&&(t.innerHTML=r),t.setAttribute(this.attrName,r))}else s&&(t[this.attrName]=!0),t.setAttribute(this.attrName,"");else s&&(t[this.attrName]=!1),t.removeAttribute(this.attrName)}}clone(t,e=0){let l,s,i=t,r=e?this.Y.slice(0,-e):this.Y;for(let t=r.length-1;t>0;t--)i=i.childNodes[r[t]];let o=i.childNodes;l=r.length?o[r[0]]:t,this.Z&&(s=o[this.X]);let a=new ExprPath(s,l,this.type,this.attrName,this.D);return a.Ct=this.Ct,a}gt(){let t=this,e=this.B.parentNode;for(;t&&t.B.parentNode===e;)t.q=null,t=t.K?.yt}$t(){let t=this.Z.parentNode;return this.Z===t.firstChild&&this.B===t.lastChild&&(t.innerHTML="",t.append(this.Z,this.B),!0)}bt(){if(this.type===ExprPathType.Ht||this.type===ExprPathType.it)return[this.B];let t;if(t=this.q,t)return t;t=[];let e=this.Z.nextSibling,l=this.B;for(;e&&e!==l;)t.push(e),e=e.nextSibling;return this.q=t,t}Ot(){return this.B.parentNode}ct(t,e=!0){let l,s=this.kt;if(e){if(l=s.V(t.Mt()),l||(s=this.jt,l=s.V(t.Mt())),!l)return null;s.L(t.Ut(),l)}else t.xt.length&&(l=s.V(t.Ut()),l||(s=this.jt,l=s.V(t.Ut())),l&&(s.L(l.It,l),l.At(t.xt),l.It=t.Mt()));return l||(l=new NodeGroup(t,this)),this.Ft.push(l),l}Ft=[];kt=new MultiValueMap;jt=new MultiValueMap;ut(){let t=this.kt.data,e=this.jt.data;for(let l in t){let s=e[l];if(s)for(let e of t[l])s.add(e);else e[l]=t[l]}this.kt=new MultiValueMap;let l=this.kt;for(let t of this.Ft)l.add(t.It,t),l.add(t.Jt,t);this.Ft=[]}}const ExprPathType={st:1,it:2,Ht:3,Comment:4,Event:5};function getNodePath(t){let e=[];for(;;){let l=t.parentNode;if(!l)break;e.push([].indexOf.call(t.parentNode.childNodes,t)),t=l}return e}function resolveNodePath(t,e){for(let l=e.length-1;l>=0;l--)t=t.childNodes[e[l]];return t}class HtmlParser{constructor(){this.Rt={context:HtmlParser.Text,quote:null,buffer:"",Vt:null},this.state={...this.Rt}}reset(){return this.state={...this.Rt},this.state.context}parse(t,e=null){if(null===t)return this.reset();for(let l=0;t.length>l;l++){const s=t[l];switch(this.state.context){case HtmlParser.Text:"<"===s&&t[l+1].match(/[/a-z!]/i)&&(e?.(t,l,this.state.context,HtmlParser.Lt),this.state.context=HtmlParser.Lt,this.state.buffer="");break;case HtmlParser.Lt:if(">"===s)e?.(t,l+1,this.state.context,HtmlParser.Text),this.state.context=HtmlParser.Text,this.state.quote=null,this.state.buffer="";else{if(" "===s&&!this.state.buffer)continue;" "===s||"/"===s||"?"===s?this.state.buffer="":'"'===s||"'"===s||"="===s?(e?.(t,l,this.state.context,HtmlParser.zt),this.state.context=HtmlParser.zt,this.state.quote="="===s?null:s,this.state.buffer=""):this.state.buffer+=s}break;case HtmlParser.zt:this.state.quote||this.state.buffer.length||'"'!==s&&"'"!==s?s===this.state.quote||!this.state.quote&&this.state.buffer.length?(e?.(t,l,this.state.context,HtmlParser.Lt),this.state.context=HtmlParser.Lt,this.state.quote=null,this.state.buffer=""):this.state.quote||">"!==s?" "!==s&&(this.state.buffer+=s):(e?.(t,l+1,this.state.context,HtmlParser.Text),this.state.context=HtmlParser.Text,this.state.quote=null,this.state.buffer=""):this.state.quote=s}}return e?.(t,t.length,this.state.context,null),this.state.context}}HtmlParser.zt="Attribute",HtmlParser.Text="Text",HtmlParser.Lt="Tag";class Shell{fragment;Wt=[];Dt=[];scripts=[];_t=[];Zt=[];constructor(t=null){if(!t)return;if(1===t.length&&!t[0].match(/[<&]/))return void(this.fragment=Globals$1.i.createTextNode(t[0]));let e,l=Shell.Bt(t),s=Globals$1.i.createElement("template");l?s.innerHTML=l:s.content.append(Globals$1.i.createTextNode("")),this.fragment=s.content;let i=[],r=0;const o=Globals$1.i.createTreeWalker(this.fragment,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT|NodeFilter.SHOW_TEXT);for(;e=o.nextNode();)if(i.map((t=>t.remove())),i=[],1===e.nodeType)for(let t of[...e.attributes]){let l=t.name.match(/^[\ue000-\uf8ff]$/);if(l)this.Wt.push(new ExprPath(null,e,ExprPathType.it)),r++,e.removeAttribute(l[0]);else{let l=t.value.split(/[\ue000-\uf8ff]/g);if(l.length>1){let s=2!==l.length||l[0].length||l[1].length?l:null,i=Util.k(t.name)?ExprPathType.Event:ExprPathType.Ht;this.Wt.push(new ExprPath(null,e,i,t.name,s)),r+=l.length-1,e.setAttribute(t.name,l.join(""))}}}else if(8===e.nodeType&&"!✨!"===e.nodeValue){if(e?.parentNode?.closest&&e?.parentNode?.closest("[contenteditable]"))throw Error('Contenteditable can\'t have expressions inside them. Use <div contenteditable value="${...}"> instead.');let t,l=e.previousSibling;l||(l=Globals$1.i.createComment("ExprPath:"+this.Wt.length),e.parentNode.insertBefore(l,e)),!e.nextSibling||8===e.nextSibling.nodeType&&"!✨!"===e.nextSibling.textContent?(t=e,t.textContent="ExprPathEnd:"+this.Wt.length):(t=e.nextSibling,i.push(e));let s=new ExprPath(l,t,ExprPathType.st);this.Wt.push(s),r++}else{if(3===e.nodeType&&"TEXTAREA"===e.parentNode?.tagName&&e.textContent.includes("\x3c!--!✨!--\x3e"))throw Error('Textarea can\'t have expressions inside them. Use <textarea value="${...}"> instead.');if(e.nodeType===Node.COMMENT_NODE){let t=e.textContent.split(/[\ue000-\uf8ff]/g);for(let l=0;t.length-1>l;l++){let t=new ExprPath(e.previousSibling,e);t.type=ExprPathType.Comment,this.Wt.push(t),r++}}else if(e.nodeType===Node.TEXT_NODE&&["SCRIPT","STYLE"].includes(e.parentNode?.nodeName)){let t=e.textContent.split(commentPlaceholder);if(t.length>1){let l=[];for(let s=0;t.length>s;s++){let i=Globals$1.i.createTextNode(t[s]);e.parentNode.insertBefore(i,e),s>0&&l.push(i)}for(let t,e=0;t=l[e];e++){let e=new ExprPath(t.previousSibling,t,ExprPathType.st);this.Wt.push(e),r++}i.push(e)}}}if(i.map((t=>t.remove())),r!==t.length-1)throw Error("Could not parse expressions in template. Check for duplicate attributes or malformed html: "+t.join("${...}"));for(let t of this.fragment.querySelectorAll("[is]"))t.setAttribute("_is",t.getAttribute("is"));for(let t of this.Wt)t.Z&&(t.X=[].indexOf.call(t.Z.parentNode.childNodes,t.Z)),t.Y=getNodePath(t.B),t.type!==ExprPathType.Ht&&t.type!==ExprPathType.Event||1!==t.B.nodeType||!t.B.tagName.includes("-")&&!t.B.hasAttribute("is")||(t.Ct=!0);this.Kt()}static Bt(t){let e=[];function l(t,l){l===HtmlParser.Lt&&(t=t.replace(/^<\/?[a-z][a-z0-9]*-[a-z0-9-]+/i,(t=>t+"-solarite-placeholder solarite-placeholder"))),e.push(t)}let s=new HtmlParser;for(let i=0;t.length>i;i++){let r=0,o=s.parse(t[i],((t,e,s,i)=>{r!==e&&l(t.slice(r,e),s),r=e}));t.length-1>i&&e.push(o===HtmlParser.Text?commentPlaceholder:String.fromCharCode(attribPlaceholder+i))}return e.join("")}Kt(){this.scripts=[].map.call(this.fragment.querySelectorAll("scripts"),(t=>getNodePath(t))),this._t=[].map.call(this.fragment.querySelectorAll("style"),(t=>getNodePath(t)));let t=this.fragment.querySelectorAll("[id],[data-id]");for(let e of t){let t=e.getAttribute("data-id")||e.getAttribute("id");if(Globals$1.div.hasOwnProperty(t))throw Error(`<${e.tagName.toLowerCase()} id="${t}"> can't override existing HTMLElement id property.`)}this.Dt=[].map.call(t,(t=>getNodePath(t)));for(let t of this.fragment.querySelectorAll("*"))(t.tagName.includes("-")||t.hasAttribute("_is"))&&(this.Wt.find((e=>e.B===t))||this.Zt.push(getNodePath(t)))}static get(t){let e=Globals$1.P.get(t);return e||(e=new Shell(t),Globals$1.P.set(t,e)),e}}const commentPlaceholder="\x3c!--!✨!--\x3e",attribPlaceholder=57344;class NodeGroup{ht;yt;Et;qt;Wt=[];It;Jt;q;_t;Xt=new Set;Zt=[];Yt;constructor(t,e=null){if(this.ht=e?.K?.ht||this,this.yt=e,!(this instanceof RootNodeGroup)){let[e,l]=this.Qt(t);e&&t.xt.length?(this.te(e,l.Wt),this.Zt=this.ee(e,l),this.le(e,l),this.At(t.xt),this.se(this.Zt)):l&&this.le(e,l)}}Qt(t){if(this.Yt=t,this.It=t.Mt(),this.Jt=t.Ut(),t.wt){let e=Globals$1.i.createTextNode(t.ie[0]);return this.Et=this.qt=e,[]}{let e=Shell.get(t.ie),l=e.fragment.cloneNode(!0);if(11===l?.nodeType){let t=l.childNodes;this.Et=t[0],this.qt=t[t.length-1]}else this.Et=this.qt=l;return[l,e]}}At(t,e=null){let l,s=t.length-1,i=Array((e=e||this.Wt).length);for(let r,o=e.length-1;r=e[o];o--){let a=e[o-1],n=e[o+1];if(r.D?.length>2?(i[o]=t.slice(s-(r.D.length-1)+1,s+1),s-=i[o].length):(i[o]=[t[s]],s--),r.B!==this.ht.root&&r.Ct){if(n&&n.Ct&&n.B===r.B||(l=o),!a||!a.Ct||a.B!==r.B){let t={};for(let s=o;l>=s;s++)t[e[s].attrName]=i[s].length>1?i[s].join(""):i[s][0];this.Pt(r.B,t,!0);for(let t=o;l>=t;t++)e[t].apply(i[t])}}else r.apply(i[o])}this.re();for(let t of this.Zt)t.oe&&t.oe(Util.N(t));this.q=null}Pt(t,e=null,l=!0){let s,i,r=t.hasAttribute("solarite-placeholder"),o=t.hasAttribute("_is");if((r||o)&&([t,s,i]=this.ae(t,r,e)),l&&t.oe){if(!s){s=Util.N(t);for(let t in e||{})s[Util.G(t)]=e[t];i=t.childNodes}t.oe(s,i)}return t}ae(t,e=void 0,l=void 0){void 0===e&&(e=!t.hasAttribute("_is"));let s=(e?t.tagName.slice(0,-21):t.getAttribute("is")).toLowerCase(),i=customElements.get(s);if(!i)throw Error(`The custom tag name ${s} is not registered.`);let r=Util.N(t,"solarite-placeholder");for(let t in l||{})r[Util.G(t)]=l[t];let o=[...t.childNodes].filter((t=>t.nodeType!==Node.COMMENT_NODE||!t.nodeValue.startsWith("ExprPath"))),a=new i(r,o);e||a.setAttribute("is",t.getAttribute("is").toLowerCase()),t.replaceWith(a);let n=t.getAttribute("data-id")||t.getAttribute("id");n&&delve(this.getRootNode(),n.split(/\./g),a);for(let e of this.Wt)e.B===t&&(e.B=a),e.Z===t&&(e.Z=a);this.Et===t&&(this.Et=a),this.qt===t&&(this.qt=a),a.ne&&a.ne();for(let e of t.attributes)"_is"!==e.name&&"solarite-placeholder"!==e.name&&a.setAttribute(e.name,e.value);for(let t in l){let e=l[t];"boolean"==typeof e?!1!==e&&null!=e&&a.setAttribute(t,""):["number","bigint","string"].includes(typeof e)&&a.setAttribute(t,e)}return[a,r,o]}bt(){let t=this.q;if(t)return t;t=[];let e=this.Et,l=this.qt?.nextSibling;for(;e&&e!==l;)t.push(e),e=e.nextSibling;return this.q=t,t}Ot(){return this.Et?.parentNode}getRootNode(){return this.ht.root}he(){return this.ht}vt(){let t=Globals$1.i.createDocumentFragment();for(let e of this.bt())t.append(e)}te(t,e,l){let s=e.length;this.Wt.length=s;for(let i=0;s>i;i++){let s=e[i].clone(t,l);s.K=this,this.Wt[i]=s}}re(){if(this._t)for(let[t,e]of this._t)e!==t.textContent&&Util.S(t,this.he().root)}ee(t,e,l=0){let s=[];for(let i of e.Zt){l&&(i=i.slice(0,-l));let e=resolveNodePath(t,i);t!==e&&s.push(e)}return s}se(t){for(let e in t)t[e]=this.Pt(t[e],null,!1)}le(root,shell,pathOffset=0){let rootEl=this.ht.root;if(rootEl){let options=this.ht.options;if(!1!==options?.Dt)for(let t of shell.Dt){pathOffset&&(t=t.slice(0,-pathOffset));let e=resolveNodePath(root,t);Util.A(rootEl,e)}if(!1!==options?._t){shell._t.length&&(this._t=new Map);for(let t of shell._t){pathOffset&&(t=t.slice(0,-pathOffset));let e=resolveNodePath(root,t);1===rootEl.nodeType&&(Util.S(e,rootEl),this._t.set(e,e.textContent))}}if(!1!==options?.scripts)for(let path of shell.scripts){pathOffset&&(path=path.slice(0,-pathOffset));let script=resolveNodePath(root,path);eval(script.textContent)}}}}class RootNodeGroup extends NodeGroup{root;fe=new Map;constructor(t,e,l){super(t),this.options=l;let[s,i]=this.Qt(t),r=0;if(s instanceof Text){if(!e)throw Error("Cannot create a standalone text node");this.Et=e,this.qt=e,s.nodeValue.length&&e.append(s),this.root=e,Globals$1.p.set(this.root,this)}else{if(e){let t;if(this.root=e,e.childNodes.length&&(t=Globals$1.i.createDocumentFragment(),t.append(...e.childNodes)),isReplaceEl(s,e)){e.append(...s.children[0].childNodes);for(let t of s.children[0].attributes)e.hasAttribute(t.name)||"solarite-placeholder"===t.name||e.setAttribute(t.name,t.value);r=1}else 1===s.childNodes.length&&3===s.childNodes[0].nodeType&&""===s.childNodes[0].textContent||e.append(...s.childNodes);if(t){for(let l of e.querySelectorAll("slot[name]")){let e=l.getAttribute("name");if(e){let s=t.querySelectorAll(`[slot='${e}']`);l.append(...s)}}let l=e.querySelector("slot:not([name])");l?l.append(t):e.append(t)}this.Et=e,this.qt=e}else{let t=getSingleEl(s);this.root=t||s,t&&(r=1)}Globals$1.p.set(this.root,this),this.te(this.root,i.Wt,r),this.Zt=this.ee(this.root,i,r),this.le(this.root,i,r),this.At(t.xt),this.se(this.Zt)}}}function getSingleEl(t){let e=[];for(let l of t.childNodes)if(1===l.nodeType||3===l.nodeType&&l.textContent.trim().length){if(e.length)return null;e.push(l)}return e[0]}function isReplaceEl(t,e){return 1===t.children.length&&e.tagName.includes("-")&&t.children[0].tagName.replace("-SOLARITE-PLACEHOLDER","")===e.tagName}class Template{xt=[];ie=[];ue;wt;constructor(t,e){this.ie=t,this.xt=e}toJSON(){return this.ue||(this.ue=[getObjectId(this.ie),this.xt]),this.ue}oe(t=null,e={}){let l,s=!1;if(t){if(l=Globals$1.p.get(t),l||(l=new RootNodeGroup(this,t,e),Globals$1.p.set(t,l),s=!0),0===l.Wt.length&&this.xt.length||l.Wt.length>this.xt.length)throw Error(`Solarite Error: Parent HTMLElement ${l.Yt.ie.join("${...}")} and ${l.Wt.length} \${value} placeholders can't accomodate a Template with ${this.xt.length} values.`)}else l=new RootNodeGroup(this,null,e),t=l.getRootNode(),Globals$1.p.set(t,l),s=!0;return s||(1!==this.ie?.length||this.ie[0]?l.At(this.xt):t.innerHTML=""),l.fe=new Map,t}Mt(){return this.It||(this.It=this.xt.length?getObjectHash(this):this.ie[0]),this.It}Ut(){return this.Jt||(this.Jt=this.xt.length?this.toJSON()[0]:this.ie[0]),this.Jt}static de(t,e,l){const s=selfClosingTags.has(t.toLowerCase());let i=[],r=[],o="<"+t;if(e&&"object"==typeof e)for(let t in e){let l=e[t];"id"!==t&&"data-id"!==t?(o+=` ${t}=`,i.push(o),r.push(l),o=""):o+=` ${t}="${l}"`}if(!s){i.push(i.length>0?'"'===o?'">':">":o+">");for(let t of l)addChild(t,i,r)}return s?i.push(i.length>0?">":o+">"):i[i.length-1]+=`</${t}>`,new Template(i,r)}}const selfClosingTags=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),addChild=(t,e,l)=>{if(Array.isArray(t))for(let s of t)addChild(s,e,l);else{let s=!1;if(t instanceof Template)if(t.xt.length>0)s=!0;else{const e=(t.ie[0]||"").match(/^<([a-zA-Z][\w:-]*)/),l=e?e[1].toLowerCase():"";s=selfClosingTags.has(l)}if(s){e[e.length-1]+=t.ie[0];for(let s=0;t.xt.length>s;s++)l.push(t.xt[s]),e.push(t.ie[s+1]??"")}else l.push(t),e.push("")}};function toEl(t){if("string"==typeof t){let e=t;(e.match(/^\s^</)||e.match(/>\s+$/))&&(e=e.trim());let l=Globals$1.i.createElement("template");l.innerHTML=e;let s=Util.J(l.content.childNodes);return 1===s.length?s[0]:l.content}if(t instanceof Template)return t.oe();if(t&&"object"==typeof t){let e=t;if("Object"!==e.constructor.name)throw Error(`Solarate Web Component class ${e.constructor?.name} must extend HTMLElement.`);if(!Globals$1.m.has(e)){Globals$1.m.set(e,null),e[renderF]();let t=Globals$1.m.get(e);Globals$1.m.delete(e);for(let l in e)t[l]="function"==typeof e[l]?e[l].bind(t):e[l];return t}}throw Error("toEl() does not support argument of type: "+(t?typeof t:t))}let renderF="render";function h(t=void 0,...e){if(Array.isArray(arguments[0]))return new Template(arguments[0],e);if("string"==typeof arguments[0]||arguments[0]instanceof String){let t=arguments[0];if(!e.length||"object"!=typeof e[0]&&null!==e[0]){let e=t;return e.match(/^\s^</)&&(e=e.trim()),new Template([e],[])}{let l=t+"",s=e[0]||{},i=e.slice(1);return Template.de(l,s,i)}}if(arguments[0]instanceof HTMLElement||arguments[0]instanceof DocumentFragment){if(!(arguments[1]instanceof Template)){let t=arguments[0],e=arguments[1];t.shadowRoot&&(t.innerHTML="");let l=(l,...s)=>(Globals$1.$.add(t),new Template(l,s).oe(t,e));return l}arguments[1].oe(arguments[0],arguments[2])}else{if(!arguments.length)return(t,...e)=>toEl(h(t,...e));if("object"!=typeof arguments[0]||!Globals$1.m.has(arguments[0]))throw Error("h() does not support argument of type: "+(arguments[0]?typeof arguments[0]:arguments[0]));{let t=arguments[0];if("Object"!==t.constructor.name)throw Error(`Solarate Web Component class ${t.constructor?.name} must extend HTMLElement.`);if(!(arguments[1]instanceof Template))return((...e)=>{let l=h(...e).oe();Globals$1.m.set(t,l)}).bind(t);{let e=arguments[1].oe();Globals$1.m.set(t,e)}}}}function getArg(el,attributeName,defaultValue=void 0,type=ArgType.String,fallback=void 0){let val=defaultValue,attrVal=el.getAttribute(attributeName)||el.getAttribute(Util.H(attributeName)),result;if(null!==attrVal&&(val=attrVal),Array.isArray(type))return type.includes(val)?val:fallback;if("function"==typeof type)return type.constructor?new type(val):type(val);if(type===ArgType.ce){let t="string"==typeof val?val.toLowerCase():val;return!["false","0",!1,0,null,void 0,NaN].includes(t)&&(!(!["true",!0].includes(t)&&0===parseFloat(t))||fallback)}switch(type){case ArgType.pe:return result=parseInt(val),isNaN(result)?fallback:result;case ArgType.be:return result=parseFloat(val),isNaN(result)?fallback:result;case ArgType.String:return[void 0,null,!1].includes(val)?"":val+"";case ArgType.me:case ArgType.ye:if("string"!=typeof val||!val.length)return val;try{return type===ArgType.me?JSON.parse(val):eval(`(${val})`)}catch(t){return val}default:return val}}function setArgs(t,e,l){for(let s in e)this[s]=getArg(t,s,e[s],l[s]||ArgType.String)}var ArgType={ce:"Bool",pe:"Int",be:"Float",String:"String",JSON:"Json",me:"Json",ye:"Eval"};function defineClass(t,e,l){if(!customElements[getName](t)){(e=e||Util.H(t.name)).includes("-")||(e+="-element");let s=null;l&&(s={ge:l}),customElements[define](e,t,s)}}function createSolarite(t=null){let e=HTMLElement;t&&!t.includes("-")&&(t=t.toLowerCase(),e=Globals$1.o[t],e||(e=Globals$1.i.createElement(t).constructor,Globals$1.o[t]=e));let l=new Proxy(e,{construct:(e,l,s)=>(defineClass(s,null,t),Reflect.construct(e,l,s))});return class extends l{$e;Ee;ve;constructor(t={}){super(),!0===t.oe?this.oe():!1===t.oe&&Globals$1.$.add(this)}ne(){!Globals$1.$.has(this)&&this.oe&&this.oe()}Pe(){this.ne(),Globals$1.connected.has(this)||(Globals$1.connected.add(this),this.Ee&&this.Ee()),this.$e&&this.$e()}Te(){this.ve&&this.ve()}static define(e=null){defineClass(this,e,t)}}}let define="define",getName="getName";
5
+ /*
6
+ ┏┓ ┓ •
7
+ ┗┓┏┓┃┏┓┏┓┓╋▗▖
8
+ ┗┛┗┛┗┗┻╹ ╹╹┗
9
+ JavasCript UI library
10
+ @license MIT
11
+ @copyright Vorticode LLC
12
+ https://vorticode.github.io/solarite/ */
13
+ const Solarite=new Proxy(createSolarite(),{apply:(t,e,l)=>createSolarite(...l)});export default h;export{ArgType,Globals$1 as Globals,Solarite,Util as SolariteUtil,Template,getArg,h,h as r,setArgs,toEl};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "solarite",
3
- "version": "0.3.1",
4
- "description": "Solarite is a small (8KB min+gzip), fast, compilation-free JavaScript library for adding reactivity to web components, so that updates require minimal re-rendering.",
3
+ "version": "0.4.0",
4
+ "description": "Solarite is a small (9KB min+gzip), fast, compilation-free JavaScript library for adding reactivity to native web components, so that updates require minimal re-rendering.",
5
5
  "main": "dist/Solarite.js",
6
6
  "files": [
7
7
  "readme.md",
package/readme.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Solarite
2
2
 
3
- Solarite is a small (8KB min+gzip), fast, compilation-free JavaScript library for adding reactivity to web components, so that updates require minimal re-rendering. It follows modern web standards and is easy to use with vanilla JavaScript.
3
+ Solarite is a smal, fast, compilation-free JavaScript library for performing minimal DOM updates on web components when your data changes. It follows modern web standards and is easy to use with vanilla JavaScript.
4
4
 
5
5
  For documentation and examples, see the **[Official Solarite Page](https://vorticode.github.io/solarite/)**.
6
6
 
7
- Download [Solarite.js](https://vorticode.github.io/solarite/dist/Solarite.js) (111KB, 8.8KB min+gzip)
7
+ Download [Solarite.js](https://vorticode.github.io/solarite/dist/Solarite.js) (117KB, 9KB min+gzip)
8
8
 
9
9
  Or:
10
10
 
package/src/ExprPath.js CHANGED
@@ -127,13 +127,13 @@ export default class ExprPath {
127
127
  case 2: // PathType.Multiple:
128
128
  this.applyMultipleAttribs(this.nodeMarker, exprs[0]);
129
129
  break;
130
- case 5: // PathType.Comment:
130
+ case 4: // PathType.Comment:
131
131
  // Expressions inside Html comments. Deliberately empty because we won't waste time updating them.
132
132
  break;
133
- case 6: // PathType.Event:
133
+ case 5: // PathType.Event:
134
134
  this.applyEventAttrib(this.nodeMarker, exprs[0], this.parentNg.rootNg.root);
135
135
  break;
136
- default: // TODO: Is this still used? Lots of tests fail without it.
136
+ default: // 3 PathType.Attribute
137
137
  // One attribute value may have multiple expressions. Here we apply them all at once.
138
138
  this.applyValueAttrib(this.nodeMarker, exprs);
139
139
  break;
@@ -143,7 +143,7 @@ export default class ExprPath {
143
143
  /**
144
144
  * Insert/replace the nodes created by a single expression.
145
145
  * Called by applyExprs()
146
- * This function is recursive, as the functions it calls also call it.
146
+ * This function is recursive. It calls functions that call applyNodes().
147
147
  * @param expr {Expr}
148
148
  * @param freeNodeGroups {boolean}
149
149
  * @return {Node[]} New Nodes created. */
@@ -178,7 +178,6 @@ export default class ExprPath {
178
178
  if (secondPass.length) {
179
179
  for (let [nodesIndex, ngIndex] of secondPass) {
180
180
  let ng = path.getNodeGroup(newNodes[nodesIndex], false);
181
-
182
181
  let ngNodes = ng.getNodes();
183
182
 
184
183
  /*#IFDEV*/assert(!(newNodes[nodesIndex] instanceof NodeGroup))/*#ENDIF*/
@@ -199,11 +198,8 @@ export default class ExprPath {
199
198
 
200
199
  /*#IFDEV*/assert(!path.nodeGroups.includes(null))/*#ENDIF*/
201
200
 
202
-
203
-
204
201
  let oldNodes = path.getNodes();
205
202
 
206
-
207
203
  // This pre-check makes it a few percent faster?
208
204
  let same = Util.arraySame(oldNodes, newNodes);
209
205
  if (!same) {
@@ -216,7 +212,6 @@ export default class ExprPath {
216
212
  // Fast clear method
217
213
  let isNowEmpty = oldNodes.length && !newNodes.length;
218
214
  if (!isNowEmpty || !path.fastClear())
219
-
220
215
  // Rearrange nodes.
221
216
  udomdiff(path.nodeMarker.parentNode, oldNodes, newNodes, path.nodeMarker)
222
217
 
@@ -228,22 +223,18 @@ export default class ExprPath {
228
223
  if (!ng.startNode.parentNode)
229
224
  ng.removeAndSaveOrphans();
230
225
 
231
-
232
-
233
-
234
226
  // Instantiate components created within ${...} expressions.
235
- // Embedded style tags are handled elsewhere, but where?
227
+ // Also see this.applyExactNodes() which handles calling render() on web components even if they are unchanged.
236
228
  for (let el of newNodes) {
237
- if (el instanceof HTMLElement) {
229
+ if (el?.nodeType === 1) { // HTMLElement
238
230
  if (el.hasAttribute('solarite-placeholder'))
239
- this.parentNg.instantiateComponent(el);
231
+ this.parentNg.handleComponent(el, null, true);
240
232
  for (let child of el.querySelectorAll('[solarite-placeholder]'))
241
- this.parentNg.instantiateComponent(child);
233
+ this.parentNg.handleComponent(child, null, true);
242
234
  }
243
235
  }
244
236
  }
245
237
 
246
-
247
238
  /*#IFDEV*/path.verify();/*#ENDIF*/
248
239
  }
249
240
 
@@ -356,7 +347,7 @@ export default class ExprPath {
356
347
  }
357
348
 
358
349
  // String/Number/Date/Boolean
359
- else if (!(expr instanceof Template) && !(expr instanceof Node)){
350
+ else if (!(expr instanceof Template) && !(expr?.nodeType)){
360
351
  // Convert expression to a string.
361
352
  if (expr === undefined || expr === false || expr === null) // Util.isFalsy() inlined
362
353
  expr = '';
@@ -366,7 +357,9 @@ export default class ExprPath {
366
357
  // Get the same Template for the same string each time.
367
358
  // let template = Globals.stringTemplates[expr];
368
359
  // if (!template) {
360
+
369
361
  let template = new Template([expr], []);
362
+ template.isText = true;
370
363
  // Globals.stringTemplates[expr] = template;
371
364
  //}
372
365
 
@@ -391,12 +384,44 @@ export default class ExprPath {
391
384
 
392
385
  if (expr instanceof Template) {
393
386
  let ng = this.getNodeGroup(expr, true);
387
+
394
388
  if (ng) {
389
+ let newestNodes = ng.getNodes();
390
+ newNodes.push(...newestNodes);
391
+
392
+ // New!
393
+ // Re-apply all expressions if there's a web component, so we can pass them to its constructor.
394
+ // NodeGroup.applyExprs() is used to call applyComponentExprs() on web components that have expression attributes.
395
+ // For those that don't, we call applyComponentExprs() directly here.
396
+ // Also see similar code at the end of this.applyNodes() which handles web components being instantiated the first time.
397
+ let apply = false;
398
+ for (let el of newestNodes) {
399
+ if (el?.nodeType === 1) { // HTMLElement
400
+
401
+ if (el.tagName.includes('-')) {
402
+ if (!expr.exprs.find(expr => expr?.nodeMarker === el))
403
+ this.parentNg.handleComponent(el, null, true);
404
+ else // Commenting out this "else" causes render() to be called too often, but other UI code fails if it's present.
405
+ apply = true;
406
+ }
407
+ for (let child of el.querySelectorAll('*')) {
408
+ if (child.tagName.includes('-')) {
409
+ if (!expr.exprs.find(expr => expr?.nodeMarker === child))
410
+ this.parentNg.handleComponent(child, null, true);
411
+ else
412
+ apply = true;
413
+ }
414
+ }
415
+ }
416
+ }
395
417
 
396
- // TODO: Track ranges of changed nodes and only pass those to udomdiff?
397
- // But will that break the swap benchmark?
398
- newNodes.push(...ng.getNodes());
418
+ // This calls render() on web components that have expressions as attributes.
419
+ if (apply)
420
+ ng.applyExprs(expr.exprs);
421
+
399
422
  this.nodeGroups.push(ng);
423
+
424
+ return ng;
400
425
  }
401
426
 
402
427
  // If expression, mark it to be evaluated later in ExprPath.apply() to find partial match.
@@ -408,10 +433,10 @@ export default class ExprPath {
408
433
  }
409
434
 
410
435
  // Node(s) created by an expression.
411
- else if (expr instanceof Node) {
436
+ else if (expr?.nodeType) {
412
437
 
413
438
  // DocumentFragment created by an expression.
414
- if (expr instanceof DocumentFragment)
439
+ if (expr?.nodeType === 11) // DocumentFragment
415
440
  newNodes.push(...expr.childNodes);
416
441
  else
417
442
  newNodes.push(expr);
@@ -443,16 +468,30 @@ export default class ExprPath {
443
468
  Globals.currentExprPath = null;
444
469
  }
445
470
 
446
- let attrs = (expr +'') // Split string into multiple attributes.
447
- .split(/([\w-]+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s]+))/g)
448
- .map(text => text.trim())
449
- .filter(text => text.length);
471
+ // Attribute as name: value object.
472
+ if (typeof expr === 'object') {
473
+ for (let name in expr) {
474
+ let value = expr[name];
475
+ if (value === undefined || value === false || value === null)
476
+ continue;
477
+ node.setAttribute(name, value);
478
+ this.attrNames.add(name)
479
+ }
480
+ }
450
481
 
451
- for (let attr of attrs) {
452
- let [name, value] = attr.split(/\s*=\s*/); // split on first equals.
453
- value = (value || '').replace(/^(['"])(.*)\1$/, '$2'); // trim value quotes if they match.
454
- node.setAttribute(name, value);
455
- this.attrNames.add(name)
482
+ // Attributes as string
483
+ else {
484
+ let attrs = (expr + '') // Split string into multiple attributes.
485
+ .split(/([\w-]+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s]+))/g)
486
+ .map(text => text.trim())
487
+ .filter(text => text.length);
488
+
489
+ for (let attr of attrs) {
490
+ let [name, value] = attr.split(/\s*=\s*/); // split on first equals.
491
+ value = (value || '').replace(/^(['"])(.*)\1$/, '$2'); // trim value quotes if they match.
492
+ node.setAttribute(name, value);
493
+ this.attrNames.add(name)
494
+ }
456
495
  }
457
496
  }
458
497
 
@@ -473,8 +512,8 @@ export default class ExprPath {
473
512
  * @param root */
474
513
  applyEventAttrib(node, expr, root) {
475
514
  /*#IFDEV*/
476
- assert(this.type === ExprPathType.Event/* || this.type === PathType.Component*/);
477
- assert(root instanceof HTMLElement);
515
+ assert(this.type === ExprPathType.Event);
516
+ assert(root?.nodeType === 1);
478
517
  /*#ENDIF*/
479
518
 
480
519
  let eventName = this.attrName.slice(2); // remove "on-" prefix.
@@ -554,7 +593,7 @@ export default class ExprPath {
554
593
  }
555
594
 
556
595
  /**
557
- * Handle values, including two-way binding.
596
+ * Set the value of an attribute. This can be for any attribute, not just attributes named "value".
558
597
  * @param node
559
598
  * @param exprs */
560
599
  // TODO: node is always this.nodeMarker?
@@ -584,12 +623,21 @@ export default class ExprPath {
584
623
  }
585
624
  else {
586
625
  // TODO: should we remove isFalsy, since these are always props?
587
- let strValue = Util.isFalsy(value) ? '' : value;
626
+ const strValue = Util.isFalsy(value) ? '' : value;
627
+
628
+ // Special case for contenteditable
629
+ if (this.attrName === 'value' && node.hasAttribute('contenteditable')) {
630
+ const existingValue = node.innerHTML;
631
+ if (strValue !== existingValue)
632
+ node.innerHTML = strValue;
633
+ }
634
+ else {
588
635
 
589
- // If we don't have this condition, when we call render(), the browser will scroll to the currently
590
- // selected item in a <select> and mess up manually scrolling to a different value.
591
- if (strValue !== node[this.attrName])
592
- node[this.attrName] = strValue;
636
+ // If we don't have this condition, when we call render(), the browser will scroll to the currently
637
+ // selected item in a <select> and mess up manually scrolling to a different value.
638
+ if (strValue !== node[this.attrName])
639
+ node[this.attrName] = strValue;
640
+ }
593
641
  }
594
642
 
595
643
  // TODO: We need to remove any old listeners, like in bindEventAttribute.
@@ -609,16 +657,8 @@ export default class ExprPath {
609
657
 
610
658
  // Regular attribute
611
659
  else {
612
- // TODO: Cache this on ExprPath.isProp when Shell creates the props. Have ExprPath.clone() copy .isProp
613
- // Or make it a new PathType.
614
- //if (this.attrName === 'disabled')
615
- // debugger;
616
-
617
- // hasOwnProperty() checks only the object, not the parents
618
- // this.attrName in node checks the node and the parents.
619
- // This version checks the html element it extends from, to see if has a setter set:
620
- // Object.getOwnPropertyDescriptor(Object.getPrototypeOf(node), this.attrName)?.set
621
- //let isProp = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(node), this.attrName)?.set;
660
+ // Cache this on ExprPath.isHtmlProperty when Shell creates the props.
661
+ // Have ExprPath.clone() copy .isHtmlProperty?
622
662
  let isProp = this.isHtmlProperty;
623
663
  if (isProp === undefined)
624
664
  isProp = this.isHtmlProperty = Util.isHtmlProp(node, this.attrName);
@@ -628,7 +668,7 @@ export default class ExprPath {
628
668
  if (!multiple) {
629
669
  Globals.currentExprPath = this; // Used by watch()
630
670
  if (typeof expr === 'function') {
631
- if (this.type === 4) { // Don't evaluate functions before passing them to components
671
+ if (this.isComponent) { // Don't evaluate functions before passing them to components
632
672
  return
633
673
  }
634
674
  this.watchFunction = expr; // The function that gets the expression, used for renderWatched()
@@ -686,6 +726,13 @@ export default class ExprPath {
686
726
  // since we also prohibit expressions that are a child of textarea.
687
727
  if (isProp)
688
728
  node[this.attrName] = joinedValue;
729
+
730
+ // Allow one-way binding to contenteditable value attribute.
731
+ // Contenteditables normally don't have a value attribute and have their content set via innerHTML.
732
+ // Solarite doesn't allow contenteditables to have expressions as their children.
733
+ else if (node.hasAttribute('contenteditable'))
734
+ node.innerHTML = joinedValue;
735
+
689
736
  // TODO: Putting an 'else' here would be more performant
690
737
  node.setAttribute(this.attrName, joinedValue);
691
738
  }
@@ -716,11 +763,9 @@ export default class ExprPath {
716
763
  nodeBefore = childNodes[this.nodeBeforeIndex];
717
764
 
718
765
  let result = new ExprPath(nodeBefore, nodeMarker, this.type, this.attrName, this.attrValue);
766
+ result.isComponent = this.isComponent;
719
767
 
720
768
  //#IFDEV
721
- result.nodeMarker.exprPath = result;
722
- if (result.nodeBefore)
723
- result.nodeBefore.prevExprPath = result;
724
769
  result.verify();
725
770
  //#ENDIF
726
771
 
@@ -729,9 +774,7 @@ export default class ExprPath {
729
774
 
730
775
  /**
731
776
  * Clear the nodeCache of this ExprPath, as well as all parent and child ExprPaths that
732
- * share the same DOM parent node.
733
- *
734
- * TODO: Is recursive clearing ever necessary? */
777
+ * share the same DOM parent node. */
735
778
  clearNodesCache() {
736
779
  let path = this;
737
780
 
@@ -744,23 +787,6 @@ export default class ExprPath {
744
787
  // If stuck in an infinite loop here, the problem is likely due to Template hash colisions.
745
788
  // Which cause one path to be the descendant of itself, creating a cycle.
746
789
  }
747
-
748
- function clearChildNodeCache(path) {
749
-
750
- // Clear cache of child ExprPaths that have the same parentNode
751
- for (let ng of path.nodeGroups) {
752
- if (ng) // Can be null from apply()'s push(null) call.
753
- for (let path2 of ng.paths) {
754
- if (path2.type === ExprPathType.Content && path2.parentNode === parentNode) {
755
- path2.nodesCache = null;
756
- clearChildNodeCache(path2);
757
- }
758
- }
759
- }
760
- }
761
-
762
- // Commented out on Sep 30, 2024 b/c it was making the benchmark never finish when adding 10k rows.
763
- //clearChildNodeCache(this);
764
790
  }
765
791
 
766
792
 
@@ -802,7 +828,7 @@ export default class ExprPath {
802
828
  // result2.push(...ng.getNodes())
803
829
  // return result2;
804
830
 
805
- if (this.type === ExprPathType.AttribValue || this.type === ExprPathType.AttribMultiple || this.type === ExprPathType.ComponentAttribValue) {
831
+ if (this.type === ExprPathType.AttribValue || this.type === ExprPathType.AttribMultiple) {
806
832
  return [this.nodeMarker];
807
833
  }
808
834
 
@@ -862,11 +888,13 @@ export default class ExprPath {
862
888
  result = collection.deleteAny(template.getExactKey());
863
889
  }
864
890
 
865
- if (result) // also delete the matching close key.
891
+ if (result) {// also delete the matching close key.
866
892
  collection.deleteSpecific(template.getCloseKey(), result);
867
- else {
868
- return null;
893
+
894
+ //result.applyExprs(template.exprs);
869
895
  }
896
+ else
897
+ return null;
870
898
  }
871
899
 
872
900
  // Find a close match.
@@ -900,12 +928,6 @@ export default class ExprPath {
900
928
  return result;
901
929
  }
902
930
 
903
- isComponent() {
904
- // Events won't have type===Component.
905
- // TODO: Have a special flag for components instead of it being on the type?
906
- return this.type === ExprPathType.ComponentAttribValue || (this.attrName && this.nodeMarker.tagName && this.nodeMarker.tagName.includes('-'));
907
- }
908
-
909
931
  /**
910
932
  * TODO: Rename this to nodeGroupsInUse, nodeGroupsAvialableAttached and nodeGroupsAvailableDetached?
911
933
  * Nodes that have been used during the current render().
@@ -963,7 +985,7 @@ export default class ExprPath {
963
985
  `parentNode: ${this.nodeBefore.parentNode?.tagName?.toLowerCase()}`,
964
986
  'nodes:',
965
987
  ...setIndent(this.getNodes().map(item => {
966
- if (item instanceof Node)
988
+ if (item?.nodeType)
967
989
  return item.outerHTML || item.textContent
968
990
  else if (item instanceof NodeGroup)
969
991
  return item.debug
@@ -1054,7 +1076,7 @@ function setValue(root, path, node) {
1054
1076
  /** @enum {int} */
1055
1077
  export const ExprPathType = {
1056
1078
  /** Child of a node */
1057
- Content: 1,
1079
+ Content: 1, // TODO: Rename to Nodes
1058
1080
 
1059
1081
  /** One or more whole attributes */
1060
1082
  AttribMultiple: 2,
@@ -1062,14 +1084,11 @@ export const ExprPathType = {
1062
1084
  /** Value of an attribute. */
1063
1085
  AttribValue: 3,
1064
1086
 
1065
- /** Value of an attribute being passed to a component. */
1066
- ComponentAttribValue: 4,
1067
-
1068
1087
  /** Expressions inside Html comments. */
1069
- Comment: 5,
1088
+ Comment: 4,
1070
1089
 
1071
1090
  /** Value of an attribute. */
1072
- Event: 6,
1091
+ Event: 5,
1073
1092
  }
1074
1093
 
1075
1094
 
package/src/Globals.js CHANGED
@@ -6,8 +6,9 @@ function reset() {
6
6
  Globals = {
7
7
 
8
8
  /**
9
- * Used by NodeGroup.applyComponentExprs() */
10
- componentArgsHash: new WeakMap(),
9
+ * Dynamic values that should be passed to a Component's constructor and render() function.
10
+ * @type {Map<HTMLElement, any[]>} */
11
+ componentArgs: new Map(),
11
12
 
12
13
  /**
13
14
  * Store which instances of Solarite have already been added to the DOM.
@@ -22,6 +23,9 @@ function reset() {
22
23
 
23
24
  div: document.createElement("div"),
24
25
 
26
+ /** @type {HTMLDocument} */
27
+ doc: document,
28
+
25
29
  /**
26
30
  * @type {Record<string, Class<Node>>} A map from built-in tag names to the constructors that create them. */
27
31
  elementClasses: {},
@@ -40,20 +44,20 @@ function reset() {
40
44
  nodeGroups: new WeakMap(),
41
45
 
42
46
  /**
43
- * Used by r() path 9. */
47
+ * Used by h() path 9. */
44
48
  objToEl: new WeakMap(),
45
49
 
46
50
  //pendingChildren: [],
47
51
 
48
52
 
49
53
  /**
50
- * Elements that have been rendered to by r() at least once.
54
+ * Elements that have been rendered to by h() at least once.
51
55
  * This is used by the Solarite class to know when to call onFirstConnect()
52
56
  * @type {WeakSet<HTMLElement>} */
53
57
  rendered: new WeakSet(),
54
58
 
55
59
  /**
56
- * Elements that are currently rendering via the r() function.
60
+ * Elements that are currently rendering via the h() function.
57
61
  * @type {WeakSet<HTMLElement>} */
58
62
  rendering: new WeakSet(),
59
63