@craftile/preview-client-html 1.0.8 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/html.cdn.js CHANGED
@@ -1 +1 @@
1
- var xe=Object.defineProperty;var Oe=(y,k,u)=>k in y?xe(y,k,{enumerable:!0,configurable:!0,writable:!0,value:u}):y[k]=u;var w=(y,k,u)=>Oe(y,typeof k!="symbol"?k+"":k,u);var HtmlPreviewClient=(function(){"use strict";var y=Object.defineProperty,k=(s,e,t)=>e in s?y(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t,u=(s,e,t)=>k(s,typeof e!="symbol"?e+"":e,t);class re{constructor(e,t="*"){u(this,"handlers",new Map),u(this,"targetWindow"),u(this,"targetOrigin"),u(this,"fallbackHandler"),this.targetWindow=e,this.targetOrigin=t,window.addEventListener("message",this.handleMessage.bind(this))}handleMessage(e){const t=e.data;if(!t.type)return;const n=this.handlers.get(t.type);n?n.forEach(i=>i(t.payload,e)):this.fallbackHandler&&this.fallbackHandler(e.data,e)}send(e,t){const n={type:e,payload:t};this.targetWindow.postMessage(n,this.targetOrigin)}listen(e,t){return this.handlers.has(e)||this.handlers.set(e,[]),this.handlers.get(e).push(t),()=>{const n=this.handlers.get(e);if(n){const i=n.indexOf(t);i>-1&&n.splice(i,1)}}}registerFallbackHandler(e){this.fallbackHandler=e}}function se(s="*"){if(window.parent===window)throw new Error("Not inside an iframe");return new re(window.parent,s)}class oe{constructor(){u(this,"listeners",new Map)}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>{this.off(e,t)}}off(e,t){const n=this.listeners.get(e);n&&(n.delete(t),n.size===0&&this.listeners.delete(e))}once(e,t){const n=i=>{t(i),this.off(e,n)};this.on(e,n)}emit(e,...t){const n=this.listeners.get(e);if(n){const i=t[0];n.forEach(r=>{try{r(i)}catch(o){console.error(`Error in event listener for '${String(e)}':`,o)}})}}removeAllListeners(e){e?this.listeners.delete(e):this.listeners.clear()}}class le{constructor(e,t={emit:()=>{},getBlock:()=>{}}){u(this,"active",!0),u(this,"messenger"),u(this,"events"),u(this,"currentHoveredBlock",null),u(this,"currentSelectedBlock",null),u(this,"overlayButtonHovered",!1),u(this,"resizeObserver",null),u(this,"mutationObserver",null),u(this,"transitionCleanupFunctions",[]),this.messenger=e,this.events=t,this.messenger.listen("craftile.inspector.enable",()=>this.enable()),this.messenger.listen("craftile.inspector.disable",()=>this.disable()),this.messenger.listen("craftile.inspector.overlay-button-enter",this.handleOverlayButtonEnter.bind(this)),this.messenger.listen("craftile.inspector.overlay-button-leave",this.handleOverlayButtonLeave.bind(this)),this.messenger.listen("craftile.editor.select-block",this.handleEditorSelectBlock.bind(this)),this.messenger.listen("craftile.editor.deselect-block",this.handleEditorDeselectBlock.bind(this)),window.addEventListener("scroll",this.handleScroll.bind(this),{passive:!0}),this.setupGlobalEventListeners()}updateTrackedElement(e,t){this.currentHoveredBlock?.dataset.block===e&&(this.currentHoveredBlock=t,this.sendHoveredBlockPosition()),this.currentSelectedBlock?.dataset.block===e&&(this.currentSelectedBlock=t,requestAnimationFrame(()=>{this.sendSelectedBlockPosition(!0)}),this.trackSelectedBlock())}enable(){this.active=!0,document.body.classList.add("craftile-inspector-active"),this.currentSelectedBlock&&this.trackSelectedBlock()}disable(){this.active=!1,document.body.classList.remove("craftile-inspector-active"),this.currentHoveredBlock=null,this.overlayButtonHovered=!1,this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.clearTransitionListeners()}handleOverlayButtonEnter(){this.overlayButtonHovered=!0}handleOverlayButtonLeave(e){this.overlayButtonHovered=!1,this.currentHoveredBlock||this.messenger.send("craftile.preview.block-leave")}handleEditorSelectBlock(e){const t=document.querySelector(`[data-block="${e.blockId}"]`);t&&(this.setSelectedBlock(t),this.sendSelectedBlockPosition(),this.trackSelectedBlock(),t.scrollIntoView({behavior:"smooth",block:"nearest",inline:"nearest"}))}handleEditorDeselectBlock(){const e=this.currentSelectedBlock;this.currentSelectedBlock=null,this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.clearTransitionListeners(),e?.dataset.block&&this.emitBlockDeselect(e.dataset.block,e)}handleScroll(){this.active&&(this.currentSelectedBlock&&this.sendSelectedBlockPosition(),this.currentHoveredBlock&&this.sendHoveredBlockPosition())}setupGlobalEventListeners(){document.addEventListener("mouseover",this.handleGlobalHover.bind(this)),document.addEventListener("mouseout",this.handleGlobalLeave.bind(this)),document.addEventListener("click",this.handleGlobalClick.bind(this),{capture:!0})}handleGlobalHover(e){if(!this.active)return;const t=e.target.closest("[data-block]");t&&(e.stopPropagation(),this.currentHoveredBlock=t,this.sendHoveredBlockPosition())}handleGlobalLeave(e){!this.active||!e.target.closest("[data-block]")||this.overlayButtonHovered||(this.currentHoveredBlock=null,this.messenger.send("craftile.preview.block-leave"))}handleGlobalClick(e){if(this.messenger.send("craftile.preview.click"),!this.active)return;const t=e.target.closest("[data-block]");if(!t||!t.getAttribute("data-block"))return;this.currentSelectedBlock===t||(e.preventDefault(),e.stopImmediatePropagation(),this.setSelectedBlock(t),this.sendSelectedBlockPosition(),this.trackSelectedBlock())}setSelectedBlock(e){const t=this.currentSelectedBlock;t!==e&&(t?.dataset.block&&this.emitBlockDeselect(t.dataset.block,t),this.currentSelectedBlock=e,e.dataset.block&&this.emitBlockSelect(e.dataset.block,e))}createBlockEventPayload(e,t){const n=this.events.getBlock(e);return{blockId:e,...n?{block:n,blockType:n.type}:{},element:t}}emitBlockSelect(e,t){this.events.emit("block.select",this.createBlockEventPayload(e,t))}emitBlockDeselect(e,t){this.events.emit("block.deselect",this.createBlockEventPayload(e,t))}sendHoveredBlockPosition(){const e=this.computeElementPositioning(this.currentHoveredBlock);this.messenger.send("craftile.preview.block-hover",{blockRect:e.rect,parentRect:e.parentRect,scrollTop:e.scrollTop,scrollLeft:e.scrollLeft,blockId:this.currentHoveredBlock.dataset.block,parentFlexDirection:e.parentFlexDirection})}sendSelectedBlockPosition(e=!1){if(!this.currentSelectedBlock)return;const t=this.computeElementPositioning(this.currentSelectedBlock);this.messenger.send(e?"craftile.preview.update-selected-block":"craftile.preview.block-select",{blockRect:t.rect,scrollTop:t.scrollTop,scrollLeft:t.scrollLeft,blockId:this.currentSelectedBlock.dataset.block})}trackSelectedBlock(){if(!this.currentSelectedBlock)return;this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.clearTransitionListeners(),this.resizeObserver=new ResizeObserver(()=>{this.active&&this.currentSelectedBlock&&this.sendSelectedBlockPosition(!0)}),this.resizeObserver.observe(this.currentSelectedBlock),this.mutationObserver=new MutationObserver(()=>{this.active&&this.currentSelectedBlock&&this.sendSelectedBlockPosition(!0)}),this.mutationObserver.observe(this.currentSelectedBlock,{attributes:!0,subtree:!1});let e=this.currentSelectedBlock.parentElement;for(;e&&(this.mutationObserver.observe(e,{childList:!0,subtree:!1}),e!==document.body);)e=e.parentElement;this.trackSelectedBlockTransitions()}clearTransitionListeners(){this.transitionCleanupFunctions.forEach(e=>e()),this.transitionCleanupFunctions=[]}trackSelectedBlockTransitions(){if(!this.currentSelectedBlock)return;const e=()=>{!this.active||!this.currentSelectedBlock?.isConnected||requestAnimationFrame(()=>{this.active&&this.currentSelectedBlock?.isConnected&&this.sendSelectedBlockPosition(!0)})};let t=this.currentSelectedBlock;for(;t;){const n=t,i=r=>{r.target===n&&e()};if(n.addEventListener("transitionend",i),n.addEventListener("transitioncancel",i),this.transitionCleanupFunctions.push(()=>{n.removeEventListener("transitionend",i),n.removeEventListener("transitioncancel",i)}),n===document.body)break;t=n.parentElement}}computeElementPositioning(e){const t=e.getBoundingClientRect(),n=window.pageYOffset||document.documentElement.scrollTop,i=window.pageXOffset||document.documentElement.scrollLeft,r=this.findEldestParentBlock(e),o=r&&r!==e?r.getBoundingClientRect():void 0,l=this.getElementFlexDirection(e.parentElement);return{rect:t,parentRect:o,scrollTop:n,scrollLeft:i,parentFlexDirection:l}}findEldestParentBlock(e){let t=null,n=e.parentElement;for(;n&&n!==document.body;)n.hasAttribute("data-block")&&(t=n),n=n.parentElement;return t}getElementFlexDirection(e){if(!e)return"column";const t=window.getComputedStyle(e),n=t.display.includes("flex")?t.flexDirection:"column";return n==="row"||n==="row-reverse"?"row":"column"}}class ce extends oe{constructor(){super(),u(this,"messenger"),u(this,"blocks",new Map),u(this,"inspector"),this.messenger=se(window.origin),this.inspector=new le(this.messenger,this),this.initialize()}initialize(){window.addEventListener("load",()=>{this.messenger.send("craftile.preview.ready",{}),setTimeout(()=>{this.sendPageData()},0)}),this.messenger.listen("craftile.editor.updates",e=>{this.updateBlocks(e)}),this.messenger.registerFallbackHandler(e=>{const{type:t,payload:n}=e;this.emit(t,n)})}getBlock(e){return this.blocks.get(e)}updateBlocks(e){for(const[t,n]of Object.entries(e.blocks))this.blocks.set(t,n);for(const t of e.changes.removed)this.blocks.delete(t)}sendPageData(){const e=document.getElementById("page-data");if(e)try{const t=JSON.parse(e.textContent||"{}");this.blocks.clear();for(const[n,i]of Object.entries(t.content.blocks||{}))this.blocks.set(n,i);this.messenger.send("craftile.preview.page-data",{pageData:t})}catch(t){console.error("Failed to parse page data:",t)}}}var X=11;function ae(s,e){var t=e.attributes,n,i,r,o,l;if(!(e.nodeType===X||s.nodeType===X)){for(var d=t.length-1;d>=0;d--)n=t[d],i=n.name,r=n.namespaceURI,o=n.value,r?(i=n.localName||i,l=s.getAttributeNS(r,i),l!==o&&(n.prefix==="xmlns"&&(i=n.name),s.setAttributeNS(r,i,o))):(l=s.getAttribute(i),l!==o&&s.setAttribute(i,o));for(var p=s.attributes,b=p.length-1;b>=0;b--)n=p[b],i=n.name,r=n.namespaceURI,r?(i=n.localName||i,e.hasAttributeNS(r,i)||s.removeAttributeNS(r,i)):e.hasAttribute(i)||s.removeAttribute(i)}}var P,de="http://www.w3.org/1999/xhtml",g=typeof document>"u"?void 0:document,he=!!g&&"content"in g.createElement("template"),fe=!!g&&g.createRange&&"createContextualFragment"in g.createRange();function ue(s){var e=g.createElement("template");return e.innerHTML=s,e.content.childNodes[0]}function me(s){P||(P=g.createRange(),P.selectNode(g.body));var e=P.createContextualFragment(s);return e.childNodes[0]}function ve(s){var e=g.createElement("body");return e.innerHTML=s,e.childNodes[0]}function pe(s){return s=s.trim(),he?ue(s):fe?me(s):ve(s)}function N(s,e){var t=s.nodeName,n=e.nodeName,i,r;return t===n?!0:(i=t.charCodeAt(0),r=n.charCodeAt(0),i<=90&&r>=97?t===n.toUpperCase():r<=90&&i>=97?n===t.toUpperCase():!1)}function ge(s,e){return!e||e===de?g.createElement(s):g.createElementNS(e,s)}function be(s,e){for(var t=s.firstChild;t;){var n=t.nextSibling;e.appendChild(t),t=n}return e}function z(s,e,t){s[t]!==e[t]&&(s[t]=e[t],s[t]?s.setAttribute(t,""):s.removeAttribute(t))}var Y={OPTION:function(s,e){var t=s.parentNode;if(t){var n=t.nodeName.toUpperCase();n==="OPTGROUP"&&(t=t.parentNode,n=t&&t.nodeName.toUpperCase()),n==="SELECT"&&!t.hasAttribute("multiple")&&(s.hasAttribute("selected")&&!e.selected&&(s.setAttribute("selected","selected"),s.removeAttribute("selected")),t.selectedIndex=-1)}z(s,e,"selected")},INPUT:function(s,e){z(s,e,"checked"),z(s,e,"disabled"),s.value!==e.value&&(s.value=e.value),e.hasAttribute("value")||s.removeAttribute("value")},TEXTAREA:function(s,e){var t=e.value;s.value!==t&&(s.value=t);var n=s.firstChild;if(n){var i=n.nodeValue;if(i==t||!t&&i==s.placeholder)return;n.nodeValue=t}},SELECT:function(s,e){if(!e.hasAttribute("multiple")){for(var t=-1,n=0,i=s.firstChild,r,o;i;)if(o=i.nodeName&&i.nodeName.toUpperCase(),o==="OPTGROUP")r=i,i=r.firstChild,i||(i=r.nextSibling,r=null);else{if(o==="OPTION"){if(i.hasAttribute("selected")){t=n;break}n++}i=i.nextSibling,!i&&r&&(i=r.nextSibling,r=null)}s.selectedIndex=t}}},L=1,J=11,Q=3,Z=8;function E(){}function ke(s){if(s)return s.getAttribute&&s.getAttribute("id")||s.id}function Ce(s){return function(t,n,i){if(i||(i={}),typeof n=="string")if(t.nodeName==="#document"||t.nodeName==="HTML"||t.nodeName==="BODY"){var r=n;n=g.createElement("html"),n.innerHTML=r}else n=pe(n);else n.nodeType===J&&(n=n.firstElementChild);var o=i.getNodeKey||ke,l=i.onBeforeNodeAdded||E,d=i.onNodeAdded||E,p=i.onBeforeElUpdated||E,b=i.onElUpdated||E,I=i.onBeforeNodeDiscarded||E,A=i.onNodeDiscarded||E,Se=i.onBeforeElChildrenUpdated||E,Be=i.skipFromChildren||E,ee=i.addChild||function(c,a){return c.appendChild(a)},G=i.childrenOnly===!0,T=Object.create(null),H=[];function M(c){H.push(c)}function te(c,a){if(c.nodeType===L)for(var m=c.firstChild;m;){var h=void 0;a&&(h=o(m))?M(h):(A(m),m.firstChild&&te(m,a)),m=m.nextSibling}}function D(c,a,m){I(c)!==!1&&(a&&a.removeChild(c),A(c),te(c,m))}function V(c){if(c.nodeType===L||c.nodeType===J)for(var a=c.firstChild;a;){var m=o(a);m&&(T[m]=a),V(a),a=a.nextSibling}}V(t);function W(c){d(c);for(var a=c.firstChild;a;){var m=a.nextSibling,h=o(a);if(h){var f=T[h];f&&N(a,f)?(a.parentNode.replaceChild(f,a),R(f,a)):W(a)}else W(a);a=m}}function we(c,a,m){for(;a;){var h=a.nextSibling;(m=o(a))?M(m):D(a,c,!0),a=h}}function R(c,a,m){var h=o(a);if(h&&delete T[h],!m){var f=p(c,a);if(f===!1||(f instanceof HTMLElement&&(c=f,V(c)),s(c,a),b(c),Se(c,a)===!1))return}c.nodeName!=="TEXTAREA"?ye(c,a):Y.TEXTAREA(c,a)}function ye(c,a){var m=Be(c,a),h=a.firstChild,f=c.firstChild,x,C,O,U,S;e:for(;h;){for(U=h.nextSibling,x=o(h);!m&&f;){if(O=f.nextSibling,h.isSameNode&&h.isSameNode(f)){h=U,f=O;continue e}C=o(f);var $=f.nodeType,B=void 0;if($===h.nodeType&&($===L?(x?x!==C&&((S=T[x])?O===S?B=!1:(c.insertBefore(S,f),C?M(C):D(f,c,!0),f=S,C=o(f)):B=!1):C&&(B=!1),B=B!==!1&&N(f,h),B&&R(f,h)):($===Q||$==Z)&&(B=!0,f.nodeValue!==h.nodeValue&&(f.nodeValue=h.nodeValue))),B){h=U,f=O;continue e}C?M(C):D(f,c,!0),f=O}if(x&&(S=T[x])&&N(S,h))m||ee(c,S),R(S,h);else{var K=l(h);K!==!1&&(K&&(h=K),h.actualize&&(h=h.actualize(c.ownerDocument||g)),ee(c,h),W(h))}h=U,f=O}we(c,f,C);var ie=Y[c.nodeName];ie&&ie(c,a)}var v=t,F=v.nodeType,ne=n.nodeType;if(!G){if(F===L)ne===L?N(t,n)||(A(t),v=be(t,ge(n.nodeName,n.namespaceURI))):v=n;else if(F===Q||F===Z){if(ne===F)return v.nodeValue!==n.nodeValue&&(v.nodeValue=n.nodeValue),v;v=n}}if(v===n)A(t);else{if(n.isSameNode&&n.isSameNode(v))return;if(R(v,n,G),H)for(var j=0,Te=H.length;j<Te;j++){var q=T[H[j]];q&&D(q,q.parentNode,!1)}}return!G&&v!==t&&t.parentNode&&(v.actualize&&(v=v.actualize(t.ownerDocument||g)),t.parentNode.replaceChild(v,t)),v}}var Ee=Ce(ae);class _{constructor(e,t){w(this,"previewClient");w(this,"morphdomOptions");w(this,"elementCache",new Map);w(this,"regionCommentsCache",new Map);w(this,"childrenCommentsCache",new Map);w(this,"pendingScripts",new Set);w(this,"scriptExecutionCount",{total:0,completed:0,failed:0});this.previewClient=e||new ce,this.morphdomOptions=t?.morphdom||{},this.previewClient.on("updates.effects",this.handleEffects.bind(this)),this.previewClient.on("craftile.editor.updates",this.handleDirectUpdates.bind(this)),this.cacheRegionComments(),this.cacheChildrenComments()}static init(e,t){return new _(e,t)}getElementCached(e){if(this.elementCache.has(e)){const n=this.elementCache.get(e);if(n.isConnected)return n;this.elementCache.delete(e)}const t=document.querySelector(`[data-block="${e}"]`);return t&&this.elementCache.set(e,t),t}cacheRegionComments(){const e=document.createTreeWalker(document.body,NodeFilter.SHOW_COMMENT,null);let t;const n=new Map;for(;t=e.nextNode();){const i=t.textContent?.trim();if(i){if(i.startsWith("BEGIN region: ")){const r=i.substring(14);n.set(r,t)}else if(i.startsWith("END region: ")){const r=i.substring(12),o=n.get(r);o&&(this.regionCommentsCache.set(r,{begin:o,end:t}),n.delete(r))}}}}cacheChildrenComments(){this.childrenCommentsCache.clear();const e=document.createTreeWalker(document.body,NodeFilter.SHOW_COMMENT,null);let t;const n=new Map;for(;t=e.nextNode();){const i=t.textContent?.trim();if(i){if(i.startsWith("BEGIN children: ")){const r=i.substring(16);n.set(r,t)}else if(i.startsWith("END children: ")){const r=i.substring(14),o=n.get(r);o&&(this.childrenCommentsCache.set(r,{begin:o,end:t}),n.delete(r))}}}}invalidateCache(e){[...e.updated,...e.removed].forEach(t=>{this.elementCache.delete(t),this.childrenCommentsCache.delete(t)})}handleEffects(e){const{effects:t,blocks:n,regions:i,changes:r}=e;t&&(this.invalidateCache(r),t.html&&this.handleHtmlEffects(t.html,{blocks:n,regions:i,changes:r}),t.css&&this.handleCssEffects(t.css),t.js&&this.handleJsEffects(t.js))}handleCssEffects(e){for(const t of e)this.injectStyleElement(t)}injectStyleElement(e){const t=document.createElement("div");t.innerHTML=e;const n=t.firstElementChild;if(!n||n.tagName!=="STYLE"&&n.tagName!=="LINK"){console.warn("Invalid CSS element provided:",e);return}const i=n.id;if(i){const r=document.getElementById(i);if(r&&(r.tagName==="STYLE"||r.tagName==="LINK")){r.parentNode?.replaceChild(n,r);return}}if(n.tagName==="STYLE"&&!i){const r=n.textContent?.trim();if(r){const o=document.querySelectorAll("style:not([id])");for(const l of o)if(l.textContent?.trim()===r)return}}if(n.tagName==="LINK"&&!i){const r=n.getAttribute("href"),o=n.getAttribute("rel");if(r){const l=document.querySelectorAll("link:not([id])");for(const d of l)if(d.getAttribute("href")===r&&d.getAttribute("rel")===o)return}}document.head.appendChild(n)}handleJsEffects(e){this.pendingScripts.clear(),this.scriptExecutionCount={total:0,completed:0,failed:0};const t=e.filter(n=>n?.trim());if(this.scriptExecutionCount.total=t.length,t.length===0){this.emitScriptExecutionComplete();return}for(const n of t)this.injectScriptElement(n)}injectScriptElement(e){const t=document.createElement("div");t.innerHTML=e;const n=t.firstElementChild;if(!n||n.tagName!=="SCRIPT"){console.warn("Invalid script element provided:",e),this.onScriptCompleted(!1);return}const i=n.id;if(i){const r=document.getElementById(i);if(r&&r.tagName==="SCRIPT"){this.pendingScripts.delete(r),r.parentNode?.replaceChild(n,r),this.trackScriptExecution(n);return}}if(!n.src&&!i){const r=n.textContent?.trim();if(r){const o=document.querySelectorAll("script:not([src]):not([id])");for(const l of o)if(l.textContent?.trim()===r){this.onScriptCompleted(!0);return}}}if(n.src&&!i){const r=n.src,o=document.querySelectorAll("script[src]:not([id])");for(const l of o)if(l.src===r){this.onScriptCompleted(!0);return}}document.head.appendChild(n),this.trackScriptExecution(n)}trackScriptExecution(e){if(e.src){this.pendingScripts.add(e);const t=()=>{this.pendingScripts.delete(e),this.onScriptCompleted(!0),e.removeEventListener("load",t),e.removeEventListener("error",n)},n=()=>{this.pendingScripts.delete(e),this.onScriptCompleted(!1),e.removeEventListener("load",t),e.removeEventListener("error",n)};e.addEventListener("load",t),e.addEventListener("error",n)}else this.onScriptCompleted(!0)}onScriptCompleted(e){e?this.scriptExecutionCount.completed++:this.scriptExecutionCount.failed++,this.scriptExecutionCount.completed+this.scriptExecutionCount.failed>=this.scriptExecutionCount.total&&this.emitScriptExecutionComplete()}emitScriptExecutionComplete(){this.previewClient.emit("scripts.execution.complete",{total:this.scriptExecutionCount.total,completed:this.scriptExecutionCount.completed,failed:this.scriptExecutionCount.failed,success:this.scriptExecutionCount.failed===0})}handleDirectUpdates(e){const{changes:t}=e;t.moved&&this.handleMoves(e),t.updated.length>0&&this.handleDisabledBlocks(e),t.removed.length>0&&this.handleRemoves(e)}handleMoves(e){const{blocks:t,changes:n}=e;for(const[i,r]of Object.entries(e.changes.moved)){if(r?.toParent&&n.updated?.includes(r?.toParent))continue;if(!this.isValidMoveInstruction(r)){console.warn(`Invalid move instruction for block ${i}:`,r);continue}const o=t[i],l=n.positions?.[i];this.moveBlockUsingDOM(o,r,l)}}handleDisabledBlocks(e){const{blocks:t,changes:n}=e;for(const i of n.updated){const r=t[i];if(!r)continue;const l=!!this.getElementCached(i);r.disabled&&l?this.removeBlock(r.id,r):r.disabled}}handleRemoves(e){const{blocks:t,changes:n}=e;for(const i of n.removed)this.removeBlock(i,t[i])}handleHtmlEffects(e,t){const{blocks:n,changes:i}=t,r=new Set(Object.keys(e));for(const[o,l]of Object.entries(e)){if(!l)continue;const d=n[o];if(!d){console.warn(`Block data not found for ${o}`);continue}if(d.parentId&&r.has(d.parentId))continue;if(d.disabled){console.debug(`Skipping disabled block ${o}`);continue}if(!!this.getElementCached(o))this.updateBlockHtml(d,l);else{const I=i.positions?.[o];if(!I){console.warn(`No position info for block ${o}`);continue}this.insertBlock(d,l,I)}}this.cacheChildrenComments()}isValidMoveInstruction(e){const t=!!(e.toParent||e.toRegion),n=e.toIndex===void 0||e.toIndex>=0;return t&&n}removeBlock(e,t){const n=this.getElementCached(e);if(n){const i={blockId:e,...t?{blockType:t.type,block:t}:{},element:n};this.previewClient.emit("block.remove.before",{...i}),n.remove(),this.elementCache.delete(e),this.previewClient.emit("block.remove.after",{...i})}else console.warn(`Block ${e} not found for removal`)}moveBlockUsingDOM(e,t,n){const i=this.getElementCached(e.id),{toParent:r,toRegion:o,toIndex:l}=t;if(!i){console.warn(`Block element ${e.id} not found for move operation`);return}this.previewClient.emit("block.move.before",{blockId:e.id,blockType:e.type,block:e,element:i,toParent:r,toRegion:o,toIndex:l});const d=n?.afterId,p=n?.beforeId;if(r){const b=this.getElementCached(r);if(!b){console.error(`Parent element ${r} not found for move operation`);return}this.insertElementInParent(i,b,d,p)}else if(o){const b=this.findRegionInsertionPoint(o,d,p);if(!b){console.error(`Failed to find insertion point for region: ${o}`);return}b.parent.insertBefore(i,b.before)}this.previewClient.emit("block.move.after",{blockId:e.id,blockType:e.type,block:e,element:i,toParent:r,toRegion:o,toIndex:l})}insertBlock(e,t,n){if(this.getElementCached(e.id))return;this.previewClient.emit("block.insert.before",{blockId:e.id,blockType:e.type,block:e,html:t,positionInfo:n});const i=this.parseHtmlElement(t,e.id);if(!i)return;const{parentId:r,regionId:o,afterId:l,beforeId:d}=n;if(r){const p=this.getElementCached(r);if(!p){console.error(`Parent element ${r} not found for block ${e.id}`);return}this.insertElementInParent(i,p,l,d)}else if(o){const p=this.findRegionInsertionPoint(o,l,d);if(!p){console.error(`Failed to find insertion point for region: ${o}`);return}p.parent.insertBefore(i,p.before)}else console.warn(`No parent or region specified for block ${e.id}, inserting into body`),document.body.appendChild(i);this.elementCache.set(e.id,i),i.scrollIntoView({behavior:"smooth",block:"nearest",inline:"nearest"}),this.previewClient.emit("block.insert.after",{blockId:e.id,blockType:e.type,block:e,element:i,html:t,positionInfo:n})}updateBlockHtml(e,t){if(!t){console.warn(`No HTML provided for block ${e.id}`);return}const n=this.getElementCached(e.id);if(!n){console.warn(`Block element ${e.id} not found for HTML update`);return}this.previewClient.emit("block.update.before",{blockId:e.id,blockType:e.type,block:e,element:n,html:t}),Ee(n,t,this.morphdomOptions),this.elementCache.delete(e.id);const i=this.getElementCached(e.id);if(!i){console.error(`Block element ${e.id} not found after morphdom update`);return}i!==n&&this.previewClient.inspector.updateTrackedElement(e.id,i),this.previewClient.emit("block.update.after",{blockId:e.id,blockType:e.type,block:e,element:i,html:t})}insertElementInParent(e,t,n,i){const r=t.getAttribute("data-block"),o=r?this.childrenCommentsCache.get(r):null;if(o){let l=null;if(i)l=this.getElementCached(i);else if(n){const d=this.getElementCached(n);d&&d.nextSibling&&(l=d.nextSibling)}l||(l=o.end),o.begin.parentNode.insertBefore(e,l)}else{let l=null;if(i)l=this.getElementCached(i);else if(n){const d=this.getElementCached(n);d&&(l=d.nextElementSibling)}t.insertBefore(e,l)}}findRegionInsertionPoint(e,t,n){const i=this.regionCommentsCache.get(e);if(!i)return console.error(`Region comments not found for region: ${e}`),null;const{begin:r,end:o}=i;let l=null;if(n){const d=this.getElementCached(n);d&&(l=d)}else if(t){const d=this.getElementCached(t);d&&d.nextSibling&&(l=d.nextSibling)}return l||(l=o),{parent:r.parentNode,before:l}}parseHtmlElement(e,t){if(!e.trim())return console.error(`Empty HTML provided for block ${t}`),null;const n=document.createElement("div");n.innerHTML=e;const i=n.firstElementChild;return i||(console.error(`Invalid HTML for block ${t}: no element found`),null)}}return _})();
1
+ var Te=Object.defineProperty;var Oe=(y,k,u)=>k in y?Te(y,k,{enumerable:!0,configurable:!0,writable:!0,value:u}):y[k]=u;var w=(y,k,u)=>Oe(y,typeof k!="symbol"?k+"":k,u);var HtmlPreviewClient=(function(){"use strict";var y=Object.defineProperty,k=(s,e,t)=>e in s?y(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t,u=(s,e,t)=>k(s,typeof e!="symbol"?e+"":e,t);class re{constructor(e,t="*"){u(this,"handlers",new Map),u(this,"targetWindow"),u(this,"targetOrigin"),u(this,"fallbackHandler"),this.targetWindow=e,this.targetOrigin=t,window.addEventListener("message",this.handleMessage.bind(this))}handleMessage(e){const t=e.data;if(!t.type)return;const n=this.handlers.get(t.type);n?n.forEach(i=>i(t.payload,e)):this.fallbackHandler&&this.fallbackHandler(e.data,e)}send(e,t){const n={type:e,payload:t};this.targetWindow.postMessage(n,this.targetOrigin)}listen(e,t){return this.handlers.has(e)||this.handlers.set(e,[]),this.handlers.get(e).push(t),()=>{const n=this.handlers.get(e);if(n){const i=n.indexOf(t);i>-1&&n.splice(i,1)}}}registerFallbackHandler(e){this.fallbackHandler=e}}function se(s="*"){if(window.parent===window)throw new Error("Not inside an iframe");return new re(window.parent,s)}class oe{constructor(){u(this,"listeners",new Map)}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>{this.off(e,t)}}off(e,t){const n=this.listeners.get(e);n&&(n.delete(t),n.size===0&&this.listeners.delete(e))}once(e,t){const n=i=>{t(i),this.off(e,n)};this.on(e,n)}emit(e,...t){const n=this.listeners.get(e);if(n){const i=t[0];n.forEach(r=>{try{r(i)}catch(o){console.error(`Error in event listener for '${String(e)}':`,o)}})}}removeAllListeners(e){e?this.listeners.delete(e):this.listeners.clear()}}class le{constructor(e,t={emit:()=>{},getBlock:()=>{}}){u(this,"active",!0),u(this,"messenger"),u(this,"events"),u(this,"currentHoveredBlock",null),u(this,"currentSelectedBlock",null),u(this,"overlayButtonHovered",!1),u(this,"resizeObserver",null),u(this,"mutationObserver",null),u(this,"transitionCleanupFunctions",[]),this.messenger=e,this.events=t,this.messenger.listen("craftile.inspector.enable",()=>this.enable()),this.messenger.listen("craftile.inspector.disable",()=>this.disable()),this.messenger.listen("craftile.inspector.overlay-button-enter",this.handleOverlayButtonEnter.bind(this)),this.messenger.listen("craftile.inspector.overlay-button-leave",this.handleOverlayButtonLeave.bind(this)),this.messenger.listen("craftile.editor.select-block",this.handleEditorSelectBlock.bind(this)),this.messenger.listen("craftile.editor.deselect-block",this.handleEditorDeselectBlock.bind(this)),window.addEventListener("scroll",this.handleScroll.bind(this),{passive:!0}),this.setupGlobalEventListeners()}updateTrackedElement(e,t){this.currentHoveredBlock?.dataset.block===e&&(this.currentHoveredBlock=t,this.sendHoveredBlockPosition()),this.currentSelectedBlock?.dataset.block===e&&(this.currentSelectedBlock=t,requestAnimationFrame(()=>{this.sendSelectedBlockPosition(!0)}),this.trackSelectedBlock())}enable(){this.active=!0,document.body.classList.add("craftile-inspector-active"),this.currentSelectedBlock&&this.trackSelectedBlock()}disable(){this.active=!1,document.body.classList.remove("craftile-inspector-active"),this.currentHoveredBlock=null,this.overlayButtonHovered=!1,this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.clearTransitionListeners()}handleOverlayButtonEnter(){this.overlayButtonHovered=!0}handleOverlayButtonLeave(e){this.overlayButtonHovered=!1,this.currentHoveredBlock||this.messenger.send("craftile.preview.block-leave")}handleEditorSelectBlock(e){const t=document.querySelector(`[data-block="${e.blockId}"]`);t&&(this.setSelectedBlock(t),this.sendSelectedBlockPosition(),this.trackSelectedBlock(),t.scrollIntoView({behavior:"smooth",block:"nearest",inline:"nearest"}))}handleEditorDeselectBlock(){const e=this.currentSelectedBlock;this.currentSelectedBlock=null,this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.clearTransitionListeners(),e?.dataset.block&&this.emitBlockDeselect(e.dataset.block,e)}handleScroll(){this.active&&(this.currentSelectedBlock&&this.sendSelectedBlockPosition(),this.currentHoveredBlock&&this.sendHoveredBlockPosition())}setupGlobalEventListeners(){document.addEventListener("mouseover",this.handleGlobalHover.bind(this)),document.addEventListener("mouseout",this.handleGlobalLeave.bind(this)),document.addEventListener("click",this.handleGlobalClick.bind(this),{capture:!0})}handleGlobalHover(e){if(!this.active)return;const t=e.target.closest("[data-block]");t&&(e.stopPropagation(),this.currentHoveredBlock=t,this.sendHoveredBlockPosition())}handleGlobalLeave(e){!this.active||!e.target.closest("[data-block]")||this.overlayButtonHovered||(this.currentHoveredBlock=null,this.messenger.send("craftile.preview.block-leave"))}handleGlobalClick(e){if(this.messenger.send("craftile.preview.click"),!this.active)return;const t=e.target.closest("[data-block]");if(!t||!t.getAttribute("data-block"))return;this.currentSelectedBlock===t||(e.preventDefault(),e.stopImmediatePropagation(),this.setSelectedBlock(t),this.sendSelectedBlockPosition(),this.trackSelectedBlock())}setSelectedBlock(e){const t=this.currentSelectedBlock;t!==e&&(t?.dataset.block&&this.emitBlockDeselect(t.dataset.block,t),this.currentSelectedBlock=e,e.dataset.block&&this.emitBlockSelect(e.dataset.block,e))}createBlockEventPayload(e,t){const n=this.events.getBlock(e);return{blockId:e,...n?{block:n,blockType:n.type}:{},element:t}}emitBlockSelect(e,t){this.events.emit("block.select",this.createBlockEventPayload(e,t))}emitBlockDeselect(e,t){this.events.emit("block.deselect",this.createBlockEventPayload(e,t))}sendHoveredBlockPosition(){const e=this.computeElementPositioning(this.currentHoveredBlock);this.messenger.send("craftile.preview.block-hover",{blockRect:e.rect,parentRect:e.parentRect,scrollTop:e.scrollTop,scrollLeft:e.scrollLeft,blockId:this.currentHoveredBlock.dataset.block,parentFlexDirection:e.parentFlexDirection})}sendSelectedBlockPosition(e=!1){if(!this.currentSelectedBlock)return;const t=this.computeElementPositioning(this.currentSelectedBlock);this.messenger.send(e?"craftile.preview.update-selected-block":"craftile.preview.block-select",{blockRect:t.rect,scrollTop:t.scrollTop,scrollLeft:t.scrollLeft,blockId:this.currentSelectedBlock.dataset.block})}trackSelectedBlock(){if(!this.currentSelectedBlock)return;this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.clearTransitionListeners(),this.resizeObserver=new ResizeObserver(()=>{this.active&&this.currentSelectedBlock&&this.sendSelectedBlockPosition(!0)}),this.resizeObserver.observe(this.currentSelectedBlock),this.mutationObserver=new MutationObserver(()=>{this.active&&this.currentSelectedBlock&&this.sendSelectedBlockPosition(!0)}),this.mutationObserver.observe(this.currentSelectedBlock,{attributes:!0,subtree:!1});let e=this.currentSelectedBlock.parentElement;for(;e&&(this.mutationObserver.observe(e,{childList:!0,subtree:!1}),e!==document.body);)e=e.parentElement;this.trackSelectedBlockTransitions()}clearTransitionListeners(){this.transitionCleanupFunctions.forEach(e=>e()),this.transitionCleanupFunctions=[]}trackSelectedBlockTransitions(){if(!this.currentSelectedBlock)return;const e=()=>{!this.active||!this.currentSelectedBlock?.isConnected||requestAnimationFrame(()=>{this.active&&this.currentSelectedBlock?.isConnected&&this.sendSelectedBlockPosition(!0)})};let t=this.currentSelectedBlock;for(;t;){const n=t,i=r=>{r.target===n&&e()};if(n.addEventListener("transitionend",i),n.addEventListener("transitioncancel",i),this.transitionCleanupFunctions.push(()=>{n.removeEventListener("transitionend",i),n.removeEventListener("transitioncancel",i)}),n===document.body)break;t=n.parentElement}}computeElementPositioning(e){const t=e.getBoundingClientRect(),n=window.pageYOffset||document.documentElement.scrollTop,i=window.pageXOffset||document.documentElement.scrollLeft,r=this.findEldestParentBlock(e),o=r&&r!==e?r.getBoundingClientRect():void 0,l=this.getElementFlexDirection(e.parentElement);return{rect:t,parentRect:o,scrollTop:n,scrollLeft:i,parentFlexDirection:l}}findEldestParentBlock(e){let t=null,n=e.parentElement;for(;n&&n!==document.body;)n.hasAttribute("data-block")&&(t=n),n=n.parentElement;return t}getElementFlexDirection(e){if(!e)return"column";const t=window.getComputedStyle(e),n=t.display.includes("flex")?t.flexDirection:"column";return n==="row"||n==="row-reverse"?"row":"column"}}class ce extends oe{constructor(){super(),u(this,"messenger"),u(this,"blocks",new Map),u(this,"inspector"),this.messenger=se(window.origin),this.inspector=new le(this.messenger,this),this.initialize()}initialize(){window.addEventListener("load",()=>{this.messenger.send("craftile.preview.ready",{}),setTimeout(()=>{this.sendPageData()},0)}),this.messenger.listen("craftile.editor.updates",e=>{this.updateBlocks(e),this.emit("craftile.editor.updates",e)}),this.messenger.registerFallbackHandler(e=>{const{type:t,payload:n}=e;this.emit(t,n)})}getBlock(e){return this.blocks.get(e)}updateBlocks(e){for(const[t,n]of Object.entries(e.blocks))this.blocks.set(t,n);for(const t of e.changes.removed)this.blocks.delete(t)}sendPageData(){const e=document.getElementById("page-data");if(e)try{const t=JSON.parse(e.textContent||"{}");this.blocks.clear();for(const[n,i]of Object.entries(t.content.blocks||{}))this.blocks.set(n,i);this.messenger.send("craftile.preview.page-data",{pageData:t})}catch(t){console.error("Failed to parse page data:",t)}}}var X=11;function ae(s,e){var t=e.attributes,n,i,r,o,l;if(!(e.nodeType===X||s.nodeType===X)){for(var d=t.length-1;d>=0;d--)n=t[d],i=n.name,r=n.namespaceURI,o=n.value,r?(i=n.localName||i,l=s.getAttributeNS(r,i),l!==o&&(n.prefix==="xmlns"&&(i=n.name),s.setAttributeNS(r,i,o))):(l=s.getAttribute(i),l!==o&&s.setAttribute(i,o));for(var p=s.attributes,g=p.length-1;g>=0;g--)n=p[g],i=n.name,r=n.namespaceURI,r?(i=n.localName||i,e.hasAttributeNS(r,i)||s.removeAttributeNS(r,i)):e.hasAttribute(i)||s.removeAttribute(i)}}var P,de="http://www.w3.org/1999/xhtml",b=typeof document>"u"?void 0:document,he=!!b&&"content"in b.createElement("template"),fe=!!b&&b.createRange&&"createContextualFragment"in b.createRange();function ue(s){var e=b.createElement("template");return e.innerHTML=s,e.content.childNodes[0]}function me(s){P||(P=b.createRange(),P.selectNode(b.body));var e=P.createContextualFragment(s);return e.childNodes[0]}function ve(s){var e=b.createElement("body");return e.innerHTML=s,e.childNodes[0]}function pe(s){return s=s.trim(),he?ue(s):fe?me(s):ve(s)}function N(s,e){var t=s.nodeName,n=e.nodeName,i,r;return t===n?!0:(i=t.charCodeAt(0),r=n.charCodeAt(0),i<=90&&r>=97?t===n.toUpperCase():r<=90&&i>=97?n===t.toUpperCase():!1)}function be(s,e){return!e||e===de?b.createElement(s):b.createElementNS(e,s)}function ge(s,e){for(var t=s.firstChild;t;){var n=t.nextSibling;e.appendChild(t),t=n}return e}function z(s,e,t){s[t]!==e[t]&&(s[t]=e[t],s[t]?s.setAttribute(t,""):s.removeAttribute(t))}var Y={OPTION:function(s,e){var t=s.parentNode;if(t){var n=t.nodeName.toUpperCase();n==="OPTGROUP"&&(t=t.parentNode,n=t&&t.nodeName.toUpperCase()),n==="SELECT"&&!t.hasAttribute("multiple")&&(s.hasAttribute("selected")&&!e.selected&&(s.setAttribute("selected","selected"),s.removeAttribute("selected")),t.selectedIndex=-1)}z(s,e,"selected")},INPUT:function(s,e){z(s,e,"checked"),z(s,e,"disabled"),s.value!==e.value&&(s.value=e.value),e.hasAttribute("value")||s.removeAttribute("value")},TEXTAREA:function(s,e){var t=e.value;s.value!==t&&(s.value=t);var n=s.firstChild;if(n){var i=n.nodeValue;if(i==t||!t&&i==s.placeholder)return;n.nodeValue=t}},SELECT:function(s,e){if(!e.hasAttribute("multiple")){for(var t=-1,n=0,i=s.firstChild,r,o;i;)if(o=i.nodeName&&i.nodeName.toUpperCase(),o==="OPTGROUP")r=i,i=r.firstChild,i||(i=r.nextSibling,r=null);else{if(o==="OPTION"){if(i.hasAttribute("selected")){t=n;break}n++}i=i.nextSibling,!i&&r&&(i=r.nextSibling,r=null)}s.selectedIndex=t}}},L=1,J=11,Q=3,Z=8;function E(){}function ke(s){if(s)return s.getAttribute&&s.getAttribute("id")||s.id}function Ce(s){return function(t,n,i){if(i||(i={}),typeof n=="string")if(t.nodeName==="#document"||t.nodeName==="HTML"||t.nodeName==="BODY"){var r=n;n=b.createElement("html"),n.innerHTML=r}else n=pe(n);else n.nodeType===J&&(n=n.firstElementChild);var o=i.getNodeKey||ke,l=i.onBeforeNodeAdded||E,d=i.onNodeAdded||E,p=i.onBeforeElUpdated||E,g=i.onElUpdated||E,A=i.onBeforeNodeDiscarded||E,I=i.onNodeDiscarded||E,Se=i.onBeforeElChildrenUpdated||E,Be=i.skipFromChildren||E,ee=i.addChild||function(c,a){return c.appendChild(a)},G=i.childrenOnly===!0,x=Object.create(null),H=[];function M(c){H.push(c)}function te(c,a){if(c.nodeType===L)for(var m=c.firstChild;m;){var h=void 0;a&&(h=o(m))?M(h):(I(m),m.firstChild&&te(m,a)),m=m.nextSibling}}function D(c,a,m){A(c)!==!1&&(a&&a.removeChild(c),I(c),te(c,m))}function V(c){if(c.nodeType===L||c.nodeType===J)for(var a=c.firstChild;a;){var m=o(a);m&&(x[m]=a),V(a),a=a.nextSibling}}V(t);function W(c){d(c);for(var a=c.firstChild;a;){var m=a.nextSibling,h=o(a);if(h){var f=x[h];f&&N(a,f)?(a.parentNode.replaceChild(f,a),R(f,a)):W(a)}else W(a);a=m}}function we(c,a,m){for(;a;){var h=a.nextSibling;(m=o(a))?M(m):D(a,c,!0),a=h}}function R(c,a,m){var h=o(a);if(h&&delete x[h],!m){var f=p(c,a);if(f===!1||(f instanceof HTMLElement&&(c=f,V(c)),s(c,a),g(c),Se(c,a)===!1))return}c.nodeName!=="TEXTAREA"?ye(c,a):Y.TEXTAREA(c,a)}function ye(c,a){var m=Be(c,a),h=a.firstChild,f=c.firstChild,T,C,O,U,S;e:for(;h;){for(U=h.nextSibling,T=o(h);!m&&f;){if(O=f.nextSibling,h.isSameNode&&h.isSameNode(f)){h=U,f=O;continue e}C=o(f);var $=f.nodeType,B=void 0;if($===h.nodeType&&($===L?(T?T!==C&&((S=x[T])?O===S?B=!1:(c.insertBefore(S,f),C?M(C):D(f,c,!0),f=S,C=o(f)):B=!1):C&&(B=!1),B=B!==!1&&N(f,h),B&&R(f,h)):($===Q||$==Z)&&(B=!0,f.nodeValue!==h.nodeValue&&(f.nodeValue=h.nodeValue))),B){h=U,f=O;continue e}C?M(C):D(f,c,!0),f=O}if(T&&(S=x[T])&&N(S,h))m||ee(c,S),R(S,h);else{var K=l(h);K!==!1&&(K&&(h=K),h.actualize&&(h=h.actualize(c.ownerDocument||b)),ee(c,h),W(h))}h=U,f=O}we(c,f,C);var ie=Y[c.nodeName];ie&&ie(c,a)}var v=t,F=v.nodeType,ne=n.nodeType;if(!G){if(F===L)ne===L?N(t,n)||(I(t),v=ge(t,be(n.nodeName,n.namespaceURI))):v=n;else if(F===Q||F===Z){if(ne===F)return v.nodeValue!==n.nodeValue&&(v.nodeValue=n.nodeValue),v;v=n}}if(v===n)I(t);else{if(n.isSameNode&&n.isSameNode(v))return;if(R(v,n,G),H)for(var j=0,xe=H.length;j<xe;j++){var q=x[H[j]];q&&D(q,q.parentNode,!1)}}return!G&&v!==t&&t.parentNode&&(v.actualize&&(v=v.actualize(t.ownerDocument||b)),t.parentNode.replaceChild(v,t)),v}}var Ee=Ce(ae);class _{constructor(e,t){w(this,"previewClient");w(this,"morphdomOptions");w(this,"elementCache",new Map);w(this,"regionCommentsCache",new Map);w(this,"childrenCommentsCache",new Map);w(this,"pendingScripts",new Set);w(this,"scriptExecutionCount",{total:0,completed:0,failed:0});this.previewClient=e||new ce,this.morphdomOptions=t?.morphdom||{},this.previewClient.on("updates.effects",this.handleEffects.bind(this)),this.previewClient.on("craftile.editor.updates",this.handleDirectUpdates.bind(this)),this.cacheRegionComments(),this.cacheChildrenComments()}static init(e,t){return new _(e,t)}getElementCached(e){if(this.elementCache.has(e)){const n=this.elementCache.get(e);if(n.isConnected)return n;this.elementCache.delete(e)}const t=document.querySelector(`[data-block="${e}"]`);return t&&this.elementCache.set(e,t),t}cacheRegionComments(){const e=document.createTreeWalker(document.body,NodeFilter.SHOW_COMMENT,null);let t;const n=new Map;for(;t=e.nextNode();){const i=t.textContent?.trim();if(i){if(i.startsWith("BEGIN region: ")){const r=i.substring(14);n.set(r,t)}else if(i.startsWith("END region: ")){const r=i.substring(12),o=n.get(r);o&&(this.regionCommentsCache.set(r,{begin:o,end:t}),n.delete(r))}}}}cacheChildrenComments(){this.childrenCommentsCache.clear();const e=document.createTreeWalker(document.body,NodeFilter.SHOW_COMMENT,null);let t;const n=new Map;for(;t=e.nextNode();){const i=t.textContent?.trim();if(i){if(i.startsWith("BEGIN children: ")){const r=i.substring(16);n.set(r,t)}else if(i.startsWith("END children: ")){const r=i.substring(14),o=n.get(r);o&&(this.childrenCommentsCache.set(r,{begin:o,end:t}),n.delete(r))}}}}invalidateCache(e){[...e.updated,...e.removed].forEach(t=>{this.elementCache.delete(t),this.childrenCommentsCache.delete(t)})}handleEffects(e){const{effects:t,blocks:n,regions:i,changes:r}=e;t&&(this.invalidateCache(r),t.html&&this.handleHtmlEffects(t.html,{blocks:n,regions:i,changes:r}),t.css&&this.handleCssEffects(t.css),t.js&&this.handleJsEffects(t.js))}handleCssEffects(e){for(const t of e)this.injectStyleElement(t)}injectStyleElement(e){const t=document.createElement("div");t.innerHTML=e;const n=t.firstElementChild;if(!n||n.tagName!=="STYLE"&&n.tagName!=="LINK"){console.warn("Invalid CSS element provided:",e);return}const i=n.id;if(i){const r=document.getElementById(i);if(r&&(r.tagName==="STYLE"||r.tagName==="LINK")){r.parentNode?.replaceChild(n,r);return}}if(n.tagName==="STYLE"&&!i){const r=n.textContent?.trim();if(r){const o=document.querySelectorAll("style:not([id])");for(const l of o)if(l.textContent?.trim()===r)return}}if(n.tagName==="LINK"&&!i){const r=n.getAttribute("href"),o=n.getAttribute("rel");if(r){const l=document.querySelectorAll("link:not([id])");for(const d of l)if(d.getAttribute("href")===r&&d.getAttribute("rel")===o)return}}document.head.appendChild(n)}handleJsEffects(e){this.pendingScripts.clear(),this.scriptExecutionCount={total:0,completed:0,failed:0};const t=e.filter(n=>n?.trim());if(this.scriptExecutionCount.total=t.length,t.length===0){this.emitScriptExecutionComplete();return}for(const n of t)this.injectScriptElement(n)}injectScriptElement(e){const t=document.createElement("div");t.innerHTML=e;const n=t.firstElementChild;if(!n||n.tagName!=="SCRIPT"){console.warn("Invalid script element provided:",e),this.onScriptCompleted(!1);return}const i=n.id,r=this.cloneExecutableScript(n);if(i){const o=document.getElementById(i);if(o&&o.tagName==="SCRIPT"){this.pendingScripts.delete(o),o.parentNode?.replaceChild(r,o),this.trackScriptExecution(r);return}}if(!n.src&&!i){const o=n.textContent?.trim();if(o){const l=document.querySelectorAll("script:not([src]):not([id])");for(const d of l)if(d.textContent?.trim()===o){this.onScriptCompleted(!0);return}}}if(n.src&&!i){const o=n.src,l=document.querySelectorAll("script[src]:not([id])");for(const d of l)if(d.src===o){this.onScriptCompleted(!0);return}}document.head.appendChild(r),this.trackScriptExecution(r)}cloneExecutableScript(e){const t=document.createElement("script");for(const n of e.attributes)t.setAttribute(n.name,n.value);return e.src||(t.textContent=e.textContent),t}trackScriptExecution(e){if(e.src){this.pendingScripts.add(e);const t=()=>{this.pendingScripts.delete(e),this.onScriptCompleted(!0),e.removeEventListener("load",t),e.removeEventListener("error",n)},n=()=>{this.pendingScripts.delete(e),this.onScriptCompleted(!1),e.removeEventListener("load",t),e.removeEventListener("error",n)};e.addEventListener("load",t),e.addEventListener("error",n)}else this.onScriptCompleted(!0)}onScriptCompleted(e){e?this.scriptExecutionCount.completed++:this.scriptExecutionCount.failed++,this.scriptExecutionCount.completed+this.scriptExecutionCount.failed>=this.scriptExecutionCount.total&&this.emitScriptExecutionComplete()}emitScriptExecutionComplete(){this.previewClient.emit("scripts.execution.complete",{total:this.scriptExecutionCount.total,completed:this.scriptExecutionCount.completed,failed:this.scriptExecutionCount.failed,success:this.scriptExecutionCount.failed===0})}handleDirectUpdates(e){const{changes:t}=e;t.moved&&this.handleMoves(e),t.updated.length>0&&this.handleDisabledBlocks(e),t.removed.length>0&&this.handleRemoves(e)}handleMoves(e){const{blocks:t,changes:n}=e;for(const[i,r]of Object.entries(e.changes.moved)){if(r?.toParent&&n.updated?.includes(r?.toParent))continue;if(!this.isValidMoveInstruction(r)){console.warn(`Invalid move instruction for block ${i}:`,r);continue}const o=t[i],l=n.positions?.[i];this.moveBlockUsingDOM(o,r,l)}}handleDisabledBlocks(e){const{blocks:t,changes:n}=e;for(const i of n.updated){const r=t[i];if(!r)continue;const l=!!this.getElementCached(i);r.disabled&&l?this.removeBlock(r.id,r):r.disabled}}handleRemoves(e){const{blocks:t,changes:n}=e;for(const i of n.removed)this.removeBlock(i,t[i])}handleHtmlEffects(e,t){const{blocks:n,changes:i}=t,r=new Set(Object.keys(e));for(const[o,l]of Object.entries(e)){if(!l)continue;const d=n[o];if(!d){console.warn(`Block data not found for ${o}`);continue}if(d.parentId&&r.has(d.parentId))continue;if(d.disabled){console.debug(`Skipping disabled block ${o}`);continue}if(!!this.getElementCached(o))this.updateBlockHtml(d,l);else{const A=i.positions?.[o];if(!A){console.warn(`No position info for block ${o}`);continue}this.insertBlock(d,l,A)}}this.cacheChildrenComments()}isValidMoveInstruction(e){const t=!!(e.toParent||e.toRegion),n=e.toIndex===void 0||e.toIndex>=0;return t&&n}removeBlock(e,t){const n=this.getElementCached(e);if(n){const i={blockId:e,...t?{blockType:t.type,block:t}:{},element:n};this.previewClient.emit("block.remove.before",{...i}),n.remove(),this.elementCache.delete(e),this.previewClient.emit("block.remove.after",{...i})}else console.warn(`Block ${e} not found for removal`)}moveBlockUsingDOM(e,t,n){const i=this.getElementCached(e.id),{toParent:r,toRegion:o,toIndex:l}=t;if(!i){console.warn(`Block element ${e.id} not found for move operation`);return}this.previewClient.emit("block.move.before",{blockId:e.id,blockType:e.type,block:e,element:i,toParent:r,toRegion:o,toIndex:l});const d=n?.afterId,p=n?.beforeId;if(r){const g=this.getElementCached(r);if(!g){console.error(`Parent element ${r} not found for move operation`);return}this.insertElementInParent(i,g,d,p)}else if(o){const g=this.findRegionInsertionPoint(o,d,p);if(!g){console.error(`Failed to find insertion point for region: ${o}`);return}g.parent.insertBefore(i,g.before)}this.previewClient.emit("block.move.after",{blockId:e.id,blockType:e.type,block:e,element:i,toParent:r,toRegion:o,toIndex:l})}insertBlock(e,t,n){if(this.getElementCached(e.id))return;this.previewClient.emit("block.insert.before",{blockId:e.id,blockType:e.type,block:e,html:t,positionInfo:n});const i=this.parseHtmlElement(t,e.id);if(!i)return;const{parentId:r,regionId:o,afterId:l,beforeId:d}=n;if(r){const p=this.getElementCached(r);if(!p){console.error(`Parent element ${r} not found for block ${e.id}`);return}this.insertElementInParent(i,p,l,d)}else if(o){const p=this.findRegionInsertionPoint(o,l,d);if(!p){console.error(`Failed to find insertion point for region: ${o}`);return}p.parent.insertBefore(i,p.before)}else console.warn(`No parent or region specified for block ${e.id}, inserting into body`),document.body.appendChild(i);this.elementCache.set(e.id,i),i.scrollIntoView({behavior:"smooth",block:"nearest",inline:"nearest"}),this.previewClient.emit("block.insert.after",{blockId:e.id,blockType:e.type,block:e,element:i,html:t,positionInfo:n})}updateBlockHtml(e,t){if(!t){console.warn(`No HTML provided for block ${e.id}`);return}const n=this.getElementCached(e.id);if(!n){console.warn(`Block element ${e.id} not found for HTML update`);return}this.previewClient.emit("block.update.before",{blockId:e.id,blockType:e.type,block:e,element:n,html:t}),Ee(n,t,this.morphdomOptions),this.elementCache.delete(e.id);const i=this.getElementCached(e.id);if(!i){console.error(`Block element ${e.id} not found after morphdom update`);return}i!==n&&this.previewClient.inspector.updateTrackedElement(e.id,i),this.previewClient.emit("block.update.after",{blockId:e.id,blockType:e.type,block:e,element:i,html:t})}insertElementInParent(e,t,n,i){const r=t.getAttribute("data-block"),o=r?this.childrenCommentsCache.get(r):null;if(o){let l=null;if(i)l=this.getElementCached(i);else if(n){const d=this.getElementCached(n);d&&d.nextSibling&&(l=d.nextSibling)}l||(l=o.end),o.begin.parentNode.insertBefore(e,l)}else{let l=null;if(i)l=this.getElementCached(i);else if(n){const d=this.getElementCached(n);d&&(l=d.nextElementSibling)}t.insertBefore(e,l)}}findRegionInsertionPoint(e,t,n){const i=this.regionCommentsCache.get(e);if(!i)return console.error(`Region comments not found for region: ${e}`),null;const{begin:r,end:o}=i;let l=null;if(n){const d=this.getElementCached(n);d&&(l=d)}else if(t){const d=this.getElementCached(t);d&&d.nextSibling&&(l=d.nextSibling)}return l||(l=o),{parent:r.parentNode,before:l}}parseHtmlElement(e,t){if(!e.trim())return console.error(`Empty HTML provided for block ${t}`),null;const n=document.createElement("div");n.innerHTML=e;const i=n.firstElementChild;return i||(console.error(`Invalid HTML for block ${t}: no element found`),null)}}return _})();
package/dist/index.d.ts CHANGED
@@ -24,6 +24,7 @@ export default class RawHtmlRenderer {
24
24
  private injectStyleElement;
25
25
  private handleJsEffects;
26
26
  private injectScriptElement;
27
+ private cloneExecutableScript;
27
28
  private trackScriptExecution;
28
29
  private onScriptCompleted;
29
30
  private emitScriptExecutionComplete;
package/dist/index.js CHANGED
@@ -178,12 +178,13 @@ class RawHtmlRenderer {
178
178
  return;
179
179
  }
180
180
  const id = scriptElement.id;
181
+ const executableScript = this.cloneExecutableScript(scriptElement);
181
182
  if (id) {
182
183
  const existing = document.getElementById(id);
183
184
  if (existing && existing.tagName === "SCRIPT") {
184
185
  this.pendingScripts.delete(existing);
185
- existing.parentNode?.replaceChild(scriptElement, existing);
186
- this.trackScriptExecution(scriptElement);
186
+ existing.parentNode?.replaceChild(executableScript, existing);
187
+ this.trackScriptExecution(executableScript);
187
188
  return;
188
189
  }
189
190
  }
@@ -209,8 +210,18 @@ class RawHtmlRenderer {
209
210
  }
210
211
  }
