solarite 0.3.0 → 0.3.2

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.
Files changed (34) hide show
  1. package/dist/Solarite-debug.js +411 -524
  2. package/dist/Solarite.js +394 -507
  3. package/dist/Solarite.min.js +2 -2
  4. package/package.json +5 -6
  5. package/readme.md +2 -2
  6. package/src/{solarite/ExprPath.js → ExprPath.js} +43 -58
  7. package/src/{solarite/Globals.js → Globals.js} +4 -4
  8. package/src/{util/MultiValueMap.js → MultiValueMap.js} +1 -32
  9. package/src/{solarite/NodeGroup.js → NodeGroup.js} +30 -26
  10. package/src/{solarite/Shell.js → Shell.js} +8 -7
  11. package/src/Solarite.d.ts +62 -0
  12. package/src/{solarite/Solarite.js → Solarite.js} +13 -15
  13. package/src/{solarite/Template.js → Template.js} +1 -1
  14. package/src/{solarite/Util.js → Util.js} +49 -45
  15. package/src/{solarite/createSolarite.js → createSolarite.js} +12 -10
  16. package/src/{solarite/getArg.js → getArg.js} +24 -3
  17. package/src/{solarite/h.js → h.js} +4 -12
  18. package/src/unused/FastLookupArray.js +54 -0
  19. package/src/unused/Hashes.js +339 -0
  20. package/src/unused/InUse.test.js +92 -0
  21. package/src/unused/InUseMap.js +98 -0
  22. package/src/unused/LinkedList.js +117 -0
  23. package/src/unused/LinkedList.test.js +115 -0
  24. package/src/unused/Misc.js +13 -0
  25. package/src/unused/Perf.js +47 -0
  26. package/src/unused/TrackedArray.js +54 -0
  27. package/src/unused/WeakArray.js +33 -0
  28. package/src/{solarite/watch.js → watch.js} +4 -4
  29. package/src/util/Util.js +0 -101
  30. /package/src/{solarite/HtmlParser.js → HtmlParser.js} +0 -0
  31. /package/src/{util/Errors.js → assert.js} +0 -0
  32. /package/src/{util/delve.js → delve.js} +0 -0
  33. /package/src/{solarite/hash.js → hash.js} +0 -0
  34. /package/src/{solarite/udomdiff.js → udomdiff.js} +0 -0
@@ -1,4 +1,4 @@
1
- // Version 2025.7.15.1920
1
+ // Version 2025.7.28.0000
2
2
  // License: MIT
3
3
  // http://vorticode.github.io/solarite
