@ruledwdl/dom 0.1.1 → 0.1.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.
- package/dist/wdl-dom.min.js +2 -2
- package/package.json +1 -1
- package/src/index.js +160 -4
package/dist/wdl-dom.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var N=new Set(["text","class","html","alpine","htmx","attr-ref"]);function g(l,e){return!e||l==null?l??"":String(e).split(".").reduce((i,t)=>i!=null?i[t]:"",l)??""}function S(l,e){return typeof l!="string"?l:l.replace(/\$\{([\w.]+)\}/g,(i,t)=>{let s=g(e,t);return s!=null?String(s):""}).replace(/\{\{([\w.]+)\}\}/g,(i,t)=>{let s=g(e,t);return s!=null?String(s):""})}function f(l,e){return l==null?l:typeof l=="function"?"":typeof l=="string"?S(l,e):Array.isArray(l)?l.map(i=>f(i,e)):typeof l=="object"?Object.fromEntries(Object.entries(l).map(([i,t])=>[i,f(t,e)])):l}function m(l){if(typeof l!="string"){if(l&&typeof l=="object")return{tag:String(l.tag||"div").toLowerCase(),semanticId:String(l.semanticId||l.id||"").replace(/^\./,""),repeator:l.repeator||l.loopKey||null};throw new Error("[wdl-dom] invalid layer expression")}let i=l.trim(),t=null,s=i.indexOf("*");s!==-1&&(t=i.slice(s+1),i=i.slice(0,s));let n=i.match(/^([a-zA-Z][a-zA-Z0-9_-]*)(?:\.([a-zA-Z0-9_-]+))?$/);return n?{tag:n[1].toLowerCase(),semanticId:(n[2]||"").replace(/^\./,""),repeator:t}:{tag:i.toLowerCase()||"div",semanticId:"",repeator:t}}function w(l){if(Array.isArray(l))return structuredClone(l);if(typeof l!="string"||!l.trim())return[];let e={tag:"__root__",semanticId:"",children:[]},i=[e],t=0,s=()=>i[i.length-1];for(;t<l.length;){let n=l[t];if(/\s/.test(n)){t++;continue}if(n===">"){let r=s().children[s().children.length-1];r&&i.push(r),t++;continue}if(n==="+"){t++;continue}if(n==="<"){if(t++,t<l.length&&l[t]==="*"){t++;let r="";for(;t<l.length&&/\d/.test(l[t]);)r+=l[t++];let h=r?parseInt(r,10):1;for(let d=0;d<h;d++)i.length>1&&i.pop()}else if(t<l.length&&l[t]==="@"){t++;let r="";for(;t<l.length&&/\d/.test(l[t]);)r+=l[t++];let d=(r?parseInt(r,10):0)+1;for(;i.length>d&&i.length>1;)i.pop()}else{let r=1;for(;t<l.length&&l[t]==="<";)r++,t++;for(let h=0;h<r;h++)i.length>1&&i.pop()}continue}let c="";for(;t<l.length&&/[a-zA-Z0-9_-]/.test(l[t]);)c+=l[t++];let o="";if(l[t]===".")for(t++;t<l.length&&/[a-zA-Z0-9_-]/.test(l[t]);)o+=l[t++];let a=null;if(l[t]==="*"){t++;let r="";for(;t<l.length&&/[a-zA-Z0-9_.]/.test(l[t]);)r+=l[t++];r&&(a=r)}s().children.push({tag:c.toLowerCase()||"div",semanticId:o,repeator:a,children:[]})}return e.children}function p(l){return l==null?"":String(l).replace(/^\./,"")}var y=class{constructor(e={}){let{container:i,component:t,onDataBind:s=null,styleTarget:n=typeof document<"u"?document.head:null,debug:c=!1}=e;if(!i)throw new Error("[wdl-dom] container is required");if(!t)throw new Error("[wdl-dom] component (ComponentState) is required");if(this.container=typeof i=="string"?document.querySelector(i):i,!this.container)throw new Error("[wdl-dom] container not found");this.component=t,this.onDataBind=s,this.styleTarget=n,this.debug=c,this.liveMap=new Map,this.liveNodes=new Map,this._loopBindings=[],this._unsubs=[],this._styleEl=null,this._mount(),this._bindStateEvents()}remount(){this._mount()}getLiveMap(){return new Map(this.liveMap)}getLiveNodes(e){let i=p(e);return[...this.liveNodes.get(i)||[]]}getNode(e,i=0){return this.getLiveNodes(e)[i]||null}destroy(){this._unsubs.forEach(e=>{try{e()}catch{}}),this._unsubs=[],this.container.replaceChildren(),this.liveMap.clear(),this.liveNodes.clear(),this._loopBindings=[],this._styleEl&&this._styleEl.parentNode&&this._styleEl.parentNode.removeChild(this._styleEl),this._styleEl=null}_registerNode(e,i){if(!e)return;let t=p(e);this.liveNodes.has(t)||this.liveNodes.set(t,[]);let s=this.liveNodes.get(t);s.includes(i)||s.push(i),this.liveMap.set(t,s[0])}_unregisterNode(e,i){if(!e)return;let t=p(e);if(this.liveNodes.has(t)){let s=this.liveNodes.get(t),n=s.indexOf(i);n!==-1&&s.splice(n,1),s.length===0?(this.liveNodes.delete(t),this.liveMap.delete(t)):this.liveMap.set(t,s[0])}else this.liveMap.delete(t)}_unregisterElementHierarchy(e){if(!e)return;let i=e.getAttribute?.("wdl-comp");if(i&&this._unregisterNode(i,e),Array.isArray(e.children))for(let t of e.children)this._unregisterElementHierarchy(t)}_getComponentData(){return this.component.data?.get?.()??this.component.getSnapshot?.()?.data??{}}_getComponentAttrMap(){return this.component.attr?.list?.()??this.component.getSnapshot?.()?.attr??{}}_resolveLoopItems(e,i){if(!e)return[];if(/^\d+$/.test(String(e))){let s=parseInt(e,10);return Array.from({length:Math.max(0,s)},(n,c)=>({_index:c}))}let t=g(i,e);return Array.isArray(t)?t:typeof t=="number"?Array.from({length:Math.max(0,t)},(s,n)=>({_index:n})):[]}_createItemScope(e,i,t){let s=t||this._getComponentData();return typeof e=="object"&&e!==null?{...s,...e,item:e,_index:i}:{...s,value:e,item:e,_index:i}}_mount(){this.container.replaceChildren(),this.liveMap.clear(),this.liveNodes.clear(),this._loopBindings=[];let e;try{e=typeof this.component.layers?.tree=="function"?this.component.layers.tree():w(this.component.layers?.list?.()??this.component.getSnapshot?.()?.layers)}catch(t){this._log("warn","tree() failed, falling back to simple parse",t);let s=this.component.getSnapshot?.()?.layers??"";e=w(s)}Array.isArray(e)||(e=[]);let i=this._getComponentData();for(let t of e)this._mountLayerNode(this.container,t,i);this._applyRootVariant(),this._syncRegistryStyles(),this._log("mount",`mounted ${this.liveMap.size} semantic keys, ${this._loopBindings.length} loops`)}_mountLayerNode(e,i,t){if(i.repeator){let n=this._resolveLoopItems(i.repeator,t),c=[];for(let a=0;a<n.length;a++){let r=this._createItemScope(n[a],a,t),h=this._createSingleElement(i,r,a);e.appendChild(h),c.push(h)}let o=null;typeof document.createComment=="function"&&(o=document.createComment(`wdl-loop:${i.repeator}`),e.appendChild(o)),this._loopBindings.push({parentEl:e,node:i,repeator:i.repeator,elements:c,anchor:o});return}let s=this._createSingleElement(i,t);e.appendChild(s)}_createSingleElement(e,i,t){let s=(e.tag||"div").toLowerCase(),n=p(e.semanticId||e.id||""),c=document.createElement(s);n&&(c.classList.add(n),c.setAttribute("wdl-comp",n),this._registerNode(n,c));let o=t!==void 0?t:i?._index;if(o!==void 0){let a=String(o);c.setAttribute("data-wdl-index",a),c.dataset&&(c.dataset.wdlIndex=a)}if(this._applyNodeAttrs(c,e,i),Array.isArray(e.children))for(let a of e.children)this._mountLayerNode(c,a,i);return c}_applyNodeAttrs(e,i,t){let s=this._getComponentAttrMap(),n=p(i.semanticId||i.id||""),c=(i.tag||"div").toLowerCase(),o=s[c]||{},a=n?s["."+n]||{}:{},r=n?s[n]||{}:{},h={...o,...a,...r},d=f(h,t);this._applyPropsToElement(e,n,d)}_applyPropsToElement(e,i,t){if(!(!t||typeof t!="object")){if(t.text!==void 0&&(e.textContent=String(t.text)),t.html!==void 0&&(e.innerHTML=String(t.html)),t.class!==void 0){let s=String(t.class).trim();e.className=i?s?`${i} ${s}`:i:s}for(let[s,n]of Object.entries(t))if(!N.has(s)){if(s==="style"&&n&&typeof n=="object"){Object.assign(e.style,n);continue}n==null?e.removeAttribute(s):e.setAttribute(s,String(n))}}}_bindStateEvents(){let e=this.component;if(typeof e.on!="function"){this._log("warn","component has no .on() \u2014 events will not be applied");return}let i=s=>this._onStateEvent(s),t=["layers:change","attr:change","data:change","variant:change","registry:change"];for(let s of t){let n=e.on(s,i);typeof n=="function"?this._unsubs.push(n):this._unsubs.push(()=>e.off?.(s,i))}}_onStateEvent(e){if(!(!e||!e.type))switch(this._log("event",e.type,e.action,e.targetId,e.payload),e.type){case"layers:change":this._handleLayers(e);break;case"attr:change":this._handleAttr(e);break;case"data:change":this._handleData(e);break;case"variant:change":this._handleVariant(e);break;case"registry:change":this._handleRegistry(e);break;default:this._log("warn","unknown event type",e.type)}}_handleLayers(e){let{action:i,targetId:t,payload:s}=e,n=p(t),c=this._getComponentData();switch(i){case"set":{this._mount();break}case"append":{let o=this.getNode(n);if(!o){this._log("warn",`append: parent "${n}" not in liveMap \u2014 remounting`),this._mount();return}let a=m(s);this._mountLayerNode(o,a,c),this._log("op",`append <${a.tag}.${a.semanticId}> \u2192 #${n}`);break}case"prepend":{let o=this.getNode(n);if(!o){this._log("warn",`prepend: parent "${n}" not in liveMap \u2014 remounting`),this._mount();return}let a=m(s),r=this._createSingleElement(a,c);o.insertBefore(r,o.firstChild),this._log("op",`prepend <${a.tag}.${a.semanticId}> \u2192 #${n}`);break}case"before":case"after":{let o=this.getNode(n);if(!o||!o.parentNode){this._log("warn",`${i}: target "${n}" missing \u2014 remounting`),this._mount();return}let a=m(s),r=this._createSingleElement(a,c);i==="before"?o.parentNode.insertBefore(r,o):o.parentNode.insertBefore(r,o.nextSibling),this._log("op",`${i} <${a.tag}.${a.semanticId}> relative to #${n}`);break}case"wrap":{let o=this.getNode(n);if(!o||!o.parentNode){this._log("warn",`wrap: target "${n}" missing \u2014 remounting`),this._mount();return}let a=m(s),r=this._createSingleElement(a,c);o.parentNode.insertBefore(r,o),r.appendChild(o),this._log("op",`wrap #${n} with <${a.tag}.${a.semanticId}>`);break}case"unwrap":{let o=this.getNode(n);if(!o||!o.parentNode){this._log("warn",`unwrap: target "${n}" missing \u2014 remounting`),this._mount();return}let a=o.parentNode;for(;o.firstChild;)a.insertBefore(o.firstChild,o);this._unregisterElementHierarchy(o),o.remove(),this._log("op",`unwrap #${n}`);break}case"move":{let o=this.getNode(n),{targetSemanticId:a,position:r}=s||{},h=p(a),d=this.getNode(h);if(!o||!d){this._log("warn",`move: source "${n}" or target "${h}" missing \u2014 remounting`),this._mount();return}r==="before"?d.parentNode?.insertBefore(o,d):r==="after"?d.parentNode?.insertBefore(o,d.nextSibling):d.appendChild(o),this._log("op",`move #${n} -> ${r} #${h}`);break}case"remove":{let o=this.getLiveNodes(n);if(o.length===0){this._log("warn",`remove: #${n} not in liveMap`);return}for(let a of o)this._unregisterElementHierarchy(a),a.remove();this._loopBindings=this._loopBindings.filter(a=>a.node.semanticId!==n),this._log("op",`remove #${n}`);break}case"update":{let o=this.getNode(n);if(!o){this._log("warn",`update: #${n} missing \u2014 remounting`),this._mount();return}let a=s||{};if(a.tag&&a.tag.toLowerCase()!==o.tagName.toLowerCase()){let r=document.createElement(String(a.tag).toLowerCase());for(let d of o.attributes)r.setAttribute(d.name,d.value);for(;o.firstChild;)r.appendChild(o.firstChild);o.parentNode?.replaceChild(r,o),this._unregisterNode(n,o);let h=a.semanticId?p(a.semanticId):n;a.semanticId&&h!==n&&(r.classList.remove(n),r.classList.add(h),r.setAttribute("wdl-comp",h)),this._registerNode(h,r)}else if(a.semanticId&&p(a.semanticId)!==n){let r=p(a.semanticId);o.classList.remove(n),o.classList.add(r),o.setAttribute("wdl-comp",r),this._unregisterNode(n,o),this._registerNode(r,o)}this._log("op",`update #${n}`,a);break}default:this._log("warn",`layers: unknown action "${i}" \u2014 remounting`),this._mount()}}_handleAttr(e){let{action:i,targetId:t,payload:s}=e,n=p(t);if(i==="set"||i==="update"){let c=this.getLiveNodes(n);if(c.length===0){this._log("warn",`attr: #${n} not in liveMap`);return}let o=this._getComponentData();for(let a of c){let r=a.getAttribute("data-wdl-index"),h=o;if(r!=null){let u=parseInt(r,10),v=this._findLoopForElement(a);if(v){let _=g(o,v.repeator);Array.isArray(_)&&_[u]!==void 0?h=this._createItemScope(_[u],u,o):h={...o,_index:u}}else h={...o,_index:u}}let d=f(s||{},h);this._applyPropsToElement(a,n,d)}this._log("op",`attr.${i} #${n}`,s);return}if(i==="remove"){let c=this.getLiveNodes(n);if(c.length===0)return;let o=s;for(let a of c)o==null||o===""?(a.textContent="",a.className=n):o==="text"?a.textContent="":o==="class"?a.className=n:o==="html"?a.innerHTML="":a.removeAttribute(o);this._log("op",`attr.remove ${o||"all"} from #${n}`)}}_applyAttrs(e,i){let t=this.getLiveNodes(e);if(t.length===0){this._log("warn",`attr: #${e} not in liveMap`);return}let s=this._getComponentData();for(let n of t){let c=n.getAttribute("data-wdl-index"),o=s;if(c!=null){let r=parseInt(c,10),h=this._findLoopForElement(n);if(h){let d=g(s,h.repeator);Array.isArray(d)&&d[r]!==void 0?o=this._createItemScope(d[r],r,s):o={...s,_index:r}}}let a=f(i||{},o);this._applyPropsToElement(n,e,a)}}_findLoopForElement(e){return this._loopBindings.find(i=>i.elements.includes(e))||null}_handleData(e){let{action:i,targetId:t,payload:s}=e,n=t||"",c=this._getComponentData();if(this._reconcileLoops(n,c),this._reconcileStaticDataBindings(n,c),typeof this.onDataBind=="function")try{this.onDataBind(this.container,n,i==="remove"?void 0:s)}catch(o){this._log("warn","onDataBind error",o)}this._log("op",`data.${i} ${n}`,i==="remove"?void 0:s)}_reconcileLoops(e,i){for(let t of this._loopBindings){if(!(!e||t.repeator===e||e.startsWith(t.repeator+".")||t.repeator.startsWith(e+".")))continue;let n=this._resolveLoopItems(t.repeator,i),c=n.length,o=t.elements.length,a=Math.min(o,c);for(let r=0;r<a;r++){let h=t.elements[r],d=this._createItemScope(n[r],r,i);h.setAttribute("data-wdl-index",String(r)),h.dataset&&(h.dataset.wdlIndex=String(r)),this._updateElementSubtree(h,t.node,d,r)}if(c>o)for(let r=o;r<c;r++){let h=this._createItemScope(n[r],r,i),d=this._createSingleElement(t.node,h,r);if(t.anchor&&t.anchor.parentNode===t.parentEl)t.parentEl.insertBefore(d,t.anchor);else if(t.elements.length>0){let u=t.elements[t.elements.length-1];t.parentEl.insertBefore(d,u.nextSibling)}else t.parentEl.appendChild(d);t.elements.push(d)}if(c<o)for(let r=o-1;r>=c;r--){let h=t.elements[r];this._unregisterElementHierarchy(h),h.remove(),t.elements.pop()}}}_updateElementSubtree(e,i,t,s){if(this._applyNodeAttrs(e,i,t),Array.isArray(i.children)&&Array.isArray(e.children)){let n=0;for(let c of i.children)if(c.repeator){let o=this._loopBindings.find(a=>a.parentEl===e&&a.node===c);o&&this._reconcileLoops(o.repeator,t)}else e.children[n]&&(this._updateElementSubtree(e.children[n],c,t,s),n++)}}_reconcileStaticDataBindings(e,i){let t=this._getComponentAttrMap();for(let[s,n]of Object.entries(t)){let c=p(s),o=JSON.stringify(n);if(!o.includes("${")&&!o.includes("{{")||e&&!o.includes(e))continue;let a=this.getLiveNodes(c);for(let r of a){if(r.hasAttribute("data-wdl-index")||this._findLoopForElement(r))continue;let h=f(n,i);this._applyPropsToElement(r,c,h)}}}_handleVariant(e){let{targetId:i,payload:t}=e,s=p(i)||this._rootSemanticId(),n=this.getNode(s);if(!n){let c=this._rootSemanticId(),o=c?this.getNode(c):null;o&&(t?o.dataset.variant=String(t):delete o.dataset.variant,this._log("op",`variant \u2192 ${t||"(none)"} on #${c}`));return}t?n.dataset.variant=String(t):delete n.dataset.variant,this._log("op",`variant \u2192 ${t||"(none)"} on #${s}`)}_applyRootVariant(){let e=this._getComponentAttrMap(),i=this._rootSemanticId();if(!i)return;let t="."+i,s=e[t]?.["data-variant"]??e["."]?.["data-variant"]??null;if(s&&this.liveMap.has(i)){let n=this.getNode(i);n&&n.dataset&&(n.dataset.variant=String(s))}}_rootSemanticId(){for(let[i,t]of this.liveMap)if(t.parentNode===this.container)return i;let e=this.liveMap.keys().next();return e.done?"":e.value}_handleRegistry(e){this._syncRegistryStyles(),this._log("op",`registry.${e.action}`)}_syncRegistryStyles(){if(!this.styleTarget)return;let e=this.component.registry?.get?.()??this.component.getSnapshot?.()?.registry??null,i=this.component.id||this.component.getSnapshot?.()?.id||"comp";if(this._styleEl||(this._styleEl=document.createElement("style"),this._styleEl.setAttribute("data-wdl-dom",i),this.styleTarget.appendChild(this._styleEl)),!e){this._styleEl.textContent="";return}let t=Array.isArray(e.rules)?e.rules:[],s=[];if(e.vars&&typeof e.vars=="object"){let n=Object.entries(e.vars).map(([c,o])=>`--${c}: ${o};`).join(" ");n&&s.push(`:root, [wdl-comp] { ${n} }`)}for(let n of t){if(!n||!n.selector)continue;let c=typeof n.css=="string"?n.css:n.css&&typeof n.css=="object"?Object.entries(n.css).map(([r,h])=>`${$(r)}: ${h};`).join(" "):"";if(!c)continue;let o=n.selector.startsWith("&")?n.selector.replace("&",`[wdl-comp="${i}"]`):n.selector,a=n.media?`@media ${n.media} { ${o} { ${c} } }`:`${o} { ${c} }`;s.push(a)}this._styleEl.textContent=s.join(`
|
|
2
|
-
`)}_log(e,...
|
|
1
|
+
var S=new Set(["text","class","html","alpine","htmx","attr-ref"]);function y(c,e){return!e||c==null?c??"":String(e).split(".").reduce((s,t)=>s!=null?s[t]:"",c)??""}function m(c,e){return typeof c!="string"?c:c.replace(/\$\{([\w.]+)\}/g,(s,t)=>{let o=y(e,t);return o!=null?String(o):""}).replace(/\{\{([\w.]+)\}\}/g,(s,t)=>{let o=y(e,t);return o!=null?String(o):""})}function _(c,e){return c==null?c:typeof c=="function"?"":typeof c=="string"?m(c,e):Array.isArray(c)?c.map(s=>_(s,e)):typeof c=="object"?Object.fromEntries(Object.entries(c).map(([s,t])=>[s,_(t,e)])):c}function w(c){if(typeof c!="string"){if(c&&typeof c=="object")return{tag:String(c.tag||"div").toLowerCase(),semanticId:String(c.semanticId||c.id||"").replace(/^\./,""),repeator:c.repeator||c.loopKey||null};throw new Error("[wdl-dom] invalid layer expression")}let s=c.trim(),t=null,o=s.indexOf("*");o!==-1&&(t=s.slice(o+1),s=s.slice(0,o));let n=s.match(/^([a-zA-Z][a-zA-Z0-9_-]*)(?:\.([a-zA-Z0-9_-]+))?$/);return n?{tag:n[1].toLowerCase(),semanticId:(n[2]||"").replace(/^\./,""),repeator:t}:{tag:s.toLowerCase()||"div",semanticId:"",repeator:t}}function N(c){if(Array.isArray(c))return structuredClone(c);if(typeof c!="string"||!c.trim())return[];let e={tag:"__root__",semanticId:"",children:[]},s=[e],t=0,o=()=>s[s.length-1];for(;t<c.length;){let n=c[t];if(/\s/.test(n)){t++;continue}if(n===">"){let a=o().children[o().children.length-1];a&&s.push(a),t++;continue}if(n==="+"){t++;continue}if(n==="<"){if(t++,t<c.length&&c[t]==="*"){t++;let a="";for(;t<c.length&&/\d/.test(c[t]);)a+=c[t++];let h=a?parseInt(a,10):1;for(let d=0;d<h;d++)s.length>1&&s.pop()}else if(t<c.length&&c[t]==="@"){t++;let a="";for(;t<c.length&&/\d/.test(c[t]);)a+=c[t++];let d=(a?parseInt(a,10):0)+1;for(;s.length>d&&s.length>1;)s.pop()}else{let a=1;for(;t<c.length&&c[t]==="<";)a++,t++;for(let h=0;h<a;h++)s.length>1&&s.pop()}continue}let r="";for(;t<c.length&&/[a-zA-Z0-9_-]/.test(c[t]);)r+=c[t++];let i="";if(c[t]===".")for(t++;t<c.length&&/[a-zA-Z0-9_-]/.test(c[t]);)i+=c[t++];let l=null;if(c[t]==="*"){t++;let a="";for(;t<c.length&&/[a-zA-Z0-9_.]/.test(c[t]);)a+=c[t++];a&&(l=a)}o().children.push({tag:r.toLowerCase()||"div",semanticId:i,repeator:l,children:[]})}return e.children}function u(c){return c==null?"":String(c).replace(/^\./,"")}var C=class{constructor(e={}){let{container:s,component:t,onDataBind:o=null,styleTarget:n=typeof document<"u"?document.head:null,debug:r=!1}=e;if(!s)throw new Error("[wdl-dom] container is required");if(!t)throw new Error("[wdl-dom] component (ComponentState) is required");if(this.container=typeof s=="string"?document.querySelector(s):s,!this.container)throw new Error("[wdl-dom] container not found");this.component=t,this.onDataBind=o,this.styleTarget=n,this.debug=r,this.liveMap=new Map,this.liveNodes=new Map,this._loopBindings=[],this._unsubs=[],this._styleEl=null,this._mount(),this._bindStateEvents()}remount(){this._mount()}getLiveMap(){return new Map(this.liveMap)}getLiveNodes(e){let s=u(e);return[...this.liveNodes.get(s)||[]]}getNode(e,s=0){return this.getLiveNodes(e)[s]||null}destroy(){this._unsubs.forEach(e=>{try{e()}catch{}}),this._unsubs=[],this.container.replaceChildren(),this.liveMap.clear(),this.liveNodes.clear(),this._loopBindings=[],this._styleEl&&this._styleEl.parentNode&&this._styleEl.parentNode.removeChild(this._styleEl),this._styleEl=null}_registerNode(e,s){if(!e)return;let t=u(e);this.liveNodes.has(t)||this.liveNodes.set(t,[]);let o=this.liveNodes.get(t);o.includes(s)||o.push(s),this.liveMap.set(t,o[0])}_unregisterNode(e,s){if(!e)return;let t=u(e);if(this.liveNodes.has(t)){let o=this.liveNodes.get(t),n=o.indexOf(s);n!==-1&&o.splice(n,1),o.length===0?(this.liveNodes.delete(t),this.liveMap.delete(t)):this.liveMap.set(t,o[0])}else this.liveMap.delete(t)}_unregisterElementHierarchy(e){if(!e)return;let s=e.getAttribute?.("wdl-comp");if(s&&this._unregisterNode(s,e),Array.isArray(e.children))for(let t of e.children)this._unregisterElementHierarchy(t)}_getComponentData(){return this.component.data?.get?.()??this.component.getSnapshot?.()?.data??{}}_getComponentAttrMap(){return this.component.attr?.list?.()??this.component.getSnapshot?.()?.attr??{}}_getComponentRegistry(){return this.component.registry?.get?.()??this.component.getSnapshot?.()?.registry??{}}_getRegistryClasses(e,s,t,o){let n=this._getComponentRegistry();if(!n||typeof n!="object")return"";let r=(e?n[e]||n["."+e]:null)||(s?n[s]:null);if(!r)return"";if(typeof r=="string")return m(r,t);if(typeof r!="object"||r===null)return"";let i=[];typeof r.base=="string"&&r.base?i.push(m(r.base,t)):typeof r.class=="string"&&r.class&&i.push(m(r.class,t));let l=o?.dataset?.variant||o?.getAttribute?.("data-variant")||this.component.variant?.get?.(e)||r.defaultVariant||null;if(l&&r.variants&&typeof r.variants=="object"){let a=r.variants[l];typeof a=="string"&&a&&i.push(m(a,t))}if(r.states&&typeof r.states=="object"){for(let[a,h]of Object.entries(r.states))if(typeof h=="string"&&h){let p=m(h,t).split(/\s+/).filter(Boolean).map(f=>f.includes(":")?f:`${a}:${f}`).join(" ");i.push(p)}}if(r.breakpoints&&typeof r.breakpoints=="object"){for(let[a,h]of Object.entries(r.breakpoints))if(typeof h=="string"&&h){let p=m(h,t).split(/\s+/).filter(Boolean).map(f=>f.includes(":")?f:`${a}:${f}`).join(" ");i.push(p)}}return i.filter(Boolean).join(" ")}_resolveLoopItems(e,s){if(!e)return[];if(/^\d+$/.test(String(e))){let o=parseInt(e,10);return Array.from({length:Math.max(0,o)},(n,r)=>({_index:r}))}let t=y(s,e);return Array.isArray(t)?t:typeof t=="number"?Array.from({length:Math.max(0,t)},(o,n)=>({_index:n})):[]}_createItemScope(e,s,t){let o=t||this._getComponentData();return typeof e=="object"&&e!==null?{...o,...e,item:e,_index:s}:{...o,value:e,item:e,_index:s}}_mount(){this.container.replaceChildren(),this.liveMap.clear(),this.liveNodes.clear(),this._loopBindings=[];let e;try{e=typeof this.component.layers?.tree=="function"?this.component.layers.tree():N(this.component.layers?.list?.()??this.component.getSnapshot?.()?.layers)}catch(t){this._log("warn","tree() failed, falling back to simple parse",t);let o=this.component.getSnapshot?.()?.layers??"";e=N(o)}Array.isArray(e)||(e=[]);let s=this._getComponentData();for(let t of e)this._mountLayerNode(this.container,t,s);this._applyRootVariant(),this._syncRegistryStyles(),this._log("mount",`mounted ${this.liveMap.size} semantic keys, ${this._loopBindings.length} loops`)}_mountLayerNode(e,s,t){if(s.repeator){let n=this._resolveLoopItems(s.repeator,t),r=[];for(let l=0;l<n.length;l++){let a=this._createItemScope(n[l],l,t),h=this._createSingleElement(s,a,l);e.appendChild(h),r.push(h)}let i=null;typeof document.createComment=="function"&&(i=document.createComment(`wdl-loop:${s.repeator}`),e.appendChild(i)),this._loopBindings.push({parentEl:e,node:s,repeator:s.repeator,elements:r,anchor:i});return}let o=this._createSingleElement(s,t);e.appendChild(o)}_createSingleElement(e,s,t){let o=(e.tag||"div").toLowerCase(),n=u(e.semanticId||e.id||""),r=document.createElement(o);n&&(r.classList.add(n),r.setAttribute("wdl-comp",n),this._registerNode(n,r));let i=t!==void 0?t:s?._index;if(i!==void 0){let l=String(i);r.setAttribute("data-wdl-index",l),r.dataset&&(r.dataset.wdlIndex=l)}if(this._applyNodeAttrs(r,e,s),Array.isArray(e.children))for(let l of e.children)this._mountLayerNode(r,l,s);return r}_applyNodeAttrs(e,s,t){let o=this._getComponentAttrMap(),n=u(s.semanticId||s.id||""),r=(s.tag||"div").toLowerCase(),i=o[r]||{},l=n?o["."+n]||{}:{},a=n?o[n]||{}:{},h={...i,...l,...a},d=_(h,t),p=this._getRegistryClasses(n,r,t,e),f=typeof d.class=="string"?d.class:"",g=[n,p,f].filter(Boolean).join(" ").split(/\s+/).filter(Boolean),b=Array.from(new Set(g)).join(" ");this._applyPropsToElement(e,n,{...d,class:b})}_refreshElementClasses(e,s){if(!e)return;let t=u(s||e.getAttribute("wdl-comp")||""),o=this._getComponentData(),n=this._getComponentAttrMap(),r=(e.tagName||"div").toLowerCase(),i=e.getAttribute("data-wdl-index"),l=o;if(i!=null){let v=parseInt(i,10),E=this._findLoopForElement(e);if(E){let A=y(o,E.repeator);Array.isArray(A)&&A[v]!==void 0?l=this._createItemScope(A[v],v,o):l={...o,_index:v}}else l={...o,_index:v}}let a=n[r]||{},h=t?n["."+t]||{}:{},d=t?n[t]||{}:{},p={...a,...h,...d},f=_(p,l),g=this._getRegistryClasses(t,r,l,e),b=typeof f.class=="string"?f.class:"",$=[t,g,b].filter(Boolean).join(" ").split(/\s+/).filter(Boolean);e.className=Array.from(new Set($)).join(" ")}_refreshAllElementClasses(){for(let[e,s]of this.liveNodes)for(let t of s)this._refreshElementClasses(t,e)}_applyPropsToElement(e,s,t){if(!(!t||typeof t!="object")){t.text!==void 0&&(e.textContent=String(t.text)),t.html!==void 0&&(e.innerHTML=String(t.html)),t.class!==void 0&&(e.className=String(t.class).trim());for(let[o,n]of Object.entries(t))if(!S.has(o)){if(o==="style"&&n&&typeof n=="object"){Object.assign(e.style,n);continue}n==null?e.removeAttribute(o):e.setAttribute(o,String(n))}}}_bindStateEvents(){let e=this.component;if(typeof e.on!="function"){this._log("warn","component has no .on() \u2014 events will not be applied");return}let s=o=>this._onStateEvent(o),t=["layers:change","attr:change","data:change","variant:change","registry:change"];for(let o of t){let n=e.on(o,s);typeof n=="function"?this._unsubs.push(n):this._unsubs.push(()=>e.off?.(o,s))}}_onStateEvent(e){if(!(!e||!e.type))switch(this._log("event",e.type,e.action,e.targetId,e.payload),e.type){case"layers:change":this._handleLayers(e);break;case"attr:change":this._handleAttr(e);break;case"data:change":this._handleData(e);break;case"variant:change":this._handleVariant(e);break;case"registry:change":this._handleRegistry(e);break;default:this._log("warn","unknown event type",e.type)}}_handleLayers(e){let{action:s,targetId:t,payload:o}=e,n=u(t),r=this._getComponentData();switch(s){case"set":{this._mount();break}case"append":{let i=this.getNode(n);if(!i){this._log("warn",`append: parent "${n}" not in liveMap \u2014 remounting`),this._mount();return}let l=w(o);this._mountLayerNode(i,l,r),this._log("op",`append <${l.tag}.${l.semanticId}> \u2192 #${n}`);break}case"prepend":{let i=this.getNode(n);if(!i){this._log("warn",`prepend: parent "${n}" not in liveMap \u2014 remounting`),this._mount();return}let l=w(o),a=this._createSingleElement(l,r);i.insertBefore(a,i.firstChild),this._log("op",`prepend <${l.tag}.${l.semanticId}> \u2192 #${n}`);break}case"before":case"after":{let i=this.getNode(n);if(!i||!i.parentNode){this._log("warn",`${s}: target "${n}" missing \u2014 remounting`),this._mount();return}let l=w(o),a=this._createSingleElement(l,r);s==="before"?i.parentNode.insertBefore(a,i):i.parentNode.insertBefore(a,i.nextSibling),this._log("op",`${s} <${l.tag}.${l.semanticId}> relative to #${n}`);break}case"wrap":{let i=this.getNode(n);if(!i||!i.parentNode){this._log("warn",`wrap: target "${n}" missing \u2014 remounting`),this._mount();return}let l=w(o),a=this._createSingleElement(l,r);i.parentNode.insertBefore(a,i),a.appendChild(i),this._log("op",`wrap #${n} with <${l.tag}.${l.semanticId}>`);break}case"unwrap":{let i=this.getNode(n);if(!i||!i.parentNode){this._log("warn",`unwrap: target "${n}" missing \u2014 remounting`),this._mount();return}let l=i.parentNode;for(;i.firstChild;)l.insertBefore(i.firstChild,i);this._unregisterElementHierarchy(i),i.remove(),this._log("op",`unwrap #${n}`);break}case"move":{let i=this.getNode(n),{targetSemanticId:l,position:a}=o||{},h=u(l),d=this.getNode(h);if(!i||!d){this._log("warn",`move: source "${n}" or target "${h}" missing \u2014 remounting`),this._mount();return}a==="before"?d.parentNode?.insertBefore(i,d):a==="after"?d.parentNode?.insertBefore(i,d.nextSibling):d.appendChild(i),this._log("op",`move #${n} -> ${a} #${h}`);break}case"remove":{let i=this.getLiveNodes(n);if(i.length===0){this._log("warn",`remove: #${n} not in liveMap`);return}for(let l of i)this._unregisterElementHierarchy(l),l.remove();this._loopBindings=this._loopBindings.filter(l=>l.node.semanticId!==n),this._log("op",`remove #${n}`);break}case"update":{let i=this.getNode(n);if(!i){this._log("warn",`update: #${n} missing \u2014 remounting`),this._mount();return}let l=o||{};if(l.tag&&l.tag.toLowerCase()!==i.tagName.toLowerCase()){let a=document.createElement(String(l.tag).toLowerCase());for(let d of i.attributes)a.setAttribute(d.name,d.value);for(;i.firstChild;)a.appendChild(i.firstChild);i.parentNode?.replaceChild(a,i),this._unregisterNode(n,i);let h=l.semanticId?u(l.semanticId):n;l.semanticId&&h!==n&&(a.classList.remove(n),a.classList.add(h),a.setAttribute("wdl-comp",h)),this._registerNode(h,a)}else if(l.semanticId&&u(l.semanticId)!==n){let a=u(l.semanticId);i.classList.remove(n),i.classList.add(a),i.setAttribute("wdl-comp",a),this._unregisterNode(n,i),this._registerNode(a,i)}this._log("op",`update #${n}`,l);break}default:this._log("warn",`layers: unknown action "${s}" \u2014 remounting`),this._mount()}}_handleAttr(e){let{action:s,targetId:t,payload:o}=e,n=u(t);if(s==="set"||s==="update"){let r=this.getLiveNodes(n);if(r.length===0){this._log("warn",`attr: #${n} not in liveMap`);return}let i=this._getComponentData();for(let l of r){let a=l.getAttribute("data-wdl-index"),h=i;if(a!=null){let p=parseInt(a,10),f=this._findLoopForElement(l);if(f){let g=y(i,f.repeator);Array.isArray(g)&&g[p]!==void 0?h=this._createItemScope(g[p],p,i):h={...i,_index:p}}else h={...i,_index:p}}let d=_(o||{},h);this._applyPropsToElement(l,n,d)}this._log("op",`attr.${s} #${n}`,o);return}if(s==="remove"){let r=this.getLiveNodes(n);if(r.length===0)return;let i=o;for(let l of r)i==null||i===""?(l.textContent="",l.className=n):i==="text"?l.textContent="":i==="class"?l.className=n:i==="html"?l.innerHTML="":l.removeAttribute(i);this._log("op",`attr.remove ${i||"all"} from #${n}`)}}_applyAttrs(e,s){let t=this.getLiveNodes(e);if(t.length===0){this._log("warn",`attr: #${e} not in liveMap`);return}let o=this._getComponentData();for(let n of t){let r=n.getAttribute("data-wdl-index"),i=o;if(r!=null){let a=parseInt(r,10),h=this._findLoopForElement(n);if(h){let d=y(o,h.repeator);Array.isArray(d)&&d[a]!==void 0?i=this._createItemScope(d[a],a,o):i={...o,_index:a}}}let l=_(s||{},i);this._applyPropsToElement(n,e,l)}}_findLoopForElement(e){return this._loopBindings.find(s=>s.elements.includes(e))||null}_handleData(e){let{action:s,targetId:t,payload:o}=e,n=t||"",r=this._getComponentData();if(this._reconcileLoops(n,r),this._reconcileStaticDataBindings(n,r),typeof this.onDataBind=="function")try{this.onDataBind(this.container,n,s==="remove"?void 0:o)}catch(i){this._log("warn","onDataBind error",i)}this._log("op",`data.${s} ${n}`,s==="remove"?void 0:o)}_reconcileLoops(e,s){for(let t of this._loopBindings){if(!(!e||t.repeator===e||e.startsWith(t.repeator+".")||t.repeator.startsWith(e+".")))continue;let n=this._resolveLoopItems(t.repeator,s),r=n.length,i=t.elements.length,l=Math.min(i,r);for(let a=0;a<l;a++){let h=t.elements[a],d=this._createItemScope(n[a],a,s);h.setAttribute("data-wdl-index",String(a)),h.dataset&&(h.dataset.wdlIndex=String(a)),this._updateElementSubtree(h,t.node,d,a)}if(r>i)for(let a=i;a<r;a++){let h=this._createItemScope(n[a],a,s),d=this._createSingleElement(t.node,h,a);if(t.anchor&&t.anchor.parentNode===t.parentEl)t.parentEl.insertBefore(d,t.anchor);else if(t.elements.length>0){let p=t.elements[t.elements.length-1];t.parentEl.insertBefore(d,p.nextSibling)}else t.parentEl.appendChild(d);t.elements.push(d)}if(r<i)for(let a=i-1;a>=r;a--){let h=t.elements[a];this._unregisterElementHierarchy(h),h.remove(),t.elements.pop()}}}_updateElementSubtree(e,s,t,o){if(this._applyNodeAttrs(e,s,t),Array.isArray(s.children)&&Array.isArray(e.children)){let n=0;for(let r of s.children)if(r.repeator){let i=this._loopBindings.find(l=>l.parentEl===e&&l.node===r);i&&this._reconcileLoops(i.repeator,t)}else e.children[n]&&(this._updateElementSubtree(e.children[n],r,t,o),n++)}}_reconcileStaticDataBindings(e,s){let t=this._getComponentAttrMap();for(let[o,n]of Object.entries(t)){let r=u(o),i=JSON.stringify(n);if(!i.includes("${")&&!i.includes("{{")||e&&!i.includes(e))continue;let l=this.getLiveNodes(r);for(let a of l){if(a.hasAttribute("data-wdl-index")||this._findLoopForElement(a))continue;let h=_(n,s);this._applyPropsToElement(a,r,h)}}}_handleVariant(e){let{targetId:s,payload:t}=e,o=u(s)||this._rootSemanticId(),n=this.getNode(o);if(!n){let r=this._rootSemanticId(),i=r?this.getNode(r):null;i&&(t?i.dataset.variant=String(t):delete i.dataset.variant,this._refreshElementClasses(i,r),this._log("op",`variant \u2192 ${t||"(none)"} on #${r}`));return}t?n.dataset.variant=String(t):delete n.dataset.variant,this._refreshElementClasses(n,o),this._log("op",`variant \u2192 ${t||"(none)"} on #${o}`)}_applyRootVariant(){let e=this._getComponentAttrMap(),s=this._rootSemanticId();if(!s)return;let t="."+s,o=e[t]?.["data-variant"]??e["."]?.["data-variant"]??null;if(o&&this.liveMap.has(s)){let n=this.getNode(s);n&&n.dataset&&(n.dataset.variant=String(o),this._refreshElementClasses(n,s))}}_rootSemanticId(){for(let[s,t]of this.liveMap)if(t.parentNode===this.container)return s;let e=this.liveMap.keys().next();return e.done?"":e.value}_handleRegistry(e){this._syncRegistryStyles(),this._refreshAllElementClasses(),this._log("op",`registry.${e.action}`)}_syncRegistryStyles(){if(!this.styleTarget)return;let e=this.component.registry?.get?.()??this.component.getSnapshot?.()?.registry??null,s=this.component.id||this.component.getSnapshot?.()?.id||"comp";if(this._styleEl||(this._styleEl=document.createElement("style"),this._styleEl.setAttribute("data-wdl-dom",s),this.styleTarget.appendChild(this._styleEl)),!e){this._styleEl.textContent="";return}let t=Array.isArray(e.rules)?e.rules:[],o=[];if(e.vars&&typeof e.vars=="object"){let n=Object.entries(e.vars).map(([r,i])=>`--${r}: ${i};`).join(" ");n&&o.push(`:root, [wdl-comp] { ${n} }`)}for(let n of t){if(!n||!n.selector)continue;let r=typeof n.css=="string"?n.css:n.css&&typeof n.css=="object"?Object.entries(n.css).map(([a,h])=>`${I(a)}: ${h};`).join(" "):"";if(!r)continue;let i=n.selector.startsWith("&")?n.selector.replace("&",`[wdl-comp="${s}"]`):n.selector,l=n.media?`@media ${n.media} { ${i} { ${r} } }`:`${i} { ${r} }`;o.push(l)}this._styleEl.textContent=o.join(`
|
|
2
|
+
`)}_log(e,...s){if(!this.debug&&e!=="warn")return;let t=`[wdl-dom:${e}]`;e==="warn"?console.warn(t,...s):console.log(t,...s)}};function I(c){return String(c).replace(/[A-Z]/g,e=>"-"+e.toLowerCase())}function x(c){return new C(c)}var L=x;export{C as WdlDom,x as createWdlDom,L as default,u as normalizeId,w as parseLayerToken,N as parseLayersSimple,_ as resolveAll,y as resolvePath,m as resolveStr};
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -387,6 +387,87 @@ export class WdlDom {
|
|
|
387
387
|
);
|
|
388
388
|
}
|
|
389
389
|
|
|
390
|
+
_getComponentRegistry() {
|
|
391
|
+
return (
|
|
392
|
+
this.component.registry?.get?.() ??
|
|
393
|
+
this.component.getSnapshot?.()?.registry ??
|
|
394
|
+
{}
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
_getRegistryClasses(id, tag, dataScope, el) {
|
|
399
|
+
const registry = this._getComponentRegistry();
|
|
400
|
+
if (!registry || typeof registry !== 'object') return '';
|
|
401
|
+
|
|
402
|
+
const entry =
|
|
403
|
+
(id ? registry[id] || registry['.' + id] : null) ||
|
|
404
|
+
(tag ? registry[tag] : null);
|
|
405
|
+
|
|
406
|
+
if (!entry) return '';
|
|
407
|
+
|
|
408
|
+
if (typeof entry === 'string') {
|
|
409
|
+
return resolveStr(entry, dataScope);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (typeof entry !== 'object' || entry === null) return '';
|
|
413
|
+
|
|
414
|
+
const classes = [];
|
|
415
|
+
|
|
416
|
+
// Base utility class string
|
|
417
|
+
if (typeof entry.base === 'string' && entry.base) {
|
|
418
|
+
classes.push(resolveStr(entry.base, dataScope));
|
|
419
|
+
} else if (typeof entry.class === 'string' && entry.class) {
|
|
420
|
+
classes.push(resolveStr(entry.class, dataScope));
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Active Variant classes
|
|
424
|
+
const activeVariant =
|
|
425
|
+
el?.dataset?.variant ||
|
|
426
|
+
el?.getAttribute?.('data-variant') ||
|
|
427
|
+
this.component.variant?.get?.(id) ||
|
|
428
|
+
entry.defaultVariant ||
|
|
429
|
+
null;
|
|
430
|
+
|
|
431
|
+
if (activeVariant && entry.variants && typeof entry.variants === 'object') {
|
|
432
|
+
const vVal = entry.variants[activeVariant];
|
|
433
|
+
if (typeof vVal === 'string' && vVal) {
|
|
434
|
+
classes.push(resolveStr(vVal, dataScope));
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// States (e.g. hover, focus)
|
|
439
|
+
if (entry.states && typeof entry.states === 'object') {
|
|
440
|
+
for (const [state, cls] of Object.entries(entry.states)) {
|
|
441
|
+
if (typeof cls === 'string' && cls) {
|
|
442
|
+
const resolved = resolveStr(cls, dataScope);
|
|
443
|
+
const formatted = resolved
|
|
444
|
+
.split(/\s+/)
|
|
445
|
+
.filter(Boolean)
|
|
446
|
+
.map((c) => (c.includes(':') ? c : `${state}:${c}`))
|
|
447
|
+
.join(' ');
|
|
448
|
+
classes.push(formatted);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// Breakpoints (e.g. md, lg)
|
|
454
|
+
if (entry.breakpoints && typeof entry.breakpoints === 'object') {
|
|
455
|
+
for (const [bp, cls] of Object.entries(entry.breakpoints)) {
|
|
456
|
+
if (typeof cls === 'string' && cls) {
|
|
457
|
+
const resolved = resolveStr(cls, dataScope);
|
|
458
|
+
const formatted = resolved
|
|
459
|
+
.split(/\s+/)
|
|
460
|
+
.filter(Boolean)
|
|
461
|
+
.map((c) => (c.includes(':') ? c : `${bp}:${c}`))
|
|
462
|
+
.join(' ');
|
|
463
|
+
classes.push(formatted);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return classes.filter(Boolean).join(' ');
|
|
469
|
+
}
|
|
470
|
+
|
|
390
471
|
_resolveLoopItems(repeator, dataScope) {
|
|
391
472
|
if (!repeator) return [];
|
|
392
473
|
if (/^\d+$/.test(String(repeator))) {
|
|
@@ -536,7 +617,77 @@ export class WdlDom {
|
|
|
536
617
|
const merged = { ...tagAttrs, ...idDotAttrs, ...idAttrs };
|
|
537
618
|
const resolved = resolveAll(merged, dataScope);
|
|
538
619
|
|
|
539
|
-
|
|
620
|
+
// Merge semantic ID, registry classes, and attr classes
|
|
621
|
+
const registryClasses = this._getRegistryClasses(id, tag, dataScope, el);
|
|
622
|
+
const attrClasses = typeof resolved.class === 'string' ? resolved.class : '';
|
|
623
|
+
|
|
624
|
+
const combinedClasses = [
|
|
625
|
+
id,
|
|
626
|
+
registryClasses,
|
|
627
|
+
attrClasses,
|
|
628
|
+
]
|
|
629
|
+
.filter(Boolean)
|
|
630
|
+
.join(' ')
|
|
631
|
+
.split(/\s+/)
|
|
632
|
+
.filter(Boolean);
|
|
633
|
+
|
|
634
|
+
const uniqueClasses = Array.from(new Set(combinedClasses)).join(' ');
|
|
635
|
+
|
|
636
|
+
this._applyPropsToElement(el, id, { ...resolved, class: uniqueClasses });
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
_refreshElementClasses(el, id) {
|
|
640
|
+
if (!el) return;
|
|
641
|
+
const normId = normalizeId(id || el.getAttribute('wdl-comp') || '');
|
|
642
|
+
const compData = this._getComponentData();
|
|
643
|
+
const attrMap = this._getComponentAttrMap();
|
|
644
|
+
const tag = (el.tagName || 'div').toLowerCase();
|
|
645
|
+
|
|
646
|
+
const idx = el.getAttribute('data-wdl-index');
|
|
647
|
+
let scope = compData;
|
|
648
|
+
if (idx !== null && idx !== undefined) {
|
|
649
|
+
const indexNum = parseInt(idx, 10);
|
|
650
|
+
const loop = this._findLoopForElement(el);
|
|
651
|
+
if (loop) {
|
|
652
|
+
const items = resolvePath(compData, loop.repeator);
|
|
653
|
+
if (Array.isArray(items) && items[indexNum] !== undefined) {
|
|
654
|
+
scope = this._createItemScope(items[indexNum], indexNum, compData);
|
|
655
|
+
} else {
|
|
656
|
+
scope = { ...compData, _index: indexNum };
|
|
657
|
+
}
|
|
658
|
+
} else {
|
|
659
|
+
scope = { ...compData, _index: indexNum };
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
const tagAttrs = attrMap[tag] || {};
|
|
664
|
+
const idDotAttrs = normId ? attrMap['.' + normId] || {} : {};
|
|
665
|
+
const idAttrs = normId ? attrMap[normId] || {} : {};
|
|
666
|
+
const merged = { ...tagAttrs, ...idDotAttrs, ...idAttrs };
|
|
667
|
+
const resolved = resolveAll(merged, scope);
|
|
668
|
+
|
|
669
|
+
const registryClasses = this._getRegistryClasses(normId, tag, scope, el);
|
|
670
|
+
const attrClasses = typeof resolved.class === 'string' ? resolved.class : '';
|
|
671
|
+
|
|
672
|
+
const combinedClasses = [
|
|
673
|
+
normId,
|
|
674
|
+
registryClasses,
|
|
675
|
+
attrClasses,
|
|
676
|
+
]
|
|
677
|
+
.filter(Boolean)
|
|
678
|
+
.join(' ')
|
|
679
|
+
.split(/\s+/)
|
|
680
|
+
.filter(Boolean);
|
|
681
|
+
|
|
682
|
+
el.className = Array.from(new Set(combinedClasses)).join(' ');
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
_refreshAllElementClasses() {
|
|
686
|
+
for (const [id, nodes] of this.liveNodes) {
|
|
687
|
+
for (const el of nodes) {
|
|
688
|
+
this._refreshElementClasses(el, id);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
540
691
|
}
|
|
541
692
|
|
|
542
693
|
/**
|
|
@@ -552,8 +703,7 @@ export class WdlDom {
|
|
|
552
703
|
el.innerHTML = String(props.html);
|
|
553
704
|
}
|
|
554
705
|
if (props.class !== undefined) {
|
|
555
|
-
|
|
556
|
-
el.className = id ? (extra ? `${id} ${extra}` : id) : extra;
|
|
706
|
+
el.className = String(props.class).trim();
|
|
557
707
|
}
|
|
558
708
|
|
|
559
709
|
for (const [key, value] of Object.entries(props)) {
|
|
@@ -1036,12 +1186,14 @@ export class WdlDom {
|
|
|
1036
1186
|
if (rootEl) {
|
|
1037
1187
|
if (payload) rootEl.dataset.variant = String(payload);
|
|
1038
1188
|
else delete rootEl.dataset.variant;
|
|
1189
|
+
this._refreshElementClasses(rootEl, rootId);
|
|
1039
1190
|
this._log('op', `variant → ${payload || '(none)'} on #${rootId}`);
|
|
1040
1191
|
}
|
|
1041
1192
|
return;
|
|
1042
1193
|
}
|
|
1043
1194
|
if (payload) el.dataset.variant = String(payload);
|
|
1044
1195
|
else delete el.dataset.variant;
|
|
1196
|
+
this._refreshElementClasses(el, id);
|
|
1045
1197
|
this._log('op', `variant → ${payload || '(none)'} on #${id}`);
|
|
1046
1198
|
}
|
|
1047
1199
|
|
|
@@ -1056,7 +1208,10 @@ export class WdlDom {
|
|
|
1056
1208
|
null;
|
|
1057
1209
|
if (variant && this.liveMap.has(rootId)) {
|
|
1058
1210
|
const el = this.getNode(rootId);
|
|
1059
|
-
if (el && el.dataset)
|
|
1211
|
+
if (el && el.dataset) {
|
|
1212
|
+
el.dataset.variant = String(variant);
|
|
1213
|
+
this._refreshElementClasses(el, rootId);
|
|
1214
|
+
}
|
|
1060
1215
|
}
|
|
1061
1216
|
}
|
|
1062
1217
|
|
|
@@ -1076,6 +1231,7 @@ export class WdlDom {
|
|
|
1076
1231
|
|
|
1077
1232
|
_handleRegistry(event) {
|
|
1078
1233
|
this._syncRegistryStyles();
|
|
1234
|
+
this._refreshAllElementClasses();
|
|
1079
1235
|
this._log('op', `registry.${event.action}`);
|
|
1080
1236
|
}
|
|
1081
1237
|
|