211
212
  }
212
- document.head.appendChild(scriptElement);
213
- this.trackScriptExecution(scriptElement);
213
+ document.head.appendChild(executableScript);
214
+ this.trackScriptExecution(executableScript);
215
+ }
216
+ cloneExecutableScript(parsedScript) {
217
+ const script = document.createElement("script");
218
+ for (const attr of parsedScript.attributes) {
219
+ script.setAttribute(attr.name, attr.value);
220
+ }
221
+ if (!parsedScript.src) {
222
+ script.textContent = parsedScript.textContent;
223
+ }
224
+ return script;
214
225
  }
215
226
  trackScriptExecution(scriptElement) {
216
227
  if (scriptElement.src) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@craftile/preview-client-html",
3
- "version": "1.0.8",
3
+ "version": "1.1.0",
4
4
  "description": "HTML preview client for static block rendering in Craftile",
5
5
  "keywords": [
6
6
  "craftile",
@@ -39,8 +39,8 @@
39
39
  "vite": "^7.0.0",
40
40
  "vite-plugin-dts": "^4.5.4",
41
41
  "vitest": "^3.2.4",
42
- "@craftile/preview-client": "1.0.8",
43
- "@craftile/types": "1.0.8"
42
+ "@craftile/preview-client": "1.1.0",
43
+ "@craftile/types": "1.1.0"
44
44
  },
45
45
  "repository": {
46
46
  "type": "git",