4
- var Util$1={t(...t){var e=!1;let l=async(...t)=>{let s=[];if(!e)for(let e=0;l.length>e;e++)s.push(l[e](...t));return await Promise.all(s)};l[Symbol.iterator]=()=>{let t=0;return{next(){return l.length>t?{value:l[t++],done:!1}:{done:!0}}}};for(let t of Object.getOwnPropertyNames(Array.prototype))"length"!==t&&"constructor"!==t&&(l[t]=Array.prototype[t]);l.l=0,Object.defineProperty(l,"length",{get:()=>l.l,set(t){l.l=t}}),l.remove=t=>{let e=l.findIndex((e=>e===t));-1!==e&&l.splice(e,1)},l.pause=()=>e=!0,l.resume=()=>e=!1;for(let e of t)l.push(e);return l},i(t,e,l){let s=t.get(e);s?s.push(l):(s=[l],t.set(e,s))}},Globals;function reset(){Globals={o:new WeakMap,connected:new WeakSet,h:null,div:document.createElement("div"),u:{},p:{},m:new WeakMap,v:new WeakMap,$:new WeakMap,P:new WeakSet,N:new WeakSet,T: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={G(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)}},A(t,e){let l=e.getAttribute("data-style");l||(e.constructor.S||(e.constructor.S=1),l=e.constructor.S++,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)}},O: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(),H:t=>t.replace(/-([a-z])/g,(t=>t[1].toUpperCase())),*C(t){if(Array.isArray(t))for(const e of t)yield*Util.C(e);else if("function"==typeof t){const e=t();yield*Util.C(e)}else yield t},k: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,U(t,e){let l=t.tagName+"."+e,s=Globals$1.p[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.p[l]=s=!!i&&!!Object.getOwnPropertyDescriptor(i,e)?.set}return s},M: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)),j:t=>void 0===t||!1===t||null===t,I:t=>"string"==typeof t||"number"==typeof t,R:t=>"function"==typeof t?Util.R(t()):t instanceof Date?t.toISOString().replace(/T/," "):Array.isArray(t)||"object"==typeof t?"":t,F(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}},isEvent=t=>t.startsWith("on")&&t in Globals$1.div;function arraySame(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}function defineClass(t,e,l){if(!customElements[getName](t)){(e=e||Util.O(t.name)).includes("-")||(e+="-element");let s=null;l&&(s={V:l}),customElements[define](e,t,s)}}function createSolarite(t=null){let e=HTMLElement;t&&!t.includes("-")&&(t=t.toLowerCase(),e=Globals$1.u[t],e||(e=document.createElement(t).constructor,Globals$1.u[t]=e));let l=new Proxy(e,{construct:(e,l,s)=>(defineClass(s,null,t),Reflect.construct(e,l,s))});return class extends l{J=Util$1.t();L=Util$1.t();W=Util$1.t();constructor(t={}){super(),!0===t.D?this.D():!1===t.D&&Globals$1.P.add(this)}_(){!Globals$1.P.has(this)&&this.D&&this.D()}B(){this._(),Globals$1.connected.has(this)||(Globals$1.connected.add(this),this.L()),this.J()}K(){this.W()}static define(e=null){defineClass(this,e,t)}}}let define="define",getName="getName",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}))}class MultiValueMap{data={};add(t,e){let l=this.data,s=l[t];s||(s=new Set,l[t]=s),s.add(e)}Z(){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}q(t){let e,l=this.data,s=l[t];if(s)return[e]=s,s.delete(e),0===s.size&&delete l[t],e}X(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}Y(t,e){let l,s=this.data,i=s[t];if(i){for(let t of i)if(t?.parentNode===e){i.delete(t),l=t;break}return l||([l]=i,i.delete(l)),0===i.size&&delete s[t],l}}tt(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;et;lt;st;it;rt;v=[];ot;nt;ht;ft;ut;ct=void 0;constructor(t,e,l=ExprPathType.dt,s=null,i=null){this.st=t,this.it=e,this.type=l,this.attrName=s,this.et=i,l===ExprPathType.bt&&(this.lt=new Set)}apply(t,e=!0){switch(this.type){case 1:this.yt(t[0],e);break;case 2:this.gt(this.it,t[0]);break;case 5:break;case 6:this.vt(this.it,t[0],this.rt.$t.root);break;default:this.Et(this.it,t)}}yt(t,e=!0){let l=this;e&&l.Pt();let s=[],i=l.v,r=[];l.v=[],l.Nt(t,s,r);let o=!1;if(r.length){for(let[t,e]of r){let i=l.Tt(s[t],!1),r=i.Gt();1===r.length?s[t]=r[0]:(s[t]=r,o=!0),l.v[e]=i}o&&(s=s.flat())}let a=l.Gt();if(!arraySame(a,s)){l.ot=s,this.rt.wt&&this.rt.wt.xt(),a.length&&!s.length&&l.At()||udomdiff(l.it.parentNode,a,s,l.it);for(let t of i)t.St.parentNode||t.Ot()}}Ht(t){let e=Math.min(t.Ct,t.items.length),l=t.Ct-e;for(let l=0;e>l;l++){let e=this.v[t.index+l],s=(this.ut||this.ft)(t.items[l]);this.kt(s,(s=>{let i=this.Tt(s,!0);if(i&&i===e);else{i||(i=this.Tt(s,!1)),this.v[t.index+l]=i;let r=e.St;for(let t of i.Gt())r.parentNode.insertBefore(t,r);i!==e&&e.Ot()}}))}if(l>0){for(let s=0;l>s;s++)this.v[t.index+e+s].Ot();this.v.splice(t.index+e,l)}else{let l=t.items.slice(e),s=this.v[t.index+e]?.St||this.it;for(let t=0;l.length>t;t++){let e=this.ut(l[t]),i=this.Tt(e,!0);i||(i=this.Tt(e,!1)),this.v.push(i);for(let t of i.Gt())s.parentNode.insertBefore(t,s)}}this.ot=null}kt(t,e){if(Array.isArray(t))for(let l of t)this.kt(l,e);else if("function"==typeof t)Globals$1.h=this,this.ft=t,t=t(),Globals$1.h=null,this.kt(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.kt(l,e)}}Nt(t,e,l){if(t instanceof Template){let s=this.Tt(t,!0);s?(e.push(...s.Gt()),this.v.push(s)):(l.push([e.length,this.v.length]),e.push(t),this.v.push(null))}else t instanceof Node?t instanceof DocumentFragment?e.push(...t.childNodes):e.push(t):this.kt(t,(t=>{this.Nt(t,e,l)}))}gt(t,e){Array.isArray(e)&&(e=e.flat().join(" "));let l=this.lt;if(this.lt=new Set,e){"function"==typeof e&&(Globals$1.h=this,this.ft=e,e=e(),Globals$1.h=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.lt.add(l)}}for(let e of l)this.lt.has(e)||t.removeAttribute(e)}vt(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.Ut(t,l,i,i,s,r)}Ut(t,e,l,s,i,r,o=!1){let a=Globals$1.m.get(t);a||(a={[l]:[,,,]},Globals$1.m.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}Et(t,e){let l=e[0];if(Util.M(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.j(i)?"":i;e!==t[this.attrName]&&(t[this.attrName]=e)}let r=()=>{let l="value"===this.attrName?Util.k(t):t[this.attrName];delve(e,s,l)};this.Ut(t,s[0],this.attrName,"input",r,[],!0)}else{let s=this.ct;void 0===s&&(s=this.ct=Util.U(t,this.attrName));let i=this.et;if(!i){if(Globals$1.h=this,"function"==typeof l){if(4===this.type)return;this.ft=l,l=l()}else l=Util.R(l);Globals$1.h=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.et.length>l;l++)if(t.push(this.et[l]),this.et.length-1>l){Globals$1.h=this;let s=Util.R(e[l]);Globals$1.h=null,Util.j(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.ht.slice(0,-e):this.ht;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.st&&(s=o[this.nt]),new ExprPath(s,l,this.type,this.attrName,this.et)}xt(){let t=this,e=this.it.parentNode;for(;t&&t.it.parentNode===e;)t.ot=null,t=t.rt?.wt}At(){let t=this.st.parentNode;return this.st===t.firstChild&&this.it===t.lastChild&&(t.innerHTML="",t.append(this.st,this.it),!0)}Gt(){if(this.type===ExprPathType.Mt||this.type===ExprPathType.bt||this.type===ExprPathType.jt)return[this.it];let t;if(t=this.ot,t)return t;t=[];let e=this.st.nextSibling,l=this.it;for(;e&&e!==l;)t.push(e),e=e.nextSibling;return this.ot=t,t}It(){return this.it.parentNode}Tt(t,e=!0){let l,s=this.Rt;if(e){if(l=s.q(t.Ft()),l||(s=this.Vt,l=s.q(t.Ft())),!l)return null;s.X(t.Jt(),l)}else t.Lt.length&&(l=s.q(t.Jt()),l||(s=this.Vt,l=s.q(t.Jt())),l&&(s.X(l.Wt,l),l.zt(t.Lt),l.Wt=t.Ft()));return l||(l=new NodeGroup(t,this)),this.Dt.push(l),l}_t(){return this.type===ExprPathType.jt||this.attrName&&this.it.tagName&&this.it.tagName.includes("-")}Dt=[];Rt=new MultiValueMap;Vt=new MultiValueMap;Pt(){let t=this.Rt.data,e=this.Vt.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.Rt=new MultiValueMap;let l=this.Rt;for(let t of this.Dt)l.add(t.Wt,t),l.add(t.Bt,t);this.Dt=[]}}const ExprPathType={dt:1,bt:2,Mt:3,jt: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.Kt={context:HtmlParser.Text,quote:null,buffer:"",Zt:null},this.state={...this.Kt}}reset(){return this.state={...this.Kt},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.qt),this.state.context=HtmlParser.qt,this.state.buffer="");break;case HtmlParser.qt: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.Xt),this.state.context=HtmlParser.Xt,this.state.quote="="===s?null:s,this.state.buffer=""):this.state.buffer+=s}break;case HtmlParser.Xt: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.qt),this.state.context=HtmlParser.qt,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.Xt="Attribute",HtmlParser.Text="Text",HtmlParser.qt="Tag";class Shell{fragment;Yt=[];Qt=[];scripts=[];te=[];ee=[];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.le(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.Yt.push(new ExprPath(null,e,ExprPathType.bt)),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=isEvent(t.name)?ExprPathType.Event:ExprPathType.Mt;this.Yt.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.Yt.length),e.parentNode.insertBefore(l,e)),!e.nextSibling||8===e.nextSibling.nodeType&&"!✨!"===e.nextSibling.textContent?(t=e,t.textContent="ExprPathEnd:"+this.Yt.length):(t=e.nextSibling,i.push(e));let s=new ExprPath(l,t,ExprPathType.dt);this.Yt.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.Yt.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.dt);this.Yt.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.Yt)t.st&&(t.nt=[].indexOf.call(t.st.parentNode.childNodes,t.st)),t.ht=getNodePath(t.it),t.type===ExprPathType.Mt&&1===t.it.nodeType&&(t.it.tagName.includes("-")||t.it.hasAttribute("is"))&&(t.type=ExprPathType.jt);this.se()}static le(t){let e=[];function l(t,l){l===HtmlParser.qt&&(t=t.replace(/^<\/?[a-z][a-z0-9]*-[a-z0-9-]+/i,(t=>t+"-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("")}se(){this.scripts=[].map.call(this.fragment.querySelectorAll("scripts"),(t=>getNodePath(t))),this.te=[].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.Qt=[].map.call(t,(t=>getNodePath(t)));for(let t of this.fragment.querySelectorAll("*"))(t.tagName.includes("-")||t.hasAttribute("_is"))&&(this.Yt.find((e=>e.it===t))||this.ee.push(getNodePath(t)))}static get(t){let e=Globals$1.T.get(t);return e||(e=new Shell(t),Globals$1.T.set(t,e)),e}}const commentPlaceholder="\x3c!--!✨!--\x3e",attribPlaceholder=57344;class NodeGroup{$t;wt;St;ie;Yt=[];Wt;Bt;ot;te;constructor(t,e=null){if(!(this instanceof RootNodeGroup)){let[l,s]=this.init(t,e);if(l&&t.Lt.length){this.re(l,s.Yt);let e=this.oe(l,s);this.ae(l,s),this.zt(t.Lt),this.ne(e)}else s&&this.ae(l,s)}}init(t,e=null,l=null,s=null){if(this.Wt=l||t.Ft(),this.Bt=s||t.Jt(),this.wt=e,this.$t=e?.rt?.$t||this,this.he=t,t.fe=this,this instanceof RootNodeGroup||t.Lt.length||t.ue[0].includes("<")){let e=Shell.get(t.ue),l=e.fragment.cloneNode(!0);if(l instanceof DocumentFragment){let t=l.childNodes;this.St=t[0],this.ie=t[t.length-1]}else this.St=this.ie=l;return[l,e]}{let e=document.createTextNode(t.ue[0]);return this.St=this.ie=e,[]}}zt(t,e=null){let l,s=t.length-1,i=Array((e=e||this.Yt).length);for(let r,o=e.length-1;r=e[o];o--){let a=e[o-1],n=e[o+1];if(r.et?.length>2?(i[o]=t.slice(s-(r.et.length-1)+1,s+1),s-=i[o].length):(i[o]=[t[s]],s--),r.it!==this.$t.root&&r._t()){if(n&&n._t()&&n.it===r.it||(l=o),!a||!a._t()||a.it!==r.it){let t={};for(let s=o;l>=s;s++)t[e[s].attrName]=i[s].length>1?i[s].join(""):i[s][0];this.ce(r.it,t);for(let t=o;l>=t;t++)e[t].apply(i[t])}}else r.apply(i[o])}this.de(),this.ot=null}ce(t,e){let l=getObjectHash(e),s=t.tagName.endsWith("-SOLARITE-PLACEHOLDER"),i=t.hasAttribute("_is");if(s||i)t=this.pe(t,s,e);else if(t.D&&Globals$1.o.get(t)!==l){let l={};for(let t in e||{})l[Util.H(t)]=e[t];t.D(l)}Globals$1.o.set(t,l)}pe(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.H(t)]=l[t];if(t.attributes.length)for(let e of t.attributes){let t=Util.H(e.name);r.hasOwnProperty(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.Yt)e.it===t&&(e.it=o),e.st===t&&(e.st=o);this.St===t&&(this.St=o),this.ie===t&&(this.ie=o),o._&&o._();for(let e of t.attributes)"_is"!==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}Gt(){let t=this.ot;if(t)return t;t=[];let e=this.St,l=this.ie?.nextSibling;for(;e&&e!==l;)t.push(e),e=e.nextSibling;return this.ot=t,t}It(){return this.St?.parentNode}getRootNode(){return this.$t.root}me(){return this.$t}Ot(){let t=document.createDocumentFragment();for(let e of this.Gt())t.append(e)}re(t,e,l){let s=e.length;this.Yt.length=s;for(let i=0;s>i;i++){let s=e[i].clone(t,l);s.rt=this,this.Yt[i]=s}}de(){if(this.te)for(let[t,e]of this.te)e!==t.textContent&&Util.A(t,this.me().root)}oe(t,e,l=0){let s=[];for(let i of e.ee){l&&(i=i.slice(0,-l));let e=resolveNodePath(t,i);t!==e&&s.push(e)}return s}ne(t){for(let e of t)this.pe(e)}ae(root,shell,pathOffset=0){let rootEl=this.$t.root;if(rootEl){let options=this.$t.options;if(!1!==options?.Qt)for(let t of shell.Qt){pathOffset&&(t=t.slice(0,-pathOffset));let e=resolveNodePath(root,t);Util.G(rootEl,e)}if(!1!==options?.te){shell.te.length&&(this.te=new Map);for(let t of shell.te){pathOffset&&(t=t.slice(0,-pathOffset));let e=resolveNodePath(root,t);1===rootEl.nodeType&&(Util.A(e,rootEl),this.te.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;be=new Map;constructor(t,e,l){super(t),this.options=l,this.$t=this;let[s,i]=this.init(t);if(s instanceof Text)e&&(this.St=e,this.ie=e,s.nodeValue.length&&e.append(s),this.root=e),Globals$1.v.set(this.root,this);else{let l=0,r=s;if(e){let t;if(Globals$1.v.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)||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.St=e,this.ie=e}else{let t=getSingleEl(s);this.root=t||s,Globals$1.v.set(this.root,this),t&&(r=t,l=1)}this.re(r,i.Yt,l);let o=this.oe(r,i,l);this.ae(r,i,l),this.zt(t.Lt),this.ne(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{Lt=[];ue=[];ye;fe;constructor(t,e){this.ue=t,this.Lt=e}toJSON(){return this.ye||(this.ye=[getObjectId(this.ue),this.Lt]),this.ye}D(t=null,e={}){let l,s=!1;if(t){if(l=Globals$1.v.get(t),l||(l=new RootNodeGroup(this,t,e),Globals$1.v.set(t,l),s=!0),0===l.Yt.length&&this.Lt.length||l.Yt.length>this.Lt.length)throw Error(`Solarite Error: Parent HTMLElement ${l.he.ue.join("${...}")} and ${l.Yt.length} \${value} placeholders can't accomodate a Template with ${this.Lt.length} values.`)}else l=new RootNodeGroup(this,null,e),t=l.getRootNode(),Globals$1.v.set(t,l),s=!0;return s||(1!==this.ue?.length||this.ue[0]?l.zt(this.Lt):t.innerHTML=""),l.be=new Map,t}Ft(){return this.Wt||(this.Wt=this.Lt.length?getObjectHash(this):this.ue[0]),this.Wt}Jt(){return this.Bt||(this.Bt=this.Lt.length?this.toJSON()[0]:this.ue[0]),this.Bt}}function h(t=void 0,...e){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.F(l.content.childNodes);return 1===s.length?s[0]:l.content}if(void 0===t)return(t,...e)=>h(t,...e).D();if(t instanceof Template)return t.D();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.$.has(e))return((...t)=>{let l=h(...t).D();Globals$1.$.set(e,l)}).bind(e);{Globals$1.$.set(e,null),e[renderF]();let t=Globals$1.$.get(e);Globals$1.$.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.P.add(l),new Template(e,s).D(l,t));return s}if(!(e[0]instanceof Template))throw Error("unsupported");s.D(l,e[1]),!l.childNodes.length&&this&&l.append(this.$t.It())}}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.O(attributeName)),result;if(null!==attrVal&&(val=attrVal),Array.isArray(type))return type.includes(val)?val:fallback;if("function"==typeof type)return type(val);if(type===ArgType.ge){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.ve:return result=parseInt(val),isNaN(result)?fallback:result;case ArgType.$e:return result=parseFloat(val),isNaN(result)?fallback:result;case ArgType.String:return[void 0,null,!1].includes(val)?"":val+"";case ArgType.Ee:case ArgType.Pe:if("string"!=typeof val||!val.length)return val;try{return type===ArgType.Ee?JSON.parse(val):eval(`(${val})`)}catch(t){return val}default:return val}}var ArgType={ge:"Bool",ve:"Int",$e:"Float",String:"String",JSON:"Json",Ee:"Json",Pe:"Eval"};let Solarite=new Proxy(createSolarite(),{apply:(t,e,l)=>createSolarite(...l)}),getInputValue=Util.k;export default h;export{ArgType,Globals$1 as Globals,Solarite,Util as SolariteUtil,Template,delve,getArg,getInputValue,h,h as r};
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)if("function"==typeof e&&(Globals$1.l=this,this.X=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.W.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.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};
package/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "solarite",
3
- "version": "0.3.0",
4
- "description": "Solarite is a small, fast, compilation-free JavaScript web component library that closely follows modern web standards.",
3
+ "version": "0.3.2",
4
+ "description": "Solarite is a small (8KB 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",
8
8
  "dist",
9
- "src/solarite",
10
- "src/util"
9
+ "src"
11
10
  ],
12
11
  "scripts": {
13
12
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -18,12 +17,12 @@
18
17
  },
19
18
  "keywords": [
20
19
  "JavaScript",
21
- "UI",
22
20
  "framework",
23
21
  "library",
24
22
  "reactive",
25
- "vanilla",
26
23
  "minimal",
24
+ "UI",
25
+ "vanilla",
27
26
  "web component"
28
27
  ],
29
28
  "author": "Eric P",
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 web component library for rendering minimal updates. It follows modern web standards and is easy to use with vanilla JavaScript.
3
+ Solarite is a small, fast, compilation-free JavaScript library for adding reactivity to native web components, so that updates require minimal re-rendering. 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) (109KB, 8.6KB min+gzip)
8
8
 
9
9
  Or:
10
10
 
@@ -1,10 +1,10 @@
1
- import {assert} from "../util/Errors.js";
2
- import delve from "../util/delve.js";
1
+ import {assert} from "./assert.js";
2
+ import delve from "./delve.js";
3
3
  import NodeGroup from "./NodeGroup.js";
4
- import Util, {arraySame, setIndent} from "./Util.js";
4
+ import Util, {setIndent} from "./Util.js";
5
5
  import Template from "./Template.js";
6
6
  import Globals from "./Globals.js";
7
- import MultiValueMap from "../util/MultiValueMap.js";
7
+ import MultiValueMap from "./MultiValueMap.js";
8
8
  import udomdiff from "./udomdiff.js";
9
9
  //import {ArraySpliceOp} from "./watch.js";
10
10
  //#IFDEV
@@ -205,7 +205,7 @@ export default class ExprPath {
205
205
 
206
206
 
207
207
  // This pre-check makes it a few percent faster?
208
- let same = arraySame(oldNodes, newNodes);
208
+ let same = Util.arraySame(oldNodes, newNodes);
209
209
  if (!same) {
210
210
 
211
211
  path.nodesCache = newNodes; // Replaces value set by path.getNodes()
@@ -227,6 +227,17 @@ export default class ExprPath {
227
227
  for (let ng of oldNodeGroups)
228
228
  if (!ng.startNode.parentNode)
229
229
  ng.removeAndSaveOrphans();
230
+
231
+ // Instantiate components created within ${...} expressions.
232
+ // Embedded style tags are handled elsewhere, but where?
233
+ for (let el of newNodes) {
234
+ if (el instanceof HTMLElement) {
235
+ if (el.hasAttribute('solarite-placeholder'))
236
+ this.parentNg.instantiateComponent(el);
237
+ for (let child of el.querySelectorAll('[solarite-placeholder]'))
238
+ this.parentNg.instantiateComponent(child);
239
+ }
240
+ }
230
241
  }
231
242
 
232
243
 
@@ -406,50 +417,10 @@ export default class ExprPath {
406
417
  // Arrays and functions.
407
418
  // I tried iterating over the result of a generator function to avoid this recursion and simplify the code,
408
419
  // but that consistently made the js-framework-benchmarks a few percentage points slower.
409
- else {
420
+ else
410
421
  this.exprToTemplates(expr, template => {
411
422
  this.applyExactNodes(template, newNodes, secondPass);
412
423
  })
413
-
414
- }
415
-
416
- // Old version
417
- /*else if (Array.isArray(expr))
418
- for (let subExpr of expr)
419
- this.applyExactNodes(subExpr, newNodes, secondPass);
420
-
421
- else if (typeof expr === 'function') {
422
- // TODO: One ExprPath can have multiple expr functions.
423
- // But if using it as a watch, it should only have one at the top level.
424
- // So maybe this is ok.
425
- Globals.currentExprPath = this; // Used by watch()
426
-
427
- this.watchFunction = expr; // TODO: Only do this if it's a top level function.
428
- let result = expr(); // As expr accesses watched variables, watch() uses Globals.currentExprPath to mark where those watched variables are being used.
429
- Globals.currentExprPath = null;
430
-
431
- this.applyExactNodes(result, newNodes, secondPass);
432
- }
433
-
434
- // String
435
- else {
436
- // Convert expression to a string.
437
- let stringExpr = expr;
438
- if (expr === undefined || expr === false || expr === null) // Util.isFalsy()
439
- stringExpr = '';
440
- else if (typeof expr !== 'string')
441
- stringExpr = expr + '';
442
-
443
- // Get the same Template for the same string each time.
444
- let template = Globals.stringTemplates[stringExpr];
445
- if (!template) {
446
- template = new Template([stringExpr], []);
447
- Globals.stringTemplates[stringExpr] = template;
448
- }
449
-
450
- // Recurse.
451
- this.applyExactNodes(template, newNodes, secondPass);
452
- }*/
453
424
  }
454
425
 
455
426
  applyMultipleAttribs(node, expr) {
@@ -469,16 +440,30 @@ export default class ExprPath {
469
440
  Globals.currentExprPath = null;
470
441
  }
471
442
 
472
- let attrs = (expr +'') // Split string into multiple attributes.
473
- .split(/([\w-]+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s]+))/g)
474
- .map(text => text.trim())
475
- .filter(text => text.length);
443
+ // Attribute as name: value object.
444
+ if (typeof expr === 'object') {
445
+ for (let name in expr) {
446
+ let value = expr[name];
447
+ if (value === undefined || value === false || value === null)
448
+ continue;
449
+ node.setAttribute(name, value);
450
+ this.attrNames.add(name)
451
+ }
452
+ }
476
453
 
477
- for (let attr of attrs) {
478
- let [name, value] = attr.split(/\s*=\s*/); // split on first equals.
479
- value = (value || '').replace(/^(['"])(.*)\1$/, '$2'); // trim value quotes if they match.
480
- node.setAttribute(name, value);
481
- this.attrNames.add(name)
454
+ // Attributes as string
455
+ else {
456
+ let attrs = (expr + '') // Split string into multiple attributes.
457
+ .split(/([\w-]+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s]+))/g)
458
+ .map(text => text.trim())
459
+ .filter(text => text.length);
460
+
461
+ for (let attr of attrs) {
462
+ let [name, value] = attr.split(/\s*=\s*/); // split on first equals.
463
+ value = (value || '').replace(/^(['"])(.*)\1$/, '$2'); // trim value quotes if they match.
464
+ node.setAttribute(name, value);
465
+ this.attrNames.add(name)
466
+ }
482
467
  }
483
468
  }
484
469
 
@@ -592,7 +577,7 @@ export default class ExprPath {
592
577
  // Copies the attribute to the property when the input event fires.
593
578
  // value=${[this, 'value]'}
594
579
  // checked=${[this, 'isAgree']}
595
- // This same logic is in NodeGroup.createNewComponent() for components.
580
+ // This same logic is in NodeGroup.instantiateComponent() for components.
596
581
  if (Util.isPath(expr)) {
597
582
  let [obj, path] = [expr[0], expr.slice(1)];
598
583
 
@@ -1055,9 +1040,9 @@ export default class ExprPath {
1055
1040
  current = current.nextSibling
1056
1041
  }
1057
1042
 
1058
- if (!arraySame(this.nodesCache, nodes))
1043
+ if (!Util.arraySame(this.nodesCache, nodes))
1059
1044
  console.log(this.nodesCache, nodes)
1060
- assert(arraySame(this.nodesCache, nodes) === true);
1045
+ assert(Util.arraySame(this.nodesCache, nodes) === true);
1061
1046
  }
1062
1047
  }
1063
1048
  //#ENDIF
@@ -23,15 +23,15 @@ function reset() {
23
23
  div: document.createElement("div"),
24
24
 
25
25
  /**
26
- * @type {Object<string, Class<Node>>} A map from built-in tag names to the constructors that create them. */
26
+ * @type {Record<string, Class<Node>>} A map from built-in tag names to the constructors that create them. */
27
27
  elementClasses: {},
28
28
 
29
- /** @type {Object<string, boolean>} Key is tag-name.propName. Value is whether it's an attribute.*/
29
+ /** @type {Record<string, boolean>} Key is tag-name.propName. Value is whether it's an attribute.*/
30
30
  htmlProps: {},
31
31
 
32
32
  /**
33
33
  * Used by ExprPath.applyEventAttrib()
34
- * @type {WeakMap<Node, Object<eventName:string, [original:function, bound:function, args:*[]]>>} */
34
+ * @type {WeakMap<Node, Record<eventName:string, [original:function, bound:function, args:*[]]>>} */
35
35
  nodeEvents: new WeakMap(),
36
36
 
37
37
  /**
@@ -66,7 +66,7 @@ function reset() {
66
66
  * A map of individual untagged strings to their Templates.
67
67
  * This way we don't keep creating new Templates for the same string when re-rendering.
68
68
  * This is used by ExprPath.applyExactNodes()
69
- * @type {Object<string, Template>} */
69
+ * @type {Record<string, Template>} */
70
70
  //stringTemplates: {},
71
71
 
72
72
  reset,
@@ -1,6 +1,6 @@
1
1
  export default class MultiValueMap {
2
2
 
3
- /** @type {Object<string, Set>} */
3
+ /** @type {Record<string, Set>} */
4
4
  data = {};
5
5
 
6
6
  // Set a new value for a key
@@ -94,37 +94,6 @@ export default class MultiValueMap {
94
94
  return result;
95
95
  }
96
96
 
97
-
98
- /**
99
- * Try to delete an item that matches the key and the isPreferred function.
100
- * if not the latter, just delete any item that matches the key.
101
- * @param key {string}
102
- * @returns {*|undefined} The deleted item. */
103
- deletePreferred(key, parent) {
104
- let result;
105
- let data = this.data;
106
- let set = data[key];
107
- if (!set)
108
- return undefined;
109
-
110
- for (let val of set) {
111
- if (val?.parentNode === parent) {
112
- set.delete(val);
113
- result = val;
114
- break;
115
- }
116
- }
117
- if (!result) {
118
- [result] = set;
119
- set.delete(result);
120
- }
121
-
122
- if (set.size === 0)
123
- delete data[key];
124
-
125
- return result;
126
- }
127
-
128
97
  hasValue(val) {
129
98
  let data = this.data;
130
99
  let names = [];
@@ -1,10 +1,10 @@
1
- import {assert} from "../util/Errors.js";
1
+ import {assert} from "./assert.js";
2
2
  import ExprPath, {ExprPathType, resolveNodePath} from "./ExprPath.js";
3
3
  import {getObjectHash} from "./hash.js";
4
4
  import Shell from "./Shell.js";
5
5
  import Util, {flattenAndIndent, nodeToArrayTree, setIndent} from "./Util.js";
6
6
  //import NodeGroupManager from "./NodeGroupManager.js";
7
- import delve from "../util/delve.js";
7
+ import delve from "./delve.js";
8
8
  import Globals from "./Globals.js";
9
9
 
10
10
  /** @typedef {boolean|string|number|function|Object|Array|Date|Node|Template} Expr */
@@ -78,7 +78,7 @@ export default class NodeGroup {
78
78
  // Apply exprs
79
79
  this.applyExprs(template.exprs);
80
80
 
81
- this.activateStaticComponents(staticComponents);
81
+ this.instantiateStaticComponents(staticComponents);
82
82
  }
83
83
  else if (shell)
84
84
  this.activateEmbeds(fragment, shell);
@@ -172,7 +172,7 @@ export default class NodeGroup {
172
172
  // Think of having two adjacent components.
173
173
  // But the dynamicAttribsAdjacet test already passes.
174
174
 
175
- // If a component:
175
+ // If expr is an attribute in a component:
176
176
  // 1. Instantiate it if it hasn't already been, sending all expr's to its constructor.
177
177
  // 2. Otherwise send them to its render function.
178
178
  // Components with no expressions as attributes are instead activated in activateEmbeds().
@@ -209,6 +209,8 @@ export default class NodeGroup {
209
209
  // TODO: Only do this if we have ExprPaths within styles?
210
210
  this.updateStyles();
211
211
 
212
+
213
+
212
214
  // Invalidate the nodes cache because we just changed it.
213
215
  this.nodesCache = null;
214
216
 
@@ -233,23 +235,25 @@ export default class NodeGroup {
233
235
  // then we could re-use the hash and logic from NodeManager?
234
236
  let newHash = getObjectHash(props);
235
237
 
236
- let isPreHtmlElement = el.tagName.endsWith('-SOLARITE-PLACEHOLDER');
238
+ let isPreHtmlElement = el.hasAttribute('solarite-placeholder');
237
239
  let isPreIsElement = el.hasAttribute('_is')
238
240
 
239
241
 
240
242
  // Instantiate a placeholder.
241
243
  if (isPreHtmlElement || isPreIsElement)
242
- el = this.createNewComponent(el, isPreHtmlElement, props);
244
+ el = this.instantiateComponent(el, isPreHtmlElement, props);
243
245
 
244
246
  // Call render() with the same params that would've been passed to the constructor.
247
+ // We do this even if the arguments haven't changed, so we can let the child component
248
+ // compare the arguments and then decide for itself whether it wants to re-render.
245
249
  else if (el.render) {
246
- let oldHash = Globals.componentArgsHash.get(el);
247
- if (oldHash !== newHash) {
250
+ //let oldHash = Globals.componentArgsHash.get(el);
251
+ //if (oldHash !== newHash) { // Only if not changed.
248
252
  let args = {};
249
253
  for (let name in props || {})
250
254
  args[Util.dashesToCamel(name)] = props[name];
251
255
  el.render(args); // Pass new values of props to render so it can decide how it wants to respond.
252
- }
256
+ //}
253
257
  }
254
258
 
255
259
  Globals.componentArgsHash.set(el, newHash);
@@ -262,10 +266,10 @@ export default class NodeGroup {
262
266
  * The logic of this function is complex and could use cleaning up.
263
267
  *
264
268
  * @param el
265
- * @param isPreHtmlElement
269
+ * @param isPreHtmlElement {?boolean} True if the element's tag name ends with -solarite-placeholder
266
270
  * @param props {Object} Attributes with dynamic values.
267
271
  * @return {HTMLElement} */
268
- createNewComponent(el, isPreHtmlElement=undefined, props=undefined) {
272
+ instantiateComponent(el, isPreHtmlElement=undefined, props=undefined) {
269
273
  if (isPreHtmlElement === undefined)
270
274
  isPreHtmlElement = !el.hasAttribute('_is');
271
275
 
@@ -279,24 +283,24 @@ export default class NodeGroup {
279
283
  if (!Constructor)
280
284
  throw new Error(`The custom tag name ${tagName} is not registered.`)
281
285
 
282
- let args = {};
286
+ let attribs = {};
283
287
  for (let name in props || {})
284
- args[Util.dashesToCamel(name)] = props[name];
288
+ attribs[Util.dashesToCamel(name)] = props[name];
285
289
 
286
290
  // Pass other attribs to constructor, since otherwise they're not yet set on the element,
287
291
  // and the constructor would otherwise have no way to see them.
288
292
  if (el.attributes.length) {
289
293
  for (let attrib of el.attributes) {
290
294
  let attribName = Util.dashesToCamel(attrib.name);
291
- if (!args.hasOwnProperty(attribName))
292
- args[attribName] = attrib.value;
295
+ if (!attribs.hasOwnProperty(attribName) && attribName !== 'solarite-placeholder')
296
+ attribs[attribName] = attrib.value;
293
297
  }
294
298
  }
295
299
 
296
300
  // Create the web component.
297
301
  // Get the children that aren't Solarite's comment placeholders.
298
- let ch = [...el.childNodes].filter(node => node.nodeType !== Node.COMMENT_NODE || !node.nodeValue.startsWith('ExprPath'));
299
- let newEl = new Constructor(args, ch);
302
+ let children = [...el.childNodes].filter(node => node.nodeType !== Node.COMMENT_NODE || !node.nodeValue.startsWith('ExprPath'));
303
+ let newEl = new Constructor(attribs, children);
300
304
 
301
305
  if (!isPreHtmlElement)
302
306
  newEl.setAttribute('is', el.getAttribute('is').toLowerCase());
@@ -330,7 +334,7 @@ export default class NodeGroup {
330
334
 
331
335
  // Copy attributes over.
332
336
  for (let attrib of el.attributes)
333
- if (attrib.name !== '_is')
337
+ if (attrib.name !== '_is' && attrib.name !== 'solarite-placeholder')
334
338
  newEl.setAttribute(attrib.name, attrib.value);
335
339
 
336
340
  // Set dynamic attributes if they are primitive types.
@@ -490,9 +494,9 @@ export default class NodeGroup {
490
494
  let result = [];
491
495
 
492
496
  // static components. These are WebComponents that do not have any constructor arguments that are expressions.
493
- // Those are instead created by applyExpr() which calls applyComponentExprs() which calls createNewcomponent().
497
+ // Those are instead created by applyExpr() which calls applyComponentExprs() which calls instantiateComponent().
494
498
  // Maybe someday these two paths will be merged?
495
- // Must happen before ids because createNewComponent will replace the element.
499
+ // Must happen before ids because instantiateComponent will replace the element.
496
500
  for (let path of shell.staticComponents) {
497
501
  if (pathOffset)
498
502
  path = path.slice(0, -pathOffset);
@@ -506,13 +510,13 @@ export default class NodeGroup {
506
510
  return result;
507
511
  }
508
512
 
509
- activateStaticComponents(staticComponents) {
513
+ instantiateStaticComponents(staticComponents) {
510
514
  for (let el of staticComponents)
511
- this.createNewComponent(el)
515
+ this.instantiateComponent(el)
512
516
  }
513
517
 
514
518
  /**
515
- * @param root {HTMLElement}
519
+ * @param root {HTMLElement|DocumentFragment}
516
520
  * @param shell {Shell}
517
521
  * @param pathOffset {int} */
518
522
  activateEmbeds(root, shell, pathOffset=0) {
@@ -622,7 +626,7 @@ export class RootNodeGroup extends NodeGroup {
622
626
 
623
627
  // Copy attributes
624
628
  for (let attrib of fragment.children[0].attributes)
625
- if (!el.hasAttribute(attrib.name))
629
+ if (!el.hasAttribute(attrib.name) && attrib.name !== 'solarite-placeholder')
626
630
  el.setAttribute(attrib.name, attrib.value);
627
631
 
628
632
  // Go one level deeper into all of shell's paths.
@@ -682,7 +686,7 @@ export class RootNodeGroup extends NodeGroup {
682
686
  // Apply exprs
683
687
  this.applyExprs(template.exprs);
684
688
 
685
- this.activateStaticComponents(staticComponents);
689
+ this.instantiateStaticComponents(staticComponents);
686
690
  }
687
691
  }
688
692
  }
@@ -706,6 +710,6 @@ function getSingleEl(fragment) {
706
710
  * @returns {boolean} */
707
711
  function isReplaceEl(fragment, el) {
708
712
  return fragment.children.length===1
709
- && el.tagName.includes('-')
713
+ && el.tagName.includes('-') // TODO: Check for solarite-placeholder attribute instead?
710
714
  && fragment.children[0].tagName.replace('-SOLARITE-PLACEHOLDER', '') === el.tagName;
711
715
  }
@@ -1,6 +1,6 @@
1
- import {assert} from "../util/Errors.js";
1
+ import {assert} from "./assert.js";
2
2
  import ExprPath, {ExprPathType, getNodePath} from "./ExprPath.js";
3
- import {isEvent} from "./Util.js";
3
+ import Util from "./Util.js";
4
4
  import Globals from "./Globals.js";
5
5
  import HtmlParser from "./HtmlParser.js";
6
6
 
@@ -35,7 +35,7 @@ export default class Shell {
35
35
  /** @type {int[][]} Array of paths. Used by activateEmbeds() to quickly find components. */
36
36
  staticComponents = [];
37
37
 
38
- /** @type {{path:int[], attribs:Object<string, string>}[]} */
38
+ /** @type {{path:int[], attribs:Record<string, string>}[]} */
39
39
  //componentAttribs = [];
40
40
 
41
41
 
@@ -96,7 +96,7 @@ export default class Shell {
96
96
  let parts = attr.value.split(/[\ue000-\uf8ff]/g);
97
97
  if (parts.length > 1) {
98
98
  let nonEmptyParts = (parts.length === 2 && !parts[0].length && !parts[1].length) ? null : parts;
99
- let type = isEvent(attr.name) ? ExprPathType.Event : ExprPathType.AttribValue;
99
+ let type = Util.isEvent(attr.name) ? ExprPathType.Event : ExprPathType.AttribValue;
100
100
 
101
101
  this.paths.push(new ExprPath(null, node, type, attr.name, nonEmptyParts));
102
102
  placeholdersUsed += parts.length - 1;
@@ -224,11 +224,12 @@ export default class Shell {
224
224
  function addToken(token, context) {
225
225
 
226
226
  if (context === HtmlParser.Tag) {
227
- // Find Solarite Components tags and append -solarite-placeholder to their tag names.
227
+ // Find Solarite Components tags and append -solarite-placeholder to their tag names
228
+ // and give them a solarite-placeholder attribute so we can easily find them later.
228
229
  // This way we can gather their constructor arguments and their children before we call their constructor.
229
- // Later, NodeGroup.createNewComponent() will replace them with the real components.
230
+ // Later, NodeGroup.instantiateComponent() will replace them with the real components.
230
231
  // Ctrl+F "solarite-placeholder" in project to find all code that manages subcomponents.
231
- token = token.replace(/^<\/?[a-z][a-z0-9]*-[a-z0-9-]+/i, match => match + '-solarite-placeholder');
232
+ token = token.replace(/^<\/?[a-z][a-z0-9]*-[a-z0-9-]+/i, match => match + '-solarite-placeholder solarite-placeholder');
232
233
  }
233
234
  tokens.push(token)
234
235
  }