@base44/vite-plugin 1.0.13 → 1.0.14
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/injections/page-height-bridge.d.ts.map +1 -1
- package/dist/injections/page-height-bridge.js +81 -9
- package/dist/injections/page-height-bridge.js.map +1 -1
- package/dist/statics/index.mjs +7 -7
- package/dist/statics/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/injections/page-height-bridge.ts +98 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-height-bridge.d.ts","sourceRoot":"","sources":["../../src/injections/page-height-bridge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"page-height-bridge.d.ts","sourceRoot":"","sources":["../../src/injections/page-height-bridge.ts"],"names":[],"mappings":"AA2BA,MAAM,MAAM,0BAA0B,GAAG;IACvC,aAAa,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAYF;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,IAAI,CAuClD;AAED,wBAAgB,gCAAgC,IAAI,0BAA0B,CAyC7E"}
|
|
@@ -3,17 +3,19 @@
|
|
|
3
3
|
// fire on their own.
|
|
4
4
|
//
|
|
5
5
|
// parent → child { type: "freeze-vh-units", referenceVhBase?: number }
|
|
6
|
-
// Rewrites every `vh` in <style> + CSSOM to
|
|
7
|
-
// vh ↔ auto-resize feedback loop).
|
|
8
|
-
//
|
|
6
|
+
// Rewrites every `vh` in <style> + CSSOM to a CSS variable-backed
|
|
7
|
+
// expression (kills the vh ↔ auto-resize feedback loop). Repeated calls
|
|
8
|
+
// update the variable, so callers can rebase without recovering raw CSS.
|
|
9
|
+
// Idempotent; covers HMR-added styles too. Fire-and-forget.
|
|
9
10
|
//
|
|
10
11
|
// parent → child { type: "measure-page-height", settleMs?: number }
|
|
11
|
-
// After `settleMs` (default 2000) posts the page's
|
|
12
|
+
// After `settleMs` (default 2000) posts the page's measured content height
|
|
12
13
|
// as `{ type: "page-height-measured", height }` to the requester.
|
|
13
14
|
const FALLBACK_VHBASE = 900;
|
|
14
15
|
const MIN_VHBASE = 400;
|
|
15
16
|
const DEFAULT_SETTLE_MS = 2000;
|
|
16
17
|
const NEUTRALIZE_DEBOUNCE_MS = 16;
|
|
18
|
+
const REFERENCE_VH_BASE_VAR = "--base44-reference-vh-base";
|
|
17
19
|
const noop = () => { };
|
|
18
20
|
let started = false;
|
|
19
21
|
/**
|
|
@@ -67,13 +69,14 @@ export function createPageHeightBridgeController() {
|
|
|
67
69
|
let pendingOrigin = "*";
|
|
68
70
|
return {
|
|
69
71
|
freezeVhUnits: (override) => {
|
|
72
|
+
const referenceVhBase = resolveReferenceVhBase(override);
|
|
73
|
+
setReferenceVhBase(referenceVhBase);
|
|
70
74
|
if (vhCleanups) {
|
|
71
75
|
vhForceRun?.();
|
|
72
76
|
return;
|
|
73
77
|
}
|
|
74
|
-
const referenceVhBase = resolveReferenceVhBase(override);
|
|
75
78
|
vhCleanups = [];
|
|
76
|
-
vhForceRun = startVhNeutralizer(
|
|
79
|
+
vhForceRun = startVhNeutralizer(vhCleanups);
|
|
77
80
|
},
|
|
78
81
|
// Target the requester's origin so the height isn't broadcast to anyone
|
|
79
82
|
// who happens to embed us. Falls back to "*" when origin is unavailable
|
|
@@ -107,19 +110,22 @@ function resolveReferenceVhBase(override) {
|
|
|
107
110
|
const detected = window.innerHeight || 0;
|
|
108
111
|
return detected >= MIN_VHBASE ? detected : FALLBACK_VHBASE;
|
|
109
112
|
}
|
|
113
|
+
function setReferenceVhBase(referenceVhBase) {
|
|
114
|
+
document.documentElement.style.setProperty(REFERENCE_VH_BASE_VAR, `${referenceVhBase}px`);
|
|
115
|
+
}
|
|
110
116
|
// Caches keep work proportional to *new* CSS, not total CSS. <head> observer
|
|
111
117
|
// catches `<style>`/`<link>` adds; per-element observers catch HMR text edits.
|
|
112
118
|
// Returns a `forceRun` so the caller can re-trigger neutralization on later
|
|
113
119
|
// parent requests (idempotent — already-rewritten text is skipped via the
|
|
114
120
|
// processed sets).
|
|
115
|
-
function startVhNeutralizer(
|
|
121
|
+
function startVhNeutralizer(cleanups) {
|
|
116
122
|
const VH_RE = /(\d+(?:\.\d+)?)vh\b/g;
|
|
117
123
|
const processedStyles = new WeakSet();
|
|
118
124
|
const processedSheets = new WeakMap();
|
|
119
125
|
const watchedStyles = new WeakSet();
|
|
120
126
|
const styleObservers = new Set();
|
|
121
127
|
const neutralize = () => {
|
|
122
|
-
const rewrite = (input) => input.replace(VH_RE, (_match, n) =>
|
|
128
|
+
const rewrite = (input) => input.replace(VH_RE, (_match, n) => `calc(var(${REFERENCE_VH_BASE_VAR}) * ${formatVhFactor(n)})`);
|
|
123
129
|
document.querySelectorAll("style").forEach((el) => {
|
|
124
130
|
watchStyleEl(el);
|
|
125
131
|
if (processedStyles.has(el))
|
|
@@ -197,6 +203,9 @@ function startVhNeutralizer(referenceVhBase, cleanups) {
|
|
|
197
203
|
}
|
|
198
204
|
return debouncedNeutralize;
|
|
199
205
|
}
|
|
206
|
+
function formatVhFactor(value) {
|
|
207
|
+
return String(Number((parseFloat(value) / 100).toFixed(6)));
|
|
208
|
+
}
|
|
200
209
|
function rewriteVhInRules(rules, rewrite) {
|
|
201
210
|
for (let i = 0; i < rules.length; i++) {
|
|
202
211
|
const rule = rules[i];
|
|
@@ -229,7 +238,70 @@ function containsStylesheetNode(nodes) {
|
|
|
229
238
|
return false;
|
|
230
239
|
}
|
|
231
240
|
function measureContentHeight() {
|
|
232
|
-
|
|
241
|
+
const scrollHeight = Math.max(document.documentElement.scrollHeight, document.body?.scrollHeight ?? 0);
|
|
242
|
+
const viewportHeight = Math.max(window.innerHeight || 0, document.documentElement.clientHeight, document.body?.clientHeight ?? 0);
|
|
243
|
+
const contentBottom = measureElementContentBottom(viewportHeight);
|
|
244
|
+
const referenceVhBase = readReferenceVhBase();
|
|
245
|
+
if (contentBottom > 0)
|
|
246
|
+
return Math.ceil(Math.max(contentBottom, referenceVhBase));
|
|
247
|
+
return Math.ceil(Math.max(scrollHeight, referenceVhBase));
|
|
248
|
+
}
|
|
249
|
+
function readReferenceVhBase() {
|
|
250
|
+
const value = document.documentElement.style.getPropertyValue(REFERENCE_VH_BASE_VAR);
|
|
251
|
+
const parsed = parseFloat(value);
|
|
252
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
253
|
+
}
|
|
254
|
+
function measureElementContentBottom(viewportHeight) {
|
|
255
|
+
if (!document.body)
|
|
256
|
+
return 0;
|
|
257
|
+
const elements = [document.body, ...Array.from(document.body.querySelectorAll("*"))];
|
|
258
|
+
const contentBottoms = new WeakMap();
|
|
259
|
+
const viewportBottom = window.scrollY + viewportHeight;
|
|
260
|
+
for (let i = elements.length - 1; i >= 0; i--) {
|
|
261
|
+
const el = elements[i];
|
|
262
|
+
if (!el)
|
|
263
|
+
continue;
|
|
264
|
+
const childContentBottom = readChildrenContentBottom(el, contentBottoms);
|
|
265
|
+
const rawBottom = readElementBottom(el);
|
|
266
|
+
const selfBottom = isViewportStretchedContainer(rawBottom, childContentBottom, viewportBottom)
|
|
267
|
+
? 0
|
|
268
|
+
: rawBottom;
|
|
269
|
+
contentBottoms.set(el, Math.max(childContentBottom, selfBottom));
|
|
270
|
+
}
|
|
271
|
+
return contentBottoms.get(document.body) ?? 0;
|
|
272
|
+
}
|
|
273
|
+
function readChildrenContentBottom(el, contentBottoms) {
|
|
274
|
+
let childContentBottom = 0;
|
|
275
|
+
for (let i = 0; i < el.children.length; i++) {
|
|
276
|
+
const child = el.children[i];
|
|
277
|
+
if (!child)
|
|
278
|
+
continue;
|
|
279
|
+
childContentBottom = Math.max(childContentBottom, contentBottoms.get(child) ?? 0);
|
|
280
|
+
}
|
|
281
|
+
return childContentBottom;
|
|
282
|
+
}
|
|
283
|
+
function readElementBottom(el) {
|
|
284
|
+
const computedStyle = window.getComputedStyle(el);
|
|
285
|
+
if (isOutOfFlowDecoration(computedStyle))
|
|
286
|
+
return 0;
|
|
287
|
+
const rect = el.getBoundingClientRect();
|
|
288
|
+
if (rect.width === 0 && rect.height === 0)
|
|
289
|
+
return 0;
|
|
290
|
+
return rect.bottom + window.scrollY + readMarginBottom(computedStyle);
|
|
291
|
+
}
|
|
292
|
+
function readMarginBottom(computedStyle) {
|
|
293
|
+
const marginBottom = parseFloat(computedStyle.marginBottom);
|
|
294
|
+
return Number.isFinite(marginBottom) ? marginBottom : 0;
|
|
295
|
+
}
|
|
296
|
+
function isOutOfFlowDecoration(computedStyle) {
|
|
297
|
+
if (computedStyle.position === "fixed")
|
|
298
|
+
return true;
|
|
299
|
+
return computedStyle.position === "absolute" && computedStyle.pointerEvents === "none";
|
|
300
|
+
}
|
|
301
|
+
function isViewportStretchedContainer(elementBottom, childBottom, viewportBottom) {
|
|
302
|
+
return (childBottom > 0 &&
|
|
303
|
+
Math.abs(elementBottom - viewportBottom) <= 1 &&
|
|
304
|
+
elementBottom - childBottom > 8);
|
|
233
305
|
}
|
|
234
306
|
function createDebouncer(fn, delayMs) {
|
|
235
307
|
let timer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-height-bridge.js","sourceRoot":"","sources":["../../src/injections/page-height-bridge.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"page-height-bridge.js","sourceRoot":"","sources":["../../src/injections/page-height-bridge.ts"],"names":[],"mappings":"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"}
|
package/dist/statics/index.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
function
|
|
2
|
-
[data-visual-edit-active] *:not([${
|
|
3
|
-
[data-visual-edit-active] *:not([${
|
|
4
|
-
[data-visual-edit-active] *:not([${
|
|
1
|
+
function le(e,t){let n=t.top<27,i=t.height>=54,l=t.width>=window.innerWidth-4,c=l?"8px":"-2px",m=l?"8px":"4px";n&&i?(e.style.top="2px",e.style.left=m):n?(e.style.top=`${t.height+2}px`,e.style.left=c):(e.style.top="-27px",e.style.left=c)}function U(e){let t=e;return!!(t.dataset?.sourceLocation||t.dataset?.visualSelectorId)}function S(e){let t=e;return t.dataset?.sourceLocation||t.dataset?.visualSelectorId||null}var z=["src"],w="data-vite-plugin-element";function C(e){if(!e)return[];let t=Array.from(document.querySelectorAll(`[data-source-location="${e}"]`));return t.length>0?t:Array.from(document.querySelectorAll(`[data-visual-selector-id="${e}"]`))}function ae(e,t){e.forEach(n=>{n.setAttribute("class",t)})}function de(e,t,n){z.includes(t)&&e.forEach(i=>{i.setAttribute(t,n)})}function ce(e,t){let n={};for(let i of t){let l=e.getAttribute(i);l!==null&&(n[i]=l)}return n}function ue(){if(document.getElementById("freeze-animations"))return;document.documentElement.setAttribute("data-visual-edit-active","");let e=document.createElement("style");e.id="freeze-animations",e.textContent=`
|
|
2
|
+
[data-visual-edit-active] *:not([${w}]):not([${w}] *),
|
|
3
|
+
[data-visual-edit-active] *:not([${w}]):not([${w}] *)::before,
|
|
4
|
+
[data-visual-edit-active] *:not([${w}]):not([${w}] *)::after {
|
|
5
5
|
animation-play-state: paused !important;
|
|
6
6
|
transition: none !important;
|
|
7
7
|
}
|
|
8
8
|
`;let t=document.createElement("style");t.id="freeze-pointer-events",t.textContent=`
|
|
9
9
|
[data-visual-edit-active] * { pointer-events: none !important; }
|
|
10
|
-
[${
|
|
11
|
-
`;let
|
|
10
|
+
[${w}], [${w}] * { pointer-events: auto !important; }
|
|
11
|
+
`;let n=document.head||document.documentElement;n.appendChild(e),n.appendChild(t),document.getAnimations().forEach(i=>{let l=i.effect?.target;if(!(l instanceof Element&&l.closest(`[${w}]`)))try{i.finish()}catch{i.pause()}})}function me(){let e=document.getElementById("freeze-animations");e&&(e.remove(),document.getElementById("freeze-pointer-events")?.remove(),document.documentElement.removeAttribute("data-visual-edit-active"),document.getAnimations().forEach(t=>{if(t.playState==="paused")try{t.play()}catch{}}))}function X(e,t){let n=document.getElementById("freeze-pointer-events");n&&(n.disabled=!0);let i=document.elementFromPoint(e,t);return n&&(n.disabled=!1),i?.closest("[data-source-location], [data-visual-selector-id]")??null}function fe(e,t,n){let i=X(e,t);if(!i)return null;let l=S(i);return l===n?null:l}var pe={position:"absolute",backgroundColor:"#ffffff",border:"1px solid #e2e8f0",borderRadius:"6px",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.15)",fontSize:"12px",minWidth:"120px",maxHeight:"200px",overflowY:"auto",zIndex:"10001",padding:"4px 0",pointerEvents:"auto"},Ee={padding:"4px 12px",cursor:"pointer",color:"#334155",backgroundColor:"transparent",whiteSpace:"nowrap",lineHeight:"1.5",fontWeight:"400"},P="#526cff",ge="#DBEAFE",he="600",G="#f1f5f9",ve=10,Y='<svg width="12" height="12" viewBox="0 0 24 24" style="vertical-align:middle;margin-left:4px"><path d="M6 9l6 6 6-6" stroke="currentColor" stroke-width="2" fill="none"/></svg>',ye='<svg width="12" height="12" viewBox="0 0 24 24" style="vertical-align:middle;margin-left:4px"><path d="M18 15l-6-6-6 6" stroke="currentColor" stroke-width="2" fill="none"/></svg>',_="data-chevron",be=12,O="data-layer-dropdown",Le=2,Te=2;function q(e,t){for(let n of Object.keys(t))e.style.setProperty(n.replace(/[A-Z]/g,i=>`-${i.toLowerCase()}`),t[n])}function we(e){return e.tagName}function j(e,t){let n={element:e,tagName:e.tagName.toLowerCase(),selectorId:S(e)};return t!==void 0&&(n.depth=t),n}function Ie(e,t,n){let i=[];function l(c,m){if(!(m>t))for(let d=0;d<c.children.length;d++){let p=c.children[d];if(U(p)){let v={element:p,tagName:p.tagName.toLowerCase(),selectorId:S(p)};n!==void 0&&(v.depth=n+m-1),i.push(v),l(p,m+1)}else l(p,m)}}return l(e,1),i}function Ze(e){let t=[],n=e.parentElement;for(;n&&n!==document.documentElement&&n!==document.body&&t.length<Le;)U(n)&&t.push(j(n)),n=n.parentElement;return t.reverse(),t}function Je(e,t){return t.forEach((n,i)=>{e.push({...n,depth:i})}),t.length}function Se(e,t,n){e.push(j(t,n));let i=Ie(t,Te,n+1);e.push(...i)}function Qe(e){return e.at(-1)?.element??null}function et(e,t){let n=Ie(e,1);return n.some(i=>i.element===t)||n.push(j(t)),n}function tt(e,t,n,i){let l=S(n),c=new Set;for(let m of t)if(m.element===n)Se(e,n,i),l&&c.add(l);else{let d=m.selectorId;if(d!=null){if(d===l||c.has(d))continue;c.add(d)}e.push({...m,depth:i})}}function Ce(e){let t=Ze(e),n=[],i=Je(n,t),l=Qe(t);if(l){let c=et(l,e);tt(n,c,e,i)}else Se(n,e,i);return n}var H=null,K=null,N=null,B=null,R=null;function nt(e,t,{onSelect:n,onHover:i,onHoverEnd:l}){let c=document.createElement("div");c.textContent=we(e),q(c,Ee);let m=e.depth??0;return m>0&&(c.style.paddingLeft=`${be+m*ve}px`),t&&(c.style.color=P,c.style.backgroundColor=ge,c.style.fontWeight=he),c.addEventListener("mouseenter",()=>{t||(c.style.backgroundColor=G),i&&i(e)}),c.addEventListener("mouseleave",()=>{t||(c.style.backgroundColor="transparent"),l&&l()}),c.addEventListener("click",d=>{d.stopPropagation(),d.preventDefault(),n(e)}),c}function ot(e,t,n){let i=document.createElement("div");return i.setAttribute(O,"true"),i.setAttribute(w,"true"),q(i,pe),e.forEach(l=>{let c=l.element===t;i.appendChild(nt(l,c,n))}),i}function Me(e){if(e.querySelector(`[${_}]`))return;let t=document.createElement("span");t.setAttribute(_,"true"),t.style.display="inline-flex",t.innerHTML=Y,e.appendChild(t),e.style.display="inline-flex",e.style.alignItems="center",e.style.cursor="pointer",e.style.userSelect="none",e.style.whiteSpace="nowrap",e.style.pointerEvents="auto",e.setAttribute(O,"true"),e.setAttribute(w,"true")}function rt(e,t,n,{onSelect:i,onHover:l,onHoverEnd:c}){let m=Array.from(e.children),d=t.findIndex(v=>v.element===n),p=v=>{if(d>=0&&d<m.length){let b=m[d];b.style.color!==P&&(b.style.backgroundColor="transparent")}if(d=v,d>=0&&d<m.length){let b=m[d];b.style.color!==P&&(b.style.backgroundColor=G),b.scrollIntoView({block:"nearest"}),l&&d>=0&&d<t.length&&l(t[d])}};R=v=>{v.key==="ArrowDown"?(v.preventDefault(),v.stopPropagation(),p(d<m.length-1?d+1:0)):v.key==="ArrowUp"?(v.preventDefault(),v.stopPropagation(),p(d>0?d-1:m.length-1)):v.key==="Enter"&&d>=0&&d<t.length&&(v.preventDefault(),v.stopPropagation(),c&&c(),i(t[d]),M())},document.addEventListener("keydown",R,!0)}function it(e,t){let n=!0;N=i=>{if(n){n=!1;return}let l=i.target;!e.contains(l)&&l!==t&&M()},document.addEventListener("mousedown",N,!0)}function De(e,t,n,i){M();let l=ot(t,n,{...i,onSelect:d=>{i.onHoverEnd&&i.onHoverEnd(),i.onSelect(d),M()}}),c=e.parentElement;if(!c)return;l.style.top=`${e.offsetTop+e.offsetHeight+2}px`,l.style.left=`${e.offsetLeft}px`,c.appendChild(l),H=l,K=e;let m=e.querySelector(`[${_}]`);m&&(m.innerHTML=ye),B=i.onHoverEnd??null,rt(l,t,n,i),it(l,e)}function M(){let e=K?.querySelector(`[${_}]`);e&&(e.innerHTML=Y),K=null,B&&(B(),B=null),H&&H.parentNode&&H.remove(),H=null,N&&(document.removeEventListener("mousedown",N,!0),N=null),R&&(document.removeEventListener("keydown",R,!0),R=null)}function xe(){return H!==null}function Ae(e){let t=null,n=null,i=null,l=()=>{t&&t.parentNode&&t.remove(),t=null},c=E=>{l(),S(E.element)!==e.getSelectedElementId()&&(t=e.createPreviewOverlay(E.element))},m=E=>{l(),M(),n&&(document.removeEventListener("keydown",n,!0),n=null),i=null;let r=e.selectElement(E.element);v(r,E.element)},d=()=>{n&&(document.removeEventListener("keydown",n,!0),n=null),i&&(m(i),i=null)},p=(E,r,u,y,T)=>{E.stopPropagation(),E.preventDefault(),xe()?(M(),d()):(i={element:u,tagName:u.tagName.toLowerCase(),selectorId:T},e.onDeselect(),n=L=>{L.key==="Escape"&&(L.stopPropagation(),M(),d())},document.addEventListener("keydown",n,!0),De(r,y,u,{onSelect:m,onHover:c,onHoverEnd:l}))},v=(E,r)=>{if(!E)return;let u=E.querySelector("div");if(!u)return;let y=Ce(r);if(y.length<=1)return;let T=S(r);Me(u),u.addEventListener("click",L=>{p(L,u,r,y,T)})};return{attachToOverlay:v,cleanup:()=>{l(),M()}}}var Z="visual-edit-focus-styles",st=["div","p","h1","h2","h3","h4","h5","h6","span","li","td","a","button","label"],J=e=>!!e.dataset.arrField,lt=e=>!(!st.includes(e.tagName.toLowerCase())||!e.textContent?.trim()||e.querySelector("img, video, canvas, svg")||e.children?.length>0),He=()=>{if(document.getElementById(Z))return;let e=document.createElement("style");e.id=Z,e.textContent=`
|
|
12
12
|
[data-selected="true"][contenteditable="true"]:focus {
|
|
13
13
|
outline: none !important;
|
|
14
14
|
}
|
|
15
|
-
`,document.head.appendChild(e)},He=()=>{document.getElementById(Z)?.remove()},_e=e=>{let t=document.createRange();t.selectNodeContents(e);let o=window.getSelection();o?.removeAllRanges(),o?.addRange(t)},lt=e=>!(e instanceof HTMLElement)||!st(e)?!1:J(e)?!0:e.dataset.dynamicContent!=="true",Q=e=>!(e instanceof HTMLElement)||e.dataset.selected!=="true"?!1:lt(e);var at=500;function ee(e){let t=null,o=null,s=!1,a=new WeakMap,c=()=>{let i=e.getSelectedElementId();if(!i)return;let u=e.findElementsById(i);e.getSelectedOverlays().forEach((T,y)=>{y<u.length&&u[y]&&e.positionOverlay(T,u[y])})},f=i=>{let u=i.dataset.originalTextContent,E=i.textContent,T=i,y=i.getBoundingClientRect(),D={type:"inline-edit",elementInfo:{tagName:i.tagName,classes:T.className?.baseVal||i.className||"",visualSelectorId:e.getSelectedElementId(),content:E,dataSourceLocation:i.dataset.sourceLocation,isDynamicContent:i.dataset.dynamicContent==="true",linenumber:i.dataset.linenumber,filename:i.dataset.filename,position:{top:y.top,left:y.left,right:y.right,bottom:y.bottom,width:y.width,height:y.height,centerX:y.left+y.width/2,centerY:y.top+y.height/2}},originalContent:u,newContent:E};J(i)&&(D.arrIndex=i.dataset.arrIndex,D.arrVariableName=i.dataset.arrVariableName,D.arrField=i.dataset.arrField),window.parent.postMessage(D,"*"),i.dataset.originalTextContent=E||""},d=i=>{o&&clearTimeout(o),o=setTimeout(()=>f(i),at)},L=i=>{c(),d(i)},p=function(){L(this)},b=i=>{Ae(),i.dataset.originalTextContent=i.textContent||"",i.dataset.originalCursor=i.style.cursor,i.contentEditable="true",i.setAttribute(I,"true");let u=new AbortController;a.set(i,u),i.addEventListener("input",p,{signal:u.signal}),i.style.cursor="text",_e(i),setTimeout(()=>{i.isConnected&&i.focus()},0)},v=i=>{let u=a.get(i);u&&(u.abort(),a.delete(i)),i.isConnected&&(He(),i.contentEditable="false",i.removeAttribute(I),delete i.dataset.originalTextContent,i.dataset.originalCursor!==void 0&&(i.style.cursor=i.dataset.originalCursor,delete i.dataset.originalCursor))};return{get enabled(){return s},set enabled(i){s=i},isEditing(){return t!==null},getCurrentElement(){return t},canEdit(i){return Q(i)},startEditing(i){t=i,e.getSelectedOverlays().forEach(u=>{u.style.display="none"}),b(i),window.parent.postMessage({type:"content-editing-started",visualSelectorId:e.getSelectedElementId()},"*")},stopEditing(){if(!t)return;o&&(clearTimeout(o),o=null),v(t),e.getSelectedOverlays().forEach(u=>{u.style.display=""}),c(),window.parent.postMessage({type:"content-editing-ended",visualSelectorId:e.getSelectedElementId()},"*"),t=null},markElementsSelected(i){i.forEach(u=>{u instanceof HTMLElement&&(u.dataset.selected="true")})},clearSelectedMarks(i){i&&e.findElementsById(i).forEach(u=>{u instanceof HTMLElement&&delete u.dataset.selected})},handleToggleMessage(i){if(!s)return;let u=e.findElementsById(i.dataSourceLocation);if(u.length===0||!(u[0]instanceof HTMLElement))return;let E=u[0];if(i.inlineEditingMode){if(!Q(E))return;e.getSelectedElementId()!==i.dataSourceLocation&&(this.stopEditing(),e.clearSelection(),this.markElementsSelected(u),e.createSelectionOverlays(u,i.dataSourceLocation)),this.startEditing(E)}else t===E&&this.stopEditing()},cleanup(){this.stopEditing()}}}var te="__theme-font-preview";function Ne(){let e=null,t=null,o,s="*";return{freezeVhUnits:a=>{if(e){t?.();return}let c=dt(a);e=[],t=ct(c,e)},measurePageHeight:(a,c=2e3)=>{s=a,o!==void 0&&window.clearTimeout(o),o=window.setTimeout(()=>{requestAnimationFrame(()=>{let f=ut();window.parent.postMessage({type:"page-height-measured",height:f},s)})},c)},teardown:()=>{if(e){for(let a of e)a();e=null,t=null}o!==void 0&&window.clearTimeout(o)}}}function dt(e){if(e!==void 0)return e;let t=window.innerHeight||0;return t>=400?t:900}function ct(e,t){let o=/(\d+(?:\.\d+)?)vh\b/g,s=new WeakSet,a=new WeakMap,c=new WeakSet,f=new Set,L=ft(()=>{let u=E=>E.replace(o,(T,y)=>`${(parseFloat(y)/100*e).toFixed(2)}px`);document.querySelectorAll("style").forEach(E=>{if(b(E),s.has(E))return;s.add(E);let T=E.textContent;if(!T||T.indexOf("vh")===-1)return;let y=u(T);y!==T&&(E.textContent=y)});for(let E=0;E<document.styleSheets.length;E++){let T=document.styleSheets[E];if(!T)continue;let y;try{y=T.cssRules}catch{continue}a.get(T)!==y.length&&(Re(y,u),a.set(T,y.length))}},16),p=L.trigger;t.push(L.cancel);let b=u=>{if(c.has(u))return;c.add(u);let E=new MutationObserver(()=>{s.delete(u),p()});E.observe(u,{characterData:!0,childList:!0,subtree:!0}),f.add(E)};t.push(()=>{for(let u of f)u.disconnect();f.clear()}),p(),document.readyState==="loading"&&(document.addEventListener("DOMContentLoaded",p),t.push(()=>document.removeEventListener("DOMContentLoaded",p))),window.addEventListener("load",p),t.push(()=>window.removeEventListener("load",p));let v=new MutationObserver(u=>{for(let E of u)if(Oe(E.addedNodes)||Oe(E.removedNodes)){p();return}});t.push(()=>v.disconnect());let i=()=>{document.head&&v.observe(document.head,{childList:!0,subtree:!1})};return document.head?i():(document.addEventListener("DOMContentLoaded",i),t.push(()=>document.removeEventListener("DOMContentLoaded",i))),p}function Re(e,t){for(let o=0;o<e.length;o++){let s=e[o];if(!s)continue;s.cssRules&&Re(s.cssRules,t);let a=s.style;if(a)for(let c=0;c<a.length;c++){let f=a[c];if(!f)continue;let d=a.getPropertyValue(f);if(!d||d.indexOf("vh")===-1)continue;let L=t(d);L!==d&&a.setProperty(f,L,a.getPropertyPriority(f))}}}function Oe(e){for(let t=0;t<e.length;t++){let o=e[t];if(o instanceof HTMLStyleElement||o instanceof HTMLLinkElement)return!0}return!1}function ut(){return Math.max(document.documentElement.scrollHeight,document.body?.scrollHeight??0)}function ft(e,t){let o;return{trigger:()=>{o!==void 0&&window.clearTimeout(o),o=window.setTimeout(e,t)},cancel:()=>{o!==void 0&&(window.clearTimeout(o),o=void 0)}}}var B=50;function mt(){let e=Ne(),t=!1,o=!1,s=!1,a=[],c=[],f=[],d=null,L=null,p=(r=!1)=>{let n=document.createElement("div");return n.style.position="absolute",n.style.pointerEvents="none",n.style.transition="all 0.1s ease-in-out",n.style.zIndex="9999",r?n.style.border="2px solid #2563EB":(n.style.border="2px solid #95a5fc",n.style.backgroundColor="rgba(99, 102, 241, 0.05)"),n},b=(r,n,l=!1)=>{if(!n||!t)return;n.offsetWidth;let g=n.getBoundingClientRect();r.style.top=`${g.top+window.scrollY}px`,r.style.left=`${g.left+window.scrollX}px`,r.style.width=`${g.width}px`,r.style.height=`${g.height}px`;let h=r.querySelector("div");h||(h=document.createElement("div"),h.textContent=n.tagName.toLowerCase(),h.style.position="absolute",h.style.left="-2px",h.style.padding="2px 8px",h.style.fontSize="11px",h.style.fontWeight=l?"500":"400",h.style.color=l?"#ffffff":"#526cff",h.style.backgroundColor=l?"#2563EB":"#DBEAFE",h.style.borderRadius="3px",h.style.minWidth="24px",h.style.textAlign="center",r.appendChild(h)),se(h,g)},v=ee({findElementsById:C,getSelectedElementId:()=>d,getSelectedOverlays:()=>c,positionOverlay:b,clearSelection:()=>{v.clearSelectedMarks(d),E(),d=null,L=null},createSelectionOverlays:(r,n)=>{r.forEach(l=>{let m=p(!0);document.body.appendChild(m),c.push(m),b(m,l,!0)}),d=n}}),i=()=>{v.clearSelectedMarks(d),E(),d=null,L=null},u=()=>{a.forEach(r=>{r&&r.parentNode&&r.remove()}),a=[],f=[]},E=()=>{c.forEach(r=>{r&&r.parentNode&&r.remove()}),c=[]},T=["p","h1","h2","h3","h4","h5","h6","span","a","label"],y=r=>{let n=r,l=r.getBoundingClientRect(),m=r,g=T.includes(r.tagName?.toLowerCase()),h=n.closest("[data-arr-variable-name]"),w=h?.dataset?.arrVariableName||null,A=h?.dataset?.arrIndex,Xe=A!=null?parseInt(A,10):null,Ge=n.dataset?.arrField||null,Ye=n.closest("[data-collection-id]"),qe=n.closest("[data-collection-item-field]"),je=n.closest("[data-collection-item-id]");window.parent.postMessage({type:"element-selected",tagName:r.tagName,classes:m.className?.baseVal||r.className||"",visualSelectorId:S(r),content:g?n.innerText:void 0,dataSourceLocation:n.dataset.sourceLocation,isDynamicContent:n.dataset.dynamicContent==="true",linenumber:n.dataset.linenumber,filename:n.dataset.filename,position:{top:l.top,left:l.left,right:l.right,bottom:l.bottom,width:l.width,height:l.height,centerX:l.left+l.width/2,centerY:l.top+l.height/2},attributes:de(r,z),isTextElement:g,staticArrayName:w,staticArrayIndex:Xe,staticArrayField:Ge,collectionId:Ye?.dataset?.collectionId||null,collectionItemField:qe?.dataset?.collectionItemField||null,collectionItemId:je?.dataset?.collectionItemId||null},"*")},D=r=>{let n=S(r);return E(),C(n||null).forEach(m=>{let g=p(!0);document.body.appendChild(g),c.push(g),b(g,m,!0)}),d=n||null,L=r,u(),y(r),c[0]},Pe=()=>{d=null,window.parent.postMessage({type:"unselect-element"},"*")},V=null,x=null,W=()=>{u(),V=null},ke=r=>{let n=C(r);u(),n.forEach(l=>{let m=p(!1);document.body.appendChild(m),a.push(m),b(m,l)}),f=n,V=r},ne=r=>{!t||o||v.isEditing()||x===null&&(x=requestAnimationFrame(()=>{if(x=null,s){W();return}let n=fe(r.clientX,r.clientY,d);if(!n){W();return}V!==n&&ke(n)}))},F=()=>{x!==null&&(cancelAnimationFrame(x),x=null),W()},oe=r=>{if(!t)return;let n=r.target;if(n.closest(`[${O}]`)||v.enabled&&n instanceof HTMLElement&&n.contentEditable==="true")return;if(v.isEditing()){r.preventDefault(),r.stopPropagation(),r.stopImmediatePropagation(),v.stopEditing();return}if(s){r.preventDefault(),r.stopPropagation(),r.stopImmediatePropagation(),window.parent.postMessage({type:"close-dropdowns"},"*");return}r.preventDefault(),r.stopPropagation(),r.stopImmediatePropagation();let l=X(r.clientX,r.clientY);if(!l)return;let m=l,g=S(l);if(d===g&&m.dataset.selected==="true"&&v.enabled&&v.canEdit(m)){v.startEditing(m);return}v.stopEditing(),v.enabled&&v.markElementsSelected(C(g));let w=D(l);re.attachToOverlay(w,l)},Be=()=>{v.stopEditing(),i()},Ve=(r,n)=>{let l=C(r);l.length!==0&&(le(l,n),setTimeout(()=>{d===r&&c.forEach((m,g)=>{g<l.length&&b(m,l[g])}),f.length>0&&f[0]?.dataset?.visualSelectorId===r&&a.forEach((h,w)=>{w<f.length&&b(h,f[w])})},B))},We=(r,n,l)=>{let m=C(r);m.length!==0&&(ae(m,n,l),setTimeout(()=>{d===r&&c.forEach((g,h)=>{h<m.length&&b(g,m[h])})},B))},Fe=(r,n,l)=>{let m=C(r);m.length!==0&&(l!=null&&(m=m.filter(g=>g.dataset.arrIndex===String(l))),m.forEach(g=>{g.innerText=n}),setTimeout(()=>{d===r&&c.forEach((g,h)=>{h<m.length&&b(g,m[h])})},B))},re=xe({createPreviewOverlay:r=>{let n=p(!1);return n.style.zIndex="9998",document.body.appendChild(n),b(n,r),n},getSelectedElementId:()=>d,selectElement:D,onDeselect:Pe}),$e=r=>{t=r,r?(document.body.style.cursor="crosshair",ce(),document.addEventListener("mousemove",ne),document.addEventListener("mouseleave",F),document.addEventListener("click",oe,!0)):(ue(),v.stopEditing(),i(),re.cleanup(),F(),document.body.style.cursor="default",document.removeEventListener("mousemove",ne),document.removeEventListener("mouseleave",F),document.removeEventListener("click",oe,!0))},ie=()=>{if(d){let r=L;if(r&&r.isConnected){let n=r.getBoundingClientRect(),l=window.innerHeight,m=window.innerWidth,g=n.top<l&&n.bottom>0&&n.left<m&&n.right>0,h={top:n.top,left:n.left,right:n.right,bottom:n.bottom,width:n.width,height:n.height,centerX:n.left+n.width/2,centerY:n.top+n.height/2};window.parent.postMessage({type:"element-position-update",position:h,isInViewport:g,visualSelectorId:d},"*")}}},Ue=r=>{let n=r.data;switch(n.type){case"toggle-visual-edit-mode":$e(n.data.enabled),n.data.specs?.newInlineEditEnabled!==void 0&&(v.enabled=n.data.specs.newInlineEditEnabled);break;case"update-classes":n.data&&n.data.classes!==void 0?Ve(n.data.visualSelectorId,n.data.classes):console.warn("[VisualEditAgent] Invalid update-classes message:",n);break;case"update-attribute":n.data&&n.data.visualSelectorId&&n.data.attribute!==void 0&&n.data.value!==void 0?We(n.data.visualSelectorId,n.data.attribute,n.data.value):console.warn("[VisualEditAgent] Invalid update-attribute message:",n);break;case"unselect-element":Be();break;case"refresh-page":window.location.reload();break;case"update-content":n.data&&n.data.content!==void 0?Fe(n.data.visualSelectorId,n.data.content,n.data.arrIndex):console.warn("[VisualEditAgent] Invalid update-content message:",n);break;case"request-element-position":if(d&&L&&L.isConnected){let l=L.getBoundingClientRect(),m=window.innerHeight,g=window.innerWidth,h=l.top<m&&l.bottom>0&&l.left<g&&l.right>0,w={top:l.top,left:l.left,right:l.right,bottom:l.bottom,width:l.width,height:l.height,centerX:l.left+l.width/2,centerY:l.top+l.height/2};window.parent.postMessage({type:"element-position-update",position:w,isInViewport:h,visualSelectorId:d},"*")}break;case"popover-drag-state":n.data&&n.data.isDragging!==void 0&&(o=n.data.isDragging,n.data.isDragging&&u());break;case"dropdown-state":n.data&&n.data.isOpen!==void 0&&(s=n.data.isOpen,n.data.isOpen&&u());break;case"update-theme-variables":if(n.data?.variables){let l=n.data.mode==="dark"?document.querySelector(".dark"):document.documentElement;if(l)for(let[m,g]of Object.entries(n.data.variables))l.style.setProperty(m,g)}break;case"inject-font-import":if(n.data?.fontUrl){let l=document.getElementById(te);l||(l=document.createElement("style"),l.id=te,document.head.appendChild(l)),l.textContent=`@import url('${n.data.fontUrl}');`}break;case"toggle-inline-edit-mode":n.data&&v.handleToggleMessage(n.data);break;case"freeze-vh-units":e.freezeVhUnits(typeof n.referenceVhBase=="number"?n.referenceVhBase:void 0);break;case"measure-page-height":e.measurePageHeight(r.origin&&r.origin!=="null"?r.origin:"*",typeof n.settleMs=="number"?n.settleMs:void 0);break;default:break}},$=()=>{if(d){let r=C(d);c.forEach((n,l)=>{l<r.length&&b(n,r[l])})}f.length>0&&a.forEach((r,n)=>{n<f.length&&b(r,f[n])})};document.querySelectorAll("[data-linenumber]:not([data-visual-selector-id])").forEach((r,n)=>{let l=r,m=`visual-id-${l.dataset.filename}-${l.dataset.linenumber}-${n}`;l.dataset.visualSelectorId=m});let ze=new MutationObserver(r=>{r.some(l=>{let m=h=>{if(h.nodeType===Node.ELEMENT_NODE){let w=h;if(w.dataset&&w.dataset.visualSelectorId)return!0;for(let A=0;A<w.children.length;A++)if(m(w.children[A]))return!0}return!1};return l.type==="attributes"&&(l.attributeName==="style"||l.attributeName==="class"||l.attributeName==="width"||l.attributeName==="height")&&m(l.target)})&&setTimeout($,B)});window.addEventListener("message",Ue),window.addEventListener("scroll",ie,!0),document.addEventListener("scroll",ie,!0),window.addEventListener("resize",$),window.addEventListener("scroll",$),ze.observe(document.body,{attributes:!0,childList:!0,subtree:!0,attributeFilter:["style","class","width","height"]}),window.parent.postMessage({type:"visual-edit-agent-ready"},"*")}export{mt as setupVisualEditAgent};
|
|
15
|
+
`,document.head.appendChild(e)},_e=()=>{document.getElementById(Z)?.remove()},Oe=e=>{let t=document.createRange();t.selectNodeContents(e);let n=window.getSelection();n?.removeAllRanges(),n?.addRange(t)},at=e=>!(e instanceof HTMLElement)||!lt(e)?!1:J(e)?!0:e.dataset.dynamicContent!=="true",Q=e=>!(e instanceof HTMLElement)||e.dataset.selected!=="true"?!1:at(e);var dt=500;function ee(e){let t=null,n=null,i=!1,l=new WeakMap,c=()=>{let r=e.getSelectedElementId();if(!r)return;let u=e.findElementsById(r);e.getSelectedOverlays().forEach((T,L)=>{L<u.length&&u[L]&&e.positionOverlay(T,u[L])})},m=r=>{let u=r.dataset.originalTextContent,y=r.textContent,T=r,L=r.getBoundingClientRect(),D={type:"inline-edit",elementInfo:{tagName:r.tagName,classes:T.className?.baseVal||r.className||"",visualSelectorId:e.getSelectedElementId(),content:y,dataSourceLocation:r.dataset.sourceLocation,isDynamicContent:r.dataset.dynamicContent==="true",linenumber:r.dataset.linenumber,filename:r.dataset.filename,position:{top:L.top,left:L.left,right:L.right,bottom:L.bottom,width:L.width,height:L.height,centerX:L.left+L.width/2,centerY:L.top+L.height/2}},originalContent:u,newContent:y};J(r)&&(D.arrIndex=r.dataset.arrIndex,D.arrVariableName=r.dataset.arrVariableName,D.arrField=r.dataset.arrField),window.parent.postMessage(D,"*"),r.dataset.originalTextContent=y||""},d=r=>{n&&clearTimeout(n),n=setTimeout(()=>m(r),dt)},p=r=>{c(),d(r)},v=function(){p(this)},b=r=>{He(),r.dataset.originalTextContent=r.textContent||"",r.dataset.originalCursor=r.style.cursor,r.contentEditable="true",r.setAttribute(w,"true");let u=new AbortController;l.set(r,u),r.addEventListener("input",v,{signal:u.signal}),r.style.cursor="text",Oe(r),setTimeout(()=>{r.isConnected&&r.focus()},0)},E=r=>{let u=l.get(r);u&&(u.abort(),l.delete(r)),r.isConnected&&(_e(),r.contentEditable="false",r.removeAttribute(w),delete r.dataset.originalTextContent,r.dataset.originalCursor!==void 0&&(r.style.cursor=r.dataset.originalCursor,delete r.dataset.originalCursor))};return{get enabled(){return i},set enabled(r){i=r},isEditing(){return t!==null},getCurrentElement(){return t},canEdit(r){return Q(r)},startEditing(r){t=r,e.getSelectedOverlays().forEach(u=>{u.style.display="none"}),b(r),window.parent.postMessage({type:"content-editing-started",visualSelectorId:e.getSelectedElementId()},"*")},stopEditing(){if(!t)return;n&&(clearTimeout(n),n=null),E(t),e.getSelectedOverlays().forEach(u=>{u.style.display=""}),c(),window.parent.postMessage({type:"content-editing-ended",visualSelectorId:e.getSelectedElementId()},"*"),t=null},markElementsSelected(r){r.forEach(u=>{u instanceof HTMLElement&&(u.dataset.selected="true")})},clearSelectedMarks(r){r&&e.findElementsById(r).forEach(u=>{u instanceof HTMLElement&&delete u.dataset.selected})},handleToggleMessage(r){if(!i)return;let u=e.findElementsById(r.dataSourceLocation);if(u.length===0||!(u[0]instanceof HTMLElement))return;let y=u[0];if(r.inlineEditingMode){if(!Q(y))return;e.getSelectedElementId()!==r.dataSourceLocation&&(this.stopEditing(),e.clearSelection(),this.markElementsSelected(u),e.createSelectionOverlays(u,r.dataSourceLocation)),this.startEditing(y)}else t===y&&this.stopEditing()},cleanup(){this.stopEditing()}}}var te="__theme-font-preview";var ne="--base44-reference-vh-base";function Re(){let e=null,t=null,n,i="*";return{freezeVhUnits:l=>{let c=ct(l);if(ut(c),e){t?.();return}e=[],t=mt(e)},measurePageHeight:(l,c=2e3)=>{i=l,n!==void 0&&window.clearTimeout(n),n=window.setTimeout(()=>{requestAnimationFrame(()=>{let m=pt();window.parent.postMessage({type:"page-height-measured",height:m},i)})},c)},teardown:()=>{if(e){for(let l of e)l();e=null,t=null}n!==void 0&&window.clearTimeout(n)}}}function ct(e){if(e!==void 0)return e;let t=window.innerHeight||0;return t>=400?t:900}function ut(e){document.documentElement.style.setProperty(ne,`${e}px`)}function mt(e){let t=/(\d+(?:\.\d+)?)vh\b/g,n=new WeakSet,i=new WeakMap,l=new WeakSet,c=new Set,d=Tt(()=>{let r=u=>u.replace(t,(y,T)=>`calc(var(${ne}) * ${ft(T)})`);document.querySelectorAll("style").forEach(u=>{if(v(u),n.has(u))return;n.add(u);let y=u.textContent;if(!y||y.indexOf("vh")===-1)return;let T=r(y);T!==y&&(u.textContent=T)});for(let u=0;u<document.styleSheets.length;u++){let y=document.styleSheets[u];if(!y)continue;let T;try{T=y.cssRules}catch{continue}i.get(y)!==T.length&&(Pe(T,r),i.set(y,T.length))}},16),p=d.trigger;e.push(d.cancel);let v=r=>{if(l.has(r))return;l.add(r);let u=new MutationObserver(()=>{n.delete(r),p()});u.observe(r,{characterData:!0,childList:!0,subtree:!0}),c.add(u)};e.push(()=>{for(let r of c)r.disconnect();c.clear()}),p(),document.readyState==="loading"&&(document.addEventListener("DOMContentLoaded",p),e.push(()=>document.removeEventListener("DOMContentLoaded",p))),window.addEventListener("load",p),e.push(()=>window.removeEventListener("load",p));let b=new MutationObserver(r=>{for(let u of r)if(Ne(u.addedNodes)||Ne(u.removedNodes)){p();return}});e.push(()=>b.disconnect());let E=()=>{document.head&&b.observe(document.head,{childList:!0,subtree:!1})};return document.head?E():(document.addEventListener("DOMContentLoaded",E),e.push(()=>document.removeEventListener("DOMContentLoaded",E))),p}function ft(e){return String(Number((parseFloat(e)/100).toFixed(6)))}function Pe(e,t){for(let n=0;n<e.length;n++){let i=e[n];if(!i)continue;i.cssRules&&Pe(i.cssRules,t);let l=i.style;if(l)for(let c=0;c<l.length;c++){let m=l[c];if(!m)continue;let d=l.getPropertyValue(m);if(!d||d.indexOf("vh")===-1)continue;let p=t(d);p!==d&&l.setProperty(m,p,l.getPropertyPriority(m))}}}function Ne(e){for(let t=0;t<e.length;t++){let n=e[t];if(n instanceof HTMLStyleElement||n instanceof HTMLLinkElement)return!0}return!1}function pt(){let e=Math.max(document.documentElement.scrollHeight,document.body?.scrollHeight??0),t=Math.max(window.innerHeight||0,document.documentElement.clientHeight,document.body?.clientHeight??0),n=gt(t),i=Et();return n>0?Math.ceil(Math.max(n,i)):Math.ceil(Math.max(e,i))}function Et(){let e=document.documentElement.style.getPropertyValue(ne),t=parseFloat(e);return Number.isFinite(t)?t:0}function gt(e){if(!document.body)return 0;let t=[document.body,...Array.from(document.body.querySelectorAll("*"))],n=new WeakMap,i=window.scrollY+e;for(let l=t.length-1;l>=0;l--){let c=t[l];if(!c)continue;let m=ht(c,n),d=vt(c),p=Lt(d,m,i)?0:d;n.set(c,Math.max(m,p))}return n.get(document.body)??0}function ht(e,t){let n=0;for(let i=0;i<e.children.length;i++){let l=e.children[i];l&&(n=Math.max(n,t.get(l)??0))}return n}function vt(e){let t=window.getComputedStyle(e);if(bt(t))return 0;let n=e.getBoundingClientRect();return n.width===0&&n.height===0?0:n.bottom+window.scrollY+yt(t)}function yt(e){let t=parseFloat(e.marginBottom);return Number.isFinite(t)?t:0}function bt(e){return e.position==="fixed"?!0:e.position==="absolute"&&e.pointerEvents==="none"}function Lt(e,t,n){return t>0&&Math.abs(e-n)<=1&&e-t>8}function Tt(e,t){let n;return{trigger:()=>{n!==void 0&&window.clearTimeout(n),n=window.setTimeout(e,t)},cancel:()=>{n!==void 0&&(window.clearTimeout(n),n=void 0)}}}var k=50;function wt(){let e=Re(),t=!1,n=!1,i=!1,l=[],c=[],m=[],d=null,p=null,v=(s=!1)=>{let o=document.createElement("div");return o.style.position="absolute",o.style.pointerEvents="none",o.style.transition="all 0.1s ease-in-out",o.style.zIndex="9999",s?o.style.border="2px solid #2563EB":(o.style.border="2px solid #95a5fc",o.style.backgroundColor="rgba(99, 102, 241, 0.05)"),o},b=(s,o,a=!1)=>{if(!o||!t)return;o.offsetWidth;let g=o.getBoundingClientRect();s.style.top=`${g.top+window.scrollY}px`,s.style.left=`${g.left+window.scrollX}px`,s.style.width=`${g.width}px`,s.style.height=`${g.height}px`;let h=s.querySelector("div");h||(h=document.createElement("div"),h.textContent=o.tagName.toLowerCase(),h.style.position="absolute",h.style.left="-2px",h.style.padding="2px 8px",h.style.fontSize="11px",h.style.fontWeight=a?"500":"400",h.style.color=a?"#ffffff":"#526cff",h.style.backgroundColor=a?"#2563EB":"#DBEAFE",h.style.borderRadius="3px",h.style.minWidth="24px",h.style.textAlign="center",s.appendChild(h)),le(h,g)},E=ee({findElementsById:C,getSelectedElementId:()=>d,getSelectedOverlays:()=>c,positionOverlay:b,clearSelection:()=>{E.clearSelectedMarks(d),y(),d=null,p=null},createSelectionOverlays:(s,o)=>{s.forEach(a=>{let f=v(!0);document.body.appendChild(f),c.push(f),b(f,a,!0)}),d=o}}),r=()=>{E.clearSelectedMarks(d),y(),d=null,p=null},u=()=>{l.forEach(s=>{s&&s.parentNode&&s.remove()}),l=[],m=[]},y=()=>{c.forEach(s=>{s&&s.parentNode&&s.remove()}),c=[]},T=["p","h1","h2","h3","h4","h5","h6","span","a","label"],L=s=>{let o=s,a=s.getBoundingClientRect(),f=s,g=T.includes(s.tagName?.toLowerCase()),h=o.closest("[data-arr-variable-name]"),I=h?.dataset?.arrVariableName||null,A=h?.dataset?.arrIndex,Ge=A!=null?parseInt(A,10):null,Ye=o.dataset?.arrField||null,qe=o.closest("[data-collection-id]"),je=o.closest("[data-collection-item-field]"),Ke=o.closest("[data-collection-item-id]");window.parent.postMessage({type:"element-selected",tagName:s.tagName,classes:f.className?.baseVal||s.className||"",visualSelectorId:S(s),content:g?o.innerText:void 0,dataSourceLocation:o.dataset.sourceLocation,isDynamicContent:o.dataset.dynamicContent==="true",linenumber:o.dataset.linenumber,filename:o.dataset.filename,position:{top:a.top,left:a.left,right:a.right,bottom:a.bottom,width:a.width,height:a.height,centerX:a.left+a.width/2,centerY:a.top+a.height/2},attributes:ce(s,z),isTextElement:g,staticArrayName:I,staticArrayIndex:Ge,staticArrayField:Ye,collectionId:qe?.dataset?.collectionId||null,collectionItemField:je?.dataset?.collectionItemField||null,collectionItemId:Ke?.dataset?.collectionItemId||null},"*")},D=s=>{let o=S(s);return y(),C(o||null).forEach(f=>{let g=v(!0);document.body.appendChild(g),c.push(g),b(g,f,!0)}),d=o||null,p=s,u(),L(s),c[0]},Be=()=>{d=null,window.parent.postMessage({type:"unselect-element"},"*")},V=null,x=null,W=()=>{u(),V=null},ke=s=>{let o=C(s);u(),o.forEach(a=>{let f=v(!1);document.body.appendChild(f),l.push(f),b(f,a)}),m=o,V=s},oe=s=>{!t||n||E.isEditing()||x===null&&(x=requestAnimationFrame(()=>{if(x=null,i){W();return}let o=fe(s.clientX,s.clientY,d);if(!o){W();return}V!==o&&ke(o)}))},F=()=>{x!==null&&(cancelAnimationFrame(x),x=null),W()},re=s=>{if(!t)return;let o=s.target;if(o.closest(`[${O}]`)||E.enabled&&o instanceof HTMLElement&&o.contentEditable==="true")return;if(E.isEditing()){s.preventDefault(),s.stopPropagation(),s.stopImmediatePropagation(),E.stopEditing();return}if(i){s.preventDefault(),s.stopPropagation(),s.stopImmediatePropagation(),window.parent.postMessage({type:"close-dropdowns"},"*");return}s.preventDefault(),s.stopPropagation(),s.stopImmediatePropagation();let a=X(s.clientX,s.clientY);if(!a)return;let f=a,g=S(a);if(d===g&&f.dataset.selected==="true"&&E.enabled&&E.canEdit(f)){E.startEditing(f);return}E.stopEditing(),E.enabled&&E.markElementsSelected(C(g));let I=D(a);ie.attachToOverlay(I,a)},Ve=()=>{E.stopEditing(),r()},We=(s,o)=>{let a=C(s);a.length!==0&&(ae(a,o),setTimeout(()=>{d===s&&c.forEach((f,g)=>{g<a.length&&b(f,a[g])}),m.length>0&&m[0]?.dataset?.visualSelectorId===s&&l.forEach((h,I)=>{I<m.length&&b(h,m[I])})},k))},Fe=(s,o,a)=>{let f=C(s);f.length!==0&&(de(f,o,a),setTimeout(()=>{d===s&&c.forEach((g,h)=>{h<f.length&&b(g,f[h])})},k))},$e=(s,o,a)=>{let f=C(s);f.length!==0&&(a!=null&&(f=f.filter(g=>g.dataset.arrIndex===String(a))),f.forEach(g=>{g.innerText=o}),setTimeout(()=>{d===s&&c.forEach((g,h)=>{h<f.length&&b(g,f[h])})},k))},ie=Ae({createPreviewOverlay:s=>{let o=v(!1);return o.style.zIndex="9998",document.body.appendChild(o),b(o,s),o},getSelectedElementId:()=>d,selectElement:D,onDeselect:Be}),Ue=s=>{t=s,s?(document.body.style.cursor="crosshair",ue(),document.addEventListener("mousemove",oe),document.addEventListener("mouseleave",F),document.addEventListener("click",re,!0)):(me(),E.stopEditing(),r(),ie.cleanup(),F(),document.body.style.cursor="default",document.removeEventListener("mousemove",oe),document.removeEventListener("mouseleave",F),document.removeEventListener("click",re,!0))},se=()=>{if(d){let s=p;if(s&&s.isConnected){let o=s.getBoundingClientRect(),a=window.innerHeight,f=window.innerWidth,g=o.top<a&&o.bottom>0&&o.left<f&&o.right>0,h={top:o.top,left:o.left,right:o.right,bottom:o.bottom,width:o.width,height:o.height,centerX:o.left+o.width/2,centerY:o.top+o.height/2};window.parent.postMessage({type:"element-position-update",position:h,isInViewport:g,visualSelectorId:d},"*")}}},ze=s=>{let o=s.data;switch(o.type){case"toggle-visual-edit-mode":Ue(o.data.enabled),o.data.specs?.newInlineEditEnabled!==void 0&&(E.enabled=o.data.specs.newInlineEditEnabled);break;case"update-classes":o.data&&o.data.classes!==void 0?We(o.data.visualSelectorId,o.data.classes):console.warn("[VisualEditAgent] Invalid update-classes message:",o);break;case"update-attribute":o.data&&o.data.visualSelectorId&&o.data.attribute!==void 0&&o.data.value!==void 0?Fe(o.data.visualSelectorId,o.data.attribute,o.data.value):console.warn("[VisualEditAgent] Invalid update-attribute message:",o);break;case"unselect-element":Ve();break;case"refresh-page":window.location.reload();break;case"update-content":o.data&&o.data.content!==void 0?$e(o.data.visualSelectorId,o.data.content,o.data.arrIndex):console.warn("[VisualEditAgent] Invalid update-content message:",o);break;case"request-element-position":if(d&&p&&p.isConnected){let a=p.getBoundingClientRect(),f=window.innerHeight,g=window.innerWidth,h=a.top<f&&a.bottom>0&&a.left<g&&a.right>0,I={top:a.top,left:a.left,right:a.right,bottom:a.bottom,width:a.width,height:a.height,centerX:a.left+a.width/2,centerY:a.top+a.height/2};window.parent.postMessage({type:"element-position-update",position:I,isInViewport:h,visualSelectorId:d},"*")}break;case"popover-drag-state":o.data&&o.data.isDragging!==void 0&&(n=o.data.isDragging,o.data.isDragging&&u());break;case"dropdown-state":o.data&&o.data.isOpen!==void 0&&(i=o.data.isOpen,o.data.isOpen&&u());break;case"update-theme-variables":if(o.data?.variables){let a=o.data.mode==="dark"?document.querySelector(".dark"):document.documentElement;if(a)for(let[f,g]of Object.entries(o.data.variables))a.style.setProperty(f,g)}break;case"inject-font-import":if(o.data?.fontUrl){let a=document.getElementById(te);a||(a=document.createElement("style"),a.id=te,document.head.appendChild(a)),a.textContent=`@import url('${o.data.fontUrl}');`}break;case"toggle-inline-edit-mode":o.data&&E.handleToggleMessage(o.data);break;case"freeze-vh-units":e.freezeVhUnits(typeof o.referenceVhBase=="number"?o.referenceVhBase:void 0);break;case"measure-page-height":e.measurePageHeight(s.origin&&s.origin!=="null"?s.origin:"*",typeof o.settleMs=="number"?o.settleMs:void 0);break;default:break}},$=()=>{if(d){let s=C(d);c.forEach((o,a)=>{a<s.length&&b(o,s[a])})}m.length>0&&l.forEach((s,o)=>{o<m.length&&b(s,m[o])})};document.querySelectorAll("[data-linenumber]:not([data-visual-selector-id])").forEach((s,o)=>{let a=s,f=`visual-id-${a.dataset.filename}-${a.dataset.linenumber}-${o}`;a.dataset.visualSelectorId=f});let Xe=new MutationObserver(s=>{s.some(a=>{let f=h=>{if(h.nodeType===Node.ELEMENT_NODE){let I=h;if(I.dataset&&I.dataset.visualSelectorId)return!0;for(let A=0;A<I.children.length;A++)if(f(I.children[A]))return!0}return!1};return a.type==="attributes"&&(a.attributeName==="style"||a.attributeName==="class"||a.attributeName==="width"||a.attributeName==="height")&&f(a.target)})&&setTimeout($,k)});window.addEventListener("message",ze),window.addEventListener("scroll",se,!0),document.addEventListener("scroll",se,!0),window.addEventListener("resize",$),window.addEventListener("scroll",$),Xe.observe(document.body,{attributes:!0,childList:!0,subtree:!0,attributeFilter:["style","class","width","height"]}),window.parent.postMessage({type:"visual-edit-agent-ready"},"*")}export{wt as setupVisualEditAgent};
|
|
16
16
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/injections/utils.ts","../../src/injections/layer-dropdown/consts.ts","../../src/injections/layer-dropdown/utils.ts","../../src/injections/layer-dropdown/dropdown-ui.ts","../../src/injections/layer-dropdown/controller.ts","../../src/capabilities/inline-edit/dom-utils.ts","../../src/capabilities/inline-edit/controller.ts","../../src/consts.ts","../../src/injections/page-height-bridge.ts","../../src/injections/visual-edit-agent.ts"],"sourcesContent":["const LABEL_HEIGHT = 27;\n\n/**\n * Positions an element-tag label relative to its highlighted overlay.\n *\n * Strategy (in priority order):\n * 1. If the element is near the viewport top AND tall enough (>= 2x label height),\n * place the label **inside** the element at the top-left.\n * 2. If the element is near the viewport top but too short, place the label\n * **below** the element.\n * 3. Otherwise, place the label **above** the element (default).\n *\n * For full-width elements (spanning nearly the entire viewport), the left offset\n * is nudged inward (6px) to prevent clipping against the viewport edge.\n *\n * @param label - The label div to position (style.top and style.left are set).\n * @param rect - The bounding client rect of the highlighted element.\n */\nexport function positionLabel(label: HTMLDivElement, rect: DOMRect): void {\n const nearTop = rect.top < LABEL_HEIGHT;\n const tallEnough = rect.height >= LABEL_HEIGHT * 2;\n const isFullWidth = rect.width >= window.innerWidth - 4;\n const edgeLeft = isFullWidth ? \"8px\" : \"-2px\";\n const insideLeft = isFullWidth ? \"8px\" : \"4px\";\n\n if (nearTop && tallEnough) {\n label.style.top = \"2px\";\n label.style.left = insideLeft;\n } else if (nearTop) {\n label.style.top = `${rect.height + 2}px`;\n label.style.left = edgeLeft;\n } else {\n label.style.top = `-${LABEL_HEIGHT}px`;\n label.style.left = edgeLeft;\n }\n}\n\n/** Check if an element has instrumentation attributes */\nexport function isInstrumentedElement(element: Element): boolean {\n const htmlEl = element as HTMLElement;\n return !!(\n htmlEl.dataset?.sourceLocation || htmlEl.dataset?.visualSelectorId\n );\n}\n\n/** Get the selector ID from an element's data attributes (prefers source-location) */\nexport function getElementSelectorId(element: Element): string | null {\n const htmlEl = element as HTMLElement;\n return (\n htmlEl.dataset?.sourceLocation ||\n htmlEl.dataset?.visualSelectorId ||\n null\n );\n}\n\nexport const ALLOWED_ATTRIBUTES: string[] = [\"src\"];\n\nexport const PLUGIN_ELEMENT_ATTR = \"data-vite-plugin-element\";\n\n/** Find elements by ID - first try data-source-location, fallback to data-visual-selector-id */\nexport function findElementsById(id: string | null): Element[] {\n if (!id) return [];\n const sourceElements = Array.from(\n document.querySelectorAll(`[data-source-location=\"${id}\"]`)\n );\n if (sourceElements.length > 0) {\n return sourceElements;\n }\n return Array.from(\n document.querySelectorAll(`[data-visual-selector-id=\"${id}\"]`)\n );\n}\n\n/**\n * Update element classes by visual selector ID.\n * Uses setAttribute instead of className to support both HTML and SVG elements.\n */\nexport function updateElementClasses(elements: Element[], classes: string): void {\n elements.forEach((element) => {\n element.setAttribute(\"class\", classes);\n });\n}\n\n/** Set a single attribute on all provided elements. */\nexport function updateElementAttribute(elements: Element[], attribute: string, value: string): void {\n if (!ALLOWED_ATTRIBUTES.includes(attribute)) {\n return;\n }\n\n elements.forEach((element) => {\n element.setAttribute(attribute, value);\n });\n}\n\n/** Collect attribute values from an element for a given allowlist. */\nexport function collectAllowedAttributes(element: Element, allowedAttributes: string[]): Record<string, string> {\n const attributes: Record<string, string> = {};\n for (const attr of allowedAttributes) {\n const val = element.getAttribute(attr);\n if (val !== null) {\n attributes[attr] = val;\n }\n }\n return attributes;\n}\n\n/**\n * Freeze all CSS animations and transitions on the page by injecting\n * scoped styles under `[data-visual-edit-active]` and programmatically\n * finishing (or pausing) every running animation.\n *\n * Plugin-owned elements (`[data-vite-plugin-element]`) are excluded so\n * the plugin UI stays animated.\n */\nexport function stopAnimations(): void {\n if (document.getElementById('freeze-animations')) return;\n\n document.documentElement.setAttribute('data-visual-edit-active', '');\n\n const animStyle = document.createElement('style');\n animStyle.id = 'freeze-animations';\n animStyle.textContent = `\n [data-visual-edit-active] *:not([${PLUGIN_ELEMENT_ATTR}]):not([${PLUGIN_ELEMENT_ATTR}] *),\n [data-visual-edit-active] *:not([${PLUGIN_ELEMENT_ATTR}]):not([${PLUGIN_ELEMENT_ATTR}] *)::before,\n [data-visual-edit-active] *:not([${PLUGIN_ELEMENT_ATTR}]):not([${PLUGIN_ELEMENT_ATTR}] *)::after {\n animation-play-state: paused !important;\n transition: none !important;\n }\n `;\n\n const pointerStyle = document.createElement('style');\n pointerStyle.id = 'freeze-pointer-events';\n pointerStyle.textContent = `\n [data-visual-edit-active] * { pointer-events: none !important; }\n [${PLUGIN_ELEMENT_ATTR}], [${PLUGIN_ELEMENT_ATTR}] * { pointer-events: auto !important; }\n `;\n\n const target = document.head || document.documentElement;\n target.appendChild(animStyle);\n target.appendChild(pointerStyle);\n\n document.getAnimations().forEach((a) => {\n // Skip animations on plugin UI elements\n const animTarget = (a.effect as KeyframeEffect)?.target;\n if (animTarget instanceof Element && animTarget.closest(`[${PLUGIN_ELEMENT_ATTR}]`)) return;\n\n try {\n a.finish(); // fast-forward to end state\n } catch {\n a.pause(); // finish() throws on infinite animations — pause instead\n }\n });\n}\n\n/**\n * Resume all previously frozen animations and remove the injected\n * freeze styles. Cleans up the `data-visual-edit-active` attribute\n * from `<html>` so scoped selectors no longer match.\n */\nexport function resumeAnimations(): void {\n const animStyle = document.getElementById('freeze-animations');\n if (!animStyle) return;\n\n animStyle.remove();\n document.getElementById('freeze-pointer-events')?.remove();\n document.documentElement.removeAttribute('data-visual-edit-active');\n\n document.getAnimations().forEach((a) => {\n if (a.playState === 'paused') {\n try { a.play(); } catch { /* animation target may have been removed */ }\n }\n });\n}\n\n/**\n * Hit-test the page at (`x`, `y`) and walk up the DOM to find the\n * nearest ancestor that carries instrumentation attributes\n * (`data-source-location` or `data-visual-selector-id`).\n *\n * Temporarily disables the pointer-events freeze sheet so the\n * browser's native `elementFromPoint` can reach the real target.\n */\nexport function findInstrumentedElement(x: number, y: number): Element | null {\n const pointerStyle = document.getElementById('freeze-pointer-events') as HTMLStyleElement | null;\n if (pointerStyle) pointerStyle.disabled = true;\n\n const el = document.elementFromPoint(x, y);\n\n if (pointerStyle) pointerStyle.disabled = false;\n\n return el?.closest('[data-source-location], [data-visual-selector-id]') ?? null;\n}\n\n/**\n * Resolve which element should be hovered at (`x`, `y`), skipping the\n * currently selected element. Returns the selector ID of the hovered\n * element, or `null` if the point is empty or hits the selected element.\n */\nexport function resolveHoverTarget(x: number, y: number, selectedElementId: string | null): string | null {\n const element = findInstrumentedElement(x, y);\n if (!element) return null;\n\n const selectorId = getElementSelectorId(element);\n\n if (selectorId === selectedElementId) return null;\n\n return selectorId;\n}\n","/** Style constants for the layer dropdown UI */\n\nexport const DROPDOWN_CONTAINER_STYLES: Record<string, string> = {\n position: \"absolute\",\n backgroundColor: \"#ffffff\",\n border: \"1px solid #e2e8f0\",\n borderRadius: \"6px\",\n boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.15)\",\n fontSize: \"12px\",\n minWidth: \"120px\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n zIndex: \"10001\",\n padding: \"4px 0\",\n pointerEvents: \"auto\",\n};\n\nexport const DROPDOWN_ITEM_BASE_STYLES: Record<string, string> = {\n padding: \"4px 12px\",\n cursor: \"pointer\",\n color: \"#334155\",\n backgroundColor: \"transparent\",\n whiteSpace: \"nowrap\",\n lineHeight: \"1.5\",\n fontWeight: \"400\",\n};\n\nexport const DROPDOWN_ITEM_ACTIVE_COLOR = \"#526cff\";\nexport const DROPDOWN_ITEM_ACTIVE_BG = \"#DBEAFE\";\nexport const DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT = \"600\";\n\nexport const DROPDOWN_ITEM_HOVER_BG = \"#f1f5f9\";\n\nexport const DEPTH_INDENT_PX = 10;\n\n/** SVG chevron shown when dropdown is collapsed (click to expand) */\nexport const CHEVRON_COLLAPSED = `<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" style=\"vertical-align:middle;margin-left:4px\"><path d=\"M6 9l6 6 6-6\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"/></svg>`;\n/** SVG chevron shown when dropdown is expanded (click to collapse) */\nexport const CHEVRON_EXPANDED = `<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" style=\"vertical-align:middle;margin-left:4px\"><path d=\"M18 15l-6-6-6 6\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"/></svg>`;\n\nexport const CHEVRON_ATTR = \"data-chevron\";\n\nexport const BASE_PADDING_PX = 12;\n\nexport const LAYER_DROPDOWN_ATTR = \"data-layer-dropdown\";\n\n/** Max instrumented ancestors to show above the selected element */\nexport const MAX_PARENT_DEPTH = 2;\n\n/** Max instrumented depth levels to show below the selected element */\nexport const MAX_CHILD_DEPTH = 2;\n","/** DOM utilities for the layer-dropdown module */\n\nimport { isInstrumentedElement, getElementSelectorId } from \"../utils.js\";\nimport { MAX_PARENT_DEPTH, MAX_CHILD_DEPTH } from \"./consts.js\";\n\nimport type { LayerInfo } from \"./types.js\";\n\n/** Apply a style map to an element */\nexport function applyStyles(element: HTMLElement, styles: Record<string, string>): void {\n for (const key of Object.keys(styles)) {\n element.style.setProperty(\n key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`),\n styles[key]!\n );\n }\n}\n\n/** Display name for a layer — just the real tag name */\nexport function getLayerDisplayName(layer: LayerInfo): string {\n return layer.tagName;\n}\n\nfunction toLayerInfo(element: Element, depth?: number): LayerInfo {\n const info: LayerInfo = {\n element,\n tagName: element.tagName.toLowerCase(),\n selectorId: getElementSelectorId(element),\n };\n if (depth !== undefined) info.depth = depth;\n return info;\n}\n\n/**\n * Collect instrumented descendants up to `maxDepth` instrumented nesting levels.\n * Non-instrumented wrappers are walked through without counting toward depth.\n * Results are in DOM order.\n * When `startDepth` is provided, assigns `depth` to each item during collection.\n */\nexport function getInstrumentedDescendants(\n parent: Element,\n maxDepth: number,\n startDepth?: number\n): LayerInfo[] {\n const result: LayerInfo[] = [];\n\n function walk(el: Element, instrDepth: number): void {\n if (instrDepth > maxDepth) return;\n for (let i = 0; i < el.children.length; i++) {\n const child = el.children[i]!;\n if (isInstrumentedElement(child)) {\n const info: LayerInfo = {\n element: child,\n tagName: child.tagName.toLowerCase(),\n selectorId: getElementSelectorId(child),\n };\n if (startDepth !== undefined) {\n info.depth = startDepth + instrDepth - 1;\n }\n result.push(info);\n walk(child, instrDepth + 1);\n } else {\n walk(child, instrDepth);\n }\n }\n }\n\n walk(parent, 1);\n return result;\n}\n\n/** Collect instrumented ancestors from selected element up to MAX_PARENT_DEPTH (outermost first). */\nfunction collectInstrumentedParents(selectedElement: Element): LayerInfo[] {\n const parents: LayerInfo[] = [];\n let current = selectedElement.parentElement;\n while (\n current &&\n current !== document.documentElement &&\n current !== document.body &&\n parents.length < MAX_PARENT_DEPTH\n ) {\n if (isInstrumentedElement(current)) {\n parents.push(toLayerInfo(current));\n }\n current = current.parentElement;\n }\n parents.reverse();\n return parents;\n}\n\n/** Add parents to chain with depth 0, 1, …; returns depth of selected (parents.length). */\nfunction addParentsToChain(chain: LayerInfo[], parents: LayerInfo[]): number {\n parents.forEach((p, i) => {\n chain.push({ ...p, depth: i });\n });\n return parents.length;\n}\n\n/** Add selected element and its descendants at the given depth. */\nfunction addSelfAndDescendantsToChain(\n chain: LayerInfo[],\n selectedElement: Element,\n selfDepth: number\n): void {\n chain.push(toLayerInfo(selectedElement, selfDepth));\n const descendants = getInstrumentedDescendants(\n selectedElement,\n MAX_CHILD_DEPTH,\n selfDepth + 1\n );\n chain.push(...descendants);\n}\n\n/** Get the innermost instrumented parent's DOM element, or null if none. */\nfunction getImmediateInstrParent(parents: LayerInfo[]): Element | null {\n return parents.at(-1)?.element ?? null;\n}\n\n/** Collect instrumented siblings of the selected element from its parent (DOM order). */\nfunction collectSiblings(parent: Element, selectedElement: Element): LayerInfo[] {\n const siblings = getInstrumentedDescendants(parent, 1);\n if (!siblings.some((s) => s.element === selectedElement)) {\n siblings.push(toLayerInfo(selectedElement));\n }\n return siblings;\n}\n\n/** Add siblings at selfDepth, expanding children only for the selected element. */\nfunction appendSiblingsWithSelected(\n chain: LayerInfo[],\n siblings: LayerInfo[],\n selectedElement: Element,\n selfDepth: number\n): void {\n const selectedSelectorId = getElementSelectorId(selectedElement);\n const seen = new Set<string>();\n for (const sibling of siblings) {\n if (sibling.element === selectedElement) {\n addSelfAndDescendantsToChain(chain, selectedElement, selfDepth);\n if (selectedSelectorId) seen.add(selectedSelectorId);\n } else {\n const id = sibling.selectorId;\n if (id != null) {\n if (id === selectedSelectorId || seen.has(id)) continue;\n seen.add(id);\n }\n chain.push({ ...sibling, depth: selfDepth });\n }\n }\n}\n\n/**\n * Build the layer chain for the dropdown:\n *\n * Parents – up to MAX_PARENT_DEPTH instrumented ancestors, outer → inner.\n * Siblings – instrumented children of the immediate parent, at the same depth.\n * Current – the selected element (highlighted), with children expanded.\n * Children – instrumented descendants within MAX_CHILD_DEPTH levels, DOM order.\n *\n * Each item carries a `depth` for visual indentation.\n */\nexport function buildLayerChain(selectedElement: Element): LayerInfo[] {\n const parents = collectInstrumentedParents(selectedElement);\n const chain: LayerInfo[] = [];\n const selfDepth = addParentsToChain(chain, parents);\n\n const instrParent = getImmediateInstrParent(parents);\n if (instrParent) {\n const siblings = collectSiblings(instrParent, selectedElement);\n appendSiblingsWithSelected(chain, siblings, selectedElement, selfDepth);\n } else {\n addSelfAndDescendantsToChain(chain, selectedElement, selfDepth);\n }\n\n return chain;\n}\n","/** Dropdown UI component for layer navigation */\n\nimport {\n DROPDOWN_CONTAINER_STYLES,\n DROPDOWN_ITEM_BASE_STYLES,\n DROPDOWN_ITEM_ACTIVE_COLOR,\n DROPDOWN_ITEM_ACTIVE_BG,\n DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT,\n DROPDOWN_ITEM_HOVER_BG,\n DEPTH_INDENT_PX,\n BASE_PADDING_PX,\n CHEVRON_COLLAPSED,\n CHEVRON_EXPANDED,\n CHEVRON_ATTR,\n LAYER_DROPDOWN_ATTR,\n} from \"./consts.js\";\nimport { applyStyles, getLayerDisplayName } from \"./utils.js\";\nimport type { LayerInfo, DropdownCallbacks } from \"./types.js\";\nimport { PLUGIN_ELEMENT_ATTR } from \"../utils.js\";\n\nlet activeDropdown: HTMLDivElement | null = null;\nlet activeLabel: HTMLDivElement | null = null;\nlet outsideMousedownHandler: ((e: MouseEvent) => void) | null = null;\nlet activeOnHoverEnd: (() => void) | null = null;\nlet activeKeydownHandler: ((e: KeyboardEvent) => void) | null = null;\n\nfunction createDropdownItem(\n layer: LayerInfo,\n isActive: boolean,\n { onSelect, onHover, onHoverEnd }: DropdownCallbacks\n): HTMLDivElement {\n const item = document.createElement(\"div\");\n item.textContent = getLayerDisplayName(layer);\n applyStyles(item, DROPDOWN_ITEM_BASE_STYLES);\n\n const depth = layer.depth ?? 0;\n if (depth > 0) {\n item.style.paddingLeft = `${BASE_PADDING_PX + depth * DEPTH_INDENT_PX}px`;\n }\n\n if (isActive) {\n item.style.color = DROPDOWN_ITEM_ACTIVE_COLOR;\n item.style.backgroundColor = DROPDOWN_ITEM_ACTIVE_BG;\n item.style.fontWeight = DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT;\n }\n\n item.addEventListener(\"mouseenter\", () => {\n if (!isActive) item.style.backgroundColor = DROPDOWN_ITEM_HOVER_BG;\n if (onHover) onHover(layer);\n });\n\n item.addEventListener(\"mouseleave\", () => {\n if (!isActive) item.style.backgroundColor = \"transparent\";\n if (onHoverEnd) onHoverEnd();\n });\n\n item.addEventListener(\"click\", (e: MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n onSelect(layer);\n });\n\n return item;\n}\n\n/** Create the dropdown DOM element with layer items */\nexport function createDropdownElement(\n layers: LayerInfo[],\n currentElement: Element | null,\n callbacks: DropdownCallbacks\n): HTMLDivElement {\n const container = document.createElement(\"div\");\n container.setAttribute(LAYER_DROPDOWN_ATTR, \"true\");\n container.setAttribute(PLUGIN_ELEMENT_ATTR, \"true\");\n applyStyles(container, DROPDOWN_CONTAINER_STYLES);\n\n layers.forEach((layer) => {\n const isActive = layer.element === currentElement;\n container.appendChild(createDropdownItem(layer, isActive, callbacks));\n });\n\n return container;\n}\n\n/** Add chevron indicator and pointer-events to the label */\nexport function enhanceLabelWithChevron(label: HTMLDivElement): void {\n if (label.querySelector(`[${CHEVRON_ATTR}]`)) return;\n\n const chevron = document.createElement(\"span\");\n chevron.setAttribute(CHEVRON_ATTR, \"true\");\n chevron.style.display = \"inline-flex\";\n chevron.innerHTML = CHEVRON_COLLAPSED;\n label.appendChild(chevron);\n\n label.style.display = \"inline-flex\";\n label.style.alignItems = \"center\";\n label.style.cursor = \"pointer\";\n label.style.userSelect = \"none\";\n label.style.whiteSpace = \"nowrap\";\n label.style.pointerEvents = \"auto\";\n label.setAttribute(LAYER_DROPDOWN_ATTR, \"true\");\n label.setAttribute(PLUGIN_ELEMENT_ATTR, \"true\");\n}\n\nfunction setupKeyboardNavigation(\n dropdown: HTMLDivElement,\n layers: LayerInfo[],\n currentElement: Element | null,\n { onSelect, onHover, onHoverEnd }: DropdownCallbacks\n): void {\n const items = Array.from(dropdown.children) as HTMLDivElement[];\n let focusedIndex = layers.findIndex((l) => l.element === currentElement);\n\n const setFocusedItem = (index: number) => {\n if (focusedIndex >= 0 && focusedIndex < items.length) {\n const prev = items[focusedIndex]!;\n if (prev.style.color !== DROPDOWN_ITEM_ACTIVE_COLOR) {\n prev.style.backgroundColor = \"transparent\";\n }\n }\n focusedIndex = index;\n if (focusedIndex >= 0 && focusedIndex < items.length) {\n const cur = items[focusedIndex]!;\n if (cur.style.color !== DROPDOWN_ITEM_ACTIVE_COLOR) {\n cur.style.backgroundColor = DROPDOWN_ITEM_HOVER_BG;\n }\n cur.scrollIntoView({ block: \"nearest\" });\n if (onHover && focusedIndex >= 0 && focusedIndex < layers.length) {\n onHover(layers[focusedIndex]!);\n }\n }\n };\n\n activeKeydownHandler = (e: KeyboardEvent) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n e.stopPropagation();\n setFocusedItem(focusedIndex < items.length - 1 ? focusedIndex + 1 : 0);\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n e.stopPropagation();\n setFocusedItem(focusedIndex > 0 ? focusedIndex - 1 : items.length - 1);\n } else if (e.key === \"Enter\" && focusedIndex >= 0 && focusedIndex < layers.length) {\n e.preventDefault();\n e.stopPropagation();\n if (onHoverEnd) onHoverEnd();\n onSelect(layers[focusedIndex]!);\n closeDropdown();\n }\n };\n document.addEventListener(\"keydown\", activeKeydownHandler, true);\n}\n\nfunction setupOutsideClickHandler(\n dropdown: HTMLDivElement,\n label: HTMLDivElement\n): void {\n let skipFirst = true;\n outsideMousedownHandler = (e: MouseEvent) => {\n if (skipFirst) { skipFirst = false; return; }\n const target = e.target as Node;\n if (!dropdown.contains(target) && target !== label) {\n closeDropdown();\n }\n };\n document.addEventListener(\"mousedown\", outsideMousedownHandler, true);\n}\n\n/** Show the dropdown below the label element */\nexport function showDropdown(\n label: HTMLDivElement,\n layers: LayerInfo[],\n currentElement: Element | null,\n callbacks: DropdownCallbacks\n): void {\n closeDropdown();\n\n const dropdown = createDropdownElement(\n layers,\n currentElement,\n {\n ...callbacks,\n onSelect: (layer) => {\n if (callbacks.onHoverEnd) callbacks.onHoverEnd();\n callbacks.onSelect(layer);\n closeDropdown();\n },\n }\n );\n\n const overlay = label.parentElement;\n if (!overlay) return;\n\n dropdown.style.top = `${label.offsetTop + label.offsetHeight + 2}px`;\n dropdown.style.left = `${label.offsetLeft}px`;\n\n overlay.appendChild(dropdown);\n activeDropdown = dropdown;\n activeLabel = label;\n const chevronEl = label.querySelector(`[${CHEVRON_ATTR}]`);\n if (chevronEl) {\n chevronEl.innerHTML = CHEVRON_EXPANDED;\n }\n activeOnHoverEnd = callbacks.onHoverEnd ?? null;\n\n setupKeyboardNavigation(dropdown, layers, currentElement, callbacks);\n setupOutsideClickHandler(dropdown, label);\n}\n\n/** Close the active dropdown and clean up listeners */\nexport function closeDropdown(): void {\n const chevronEl = activeLabel?.querySelector(`[${CHEVRON_ATTR}]`);\n if (chevronEl) {\n chevronEl.innerHTML = CHEVRON_COLLAPSED;\n }\n activeLabel = null;\n\n if (activeOnHoverEnd) {\n activeOnHoverEnd();\n activeOnHoverEnd = null;\n }\n\n if (activeDropdown && activeDropdown.parentNode) {\n activeDropdown.remove();\n }\n activeDropdown = null;\n\n if (outsideMousedownHandler) {\n document.removeEventListener(\"mousedown\", outsideMousedownHandler, true);\n outsideMousedownHandler = null;\n }\n\n if (activeKeydownHandler) {\n document.removeEventListener(\"keydown\", activeKeydownHandler, true);\n activeKeydownHandler = null;\n }\n}\n\n/** Check if a dropdown is currently visible */\nexport function isDropdownOpen(): boolean {\n return activeDropdown !== null;\n}\n","/** Controller that encapsulates layer-dropdown integration logic */\n\nimport { getElementSelectorId } from \"../utils.js\";\nimport { buildLayerChain } from \"./utils.js\";\nimport {\n enhanceLabelWithChevron,\n showDropdown,\n closeDropdown,\n isDropdownOpen,\n} from \"./dropdown-ui.js\";\nimport type { LayerInfo, LayerControllerConfig, LayerController } from \"./types.js\";\n\nexport function createLayerController(config: LayerControllerConfig): LayerController {\n let layerPreviewOverlay: HTMLDivElement | null = null;\n let escapeHandler: ((e: KeyboardEvent) => void) | null = null;\n let dropdownSourceLayer: LayerInfo | null = null;\n\n const clearLayerPreview = () => {\n if (layerPreviewOverlay && layerPreviewOverlay.parentNode) {\n layerPreviewOverlay.remove();\n }\n layerPreviewOverlay = null;\n };\n\n const showLayerPreview = (layer: LayerInfo) => {\n clearLayerPreview();\n if (getElementSelectorId(layer.element) === config.getSelectedElementId()) return;\n\n layerPreviewOverlay = config.createPreviewOverlay(layer.element);\n };\n\n const selectLayer = (layer: LayerInfo) => {\n clearLayerPreview();\n closeDropdown();\n if (escapeHandler) {\n document.removeEventListener(\"keydown\", escapeHandler, true);\n escapeHandler = null;\n }\n dropdownSourceLayer = null;\n\n const firstOverlay = config.selectElement(layer.element);\n attachToOverlay(firstOverlay, layer.element);\n };\n\n const restoreSelection = () => {\n if (escapeHandler) {\n document.removeEventListener(\"keydown\", escapeHandler, true);\n escapeHandler = null;\n }\n if (dropdownSourceLayer) {\n selectLayer(dropdownSourceLayer);\n dropdownSourceLayer = null;\n }\n };\n\n const handleLabelClick = (e: MouseEvent, label: HTMLDivElement, element: Element, layers: LayerInfo[], currentId: string | null) => {\n e.stopPropagation();\n e.preventDefault();\n if (isDropdownOpen()) {\n closeDropdown();\n restoreSelection();\n } else {\n dropdownSourceLayer = {\n element,\n tagName: element.tagName.toLowerCase(),\n selectorId: currentId,\n };\n config.onDeselect();\n\n escapeHandler = (ev: KeyboardEvent) => {\n if (ev.key === \"Escape\") {\n ev.stopPropagation();\n closeDropdown();\n restoreSelection();\n }\n };\n document.addEventListener(\"keydown\", escapeHandler, true);\n\n showDropdown(label, layers, element, { onSelect: selectLayer, onHover: showLayerPreview, onHoverEnd: clearLayerPreview });\n }\n };\n\n const attachToOverlay = (\n overlay: HTMLDivElement | undefined,\n element: Element\n ) => {\n if (!overlay) return;\n\n const label = overlay.querySelector(\"div\") as HTMLDivElement | null;\n if (!label) return;\n\n const layers = buildLayerChain(element);\n if (layers.length <= 1) return;\n\n const currentId = getElementSelectorId(element);\n enhanceLabelWithChevron(label);\n\n label.addEventListener(\"click\", (e: MouseEvent) => {\n handleLabelClick(e, label, element, layers, currentId);\n });\n };\n\n const cleanup = () => {\n clearLayerPreview();\n closeDropdown();\n };\n\n return { attachToOverlay, cleanup };\n}\n","const FOCUS_STYLE_ID = \"visual-edit-focus-styles\";\n\nconst EDITABLE_TAGS = [\n \"div\", \"p\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\",\n \"span\", \"li\", \"td\", \"a\", \"button\", \"label\",\n];\n\nexport const isStaticArrayTextElement = (element: HTMLElement): boolean => {\n return !!element.dataset.arrField;\n};\n\nconst passesStructuralChecks = (element: HTMLElement): boolean => {\n if (!EDITABLE_TAGS.includes(element.tagName.toLowerCase())) return false;\n if (!element.textContent?.trim()) return false;\n if (element.querySelector(\"img, video, canvas, svg\")) return false;\n if (element.children?.length > 0) return false;\n return true;\n};\n\nexport const injectFocusOutlineCSS = () => {\n if (document.getElementById(FOCUS_STYLE_ID)) return;\n\n const style = document.createElement(\"style\");\n style.id = FOCUS_STYLE_ID;\n style.textContent = `\n [data-selected=\"true\"][contenteditable=\"true\"]:focus {\n outline: none !important;\n }\n `;\n document.head.appendChild(style);\n};\n\nexport const removeFocusOutlineCSS = () => {\n document.getElementById(FOCUS_STYLE_ID)?.remove();\n};\n\nexport const selectText = (element: HTMLElement) => {\n const range = document.createRange();\n range.selectNodeContents(element);\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(range);\n};\n\nexport const isEditableTextElement = (element: Element): boolean => {\n if (!(element instanceof HTMLElement)) return false;\n if (!passesStructuralChecks(element)) return false;\n if (isStaticArrayTextElement(element)) return true;\n if (element.dataset.dynamicContent === \"true\") return false;\n return true;\n};\n\nexport const shouldEnterInlineEditingMode = (element: Element): boolean => {\n if (!(element instanceof HTMLElement) || element.dataset.selected !== \"true\") {\n return false;\n }\n return isEditableTextElement(element);\n};\n","import type { InlineEditHost, InlineEditController } from \"./types.js\";\nimport {\n injectFocusOutlineCSS,\n removeFocusOutlineCSS,\n selectText,\n shouldEnterInlineEditingMode,\n isStaticArrayTextElement,\n} from \"./dom-utils.js\";\nimport { PLUGIN_ELEMENT_ATTR } from \"../../injections/utils.js\";\n\nconst DEBOUNCE_MS = 500;\n\nexport function createInlineEditController(\n host: InlineEditHost\n): InlineEditController {\n let currentEditingElement: HTMLElement | null = null;\n let debouncedSendTimeout: ReturnType<typeof setTimeout> | null = null;\n let enabled = false;\n const listenerAbortControllers = new WeakMap<HTMLElement, AbortController>();\n\n // --- Private helpers ---\n\n const repositionOverlays = () => {\n const selectedId = host.getSelectedElementId();\n if (!selectedId) return;\n const elements = host.findElementsById(selectedId);\n const overlays = host.getSelectedOverlays();\n overlays.forEach((overlay, i) => {\n if (i < elements.length && elements[i]) {\n host.positionOverlay(overlay, elements[i]);\n }\n });\n };\n\n const reportEdit = (element: HTMLElement) => {\n const originalContent = element.dataset.originalTextContent;\n const newContent = element.textContent;\n\n const svgElement = element as unknown as SVGElement;\n const rect = element.getBoundingClientRect();\n\n const message: Record<string, unknown> = {\n type: \"inline-edit\",\n elementInfo: {\n tagName: element.tagName,\n classes:\n (svgElement.className as unknown as SVGAnimatedString)?.baseVal ||\n element.className ||\n \"\",\n visualSelectorId: host.getSelectedElementId(),\n content: newContent,\n dataSourceLocation: element.dataset.sourceLocation,\n isDynamicContent: element.dataset.dynamicContent === \"true\",\n linenumber: element.dataset.linenumber,\n filename: element.dataset.filename,\n position: {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n centerX: rect.left + rect.width / 2,\n centerY: rect.top + rect.height / 2,\n },\n },\n originalContent,\n newContent,\n };\n\n if (isStaticArrayTextElement(element)) {\n message.arrIndex = element.dataset.arrIndex;\n message.arrVariableName = element.dataset.arrVariableName;\n message.arrField = element.dataset.arrField;\n }\n\n window.parent.postMessage(message, \"*\");\n\n element.dataset.originalTextContent = newContent || \"\";\n };\n\n const debouncedReport = (element: HTMLElement) => {\n if (debouncedSendTimeout) clearTimeout(debouncedSendTimeout);\n debouncedSendTimeout = setTimeout(() => reportEdit(element), DEBOUNCE_MS);\n };\n\n const onTextInput = (element: HTMLElement) => {\n repositionOverlays();\n debouncedReport(element);\n };\n\n const handleInputEvent = function (this: HTMLElement) {\n onTextInput(this);\n };\n\n const makeEditable = (element: HTMLElement) => {\n injectFocusOutlineCSS();\n\n element.dataset.originalTextContent = element.textContent || \"\";\n element.dataset.originalCursor = element.style.cursor;\n element.contentEditable = \"true\";\n element.setAttribute(PLUGIN_ELEMENT_ATTR, \"true\");\n\n const abortController = new AbortController();\n listenerAbortControllers.set(element, abortController);\n element.addEventListener(\"input\", handleInputEvent, {\n signal: abortController.signal,\n });\n\n element.style.cursor = \"text\";\n selectText(element);\n setTimeout(() => {\n if (element.isConnected) {\n element.focus();\n }\n }, 0);\n };\n\n const makeNonEditable = (element: HTMLElement) => {\n const abortController = listenerAbortControllers.get(element);\n if (abortController) {\n abortController.abort();\n listenerAbortControllers.delete(element);\n }\n\n if (!element.isConnected) return;\n\n removeFocusOutlineCSS();\n element.contentEditable = \"false\";\n element.removeAttribute(PLUGIN_ELEMENT_ATTR);\n delete element.dataset.originalTextContent;\n\n if (element.dataset.originalCursor !== undefined) {\n element.style.cursor = element.dataset.originalCursor;\n delete element.dataset.originalCursor;\n }\n };\n\n // --- Public API ---\n\n return {\n get enabled() {\n return enabled;\n },\n set enabled(value: boolean) {\n enabled = value;\n },\n\n isEditing() {\n return currentEditingElement !== null;\n },\n\n getCurrentElement() {\n return currentEditingElement;\n },\n\n canEdit(element: Element) {\n return shouldEnterInlineEditingMode(element);\n },\n\n startEditing(element: HTMLElement) {\n currentEditingElement = element;\n\n host.getSelectedOverlays().forEach((o) => {\n o.style.display = \"none\";\n });\n\n makeEditable(element);\n\n window.parent.postMessage(\n {\n type: \"content-editing-started\",\n visualSelectorId: host.getSelectedElementId(),\n },\n \"*\"\n );\n },\n\n stopEditing() {\n if (!currentEditingElement) return;\n\n if (debouncedSendTimeout) {\n clearTimeout(debouncedSendTimeout);\n debouncedSendTimeout = null;\n }\n\n const element = currentEditingElement;\n makeNonEditable(element);\n\n host.getSelectedOverlays().forEach((o) => {\n o.style.display = \"\";\n });\n\n repositionOverlays();\n\n window.parent.postMessage(\n {\n type: \"content-editing-ended\",\n visualSelectorId: host.getSelectedElementId(),\n },\n \"*\"\n );\n\n currentEditingElement = null;\n },\n\n markElementsSelected(elements: Element[]) {\n elements.forEach((el) => {\n if (el instanceof HTMLElement) {\n el.dataset.selected = \"true\";\n }\n });\n },\n\n clearSelectedMarks(elementId: string | null) {\n if (!elementId) return;\n host.findElementsById(elementId).forEach((el) => {\n if (el instanceof HTMLElement) {\n delete el.dataset.selected;\n }\n });\n },\n\n handleToggleMessage(data: { dataSourceLocation: string; inlineEditingMode: boolean }) {\n if (!enabled) return;\n\n const elements = host.findElementsById(data.dataSourceLocation);\n if (elements.length === 0 || !(elements[0] instanceof HTMLElement)) return;\n\n const element = elements[0];\n\n if (data.inlineEditingMode) {\n if (!shouldEnterInlineEditingMode(element)) return;\n\n // Select the element first if not already selected\n if (host.getSelectedElementId() !== data.dataSourceLocation) {\n this.stopEditing();\n host.clearSelection();\n this.markElementsSelected(elements);\n host.createSelectionOverlays(elements, data.dataSourceLocation);\n }\n this.startEditing(element);\n } else {\n if (currentEditingElement === element) {\n this.stopEditing();\n }\n }\n },\n\n cleanup() {\n this.stopEditing();\n },\n };\n}\n","export const DATA_COLLECTION_ID = \"data-collection-id\";\nexport const DATA_COLLECTION_ITEM_ID = \"data-collection-item-id\";\nexport const DATA_COLLECTION_ITEM_FIELD = \"data-collection-item-field\";\nexport const DATA_COLLECTION_REFERENCE = \"data-collection-reference\";\nexport const DATA_ARR_INDEX = \"data-arr-index\";\nexport const DATA_ARR_VARIABLE_NAME = \"data-arr-variable-name\";\nexport const DATA_ARR_FIELD = \"data-arr-field\";\n\nexport const ALLOWED_CUSTOM_COMPONENTS = [\"Image\", \"Link\"];\nexport const MAX_JSX_DEPTH = 10;\nexport const EXCLUDED_FIELDS = [\"children\", \"length\"];\nexport const THEME_FONT_PREVIEW_ID = \"__theme-font-preview\";\n","// page-height-bridge — postMessage protocol the iframe exposes to its parent.\n// Inert until the parent posts a message; no observers, rewrites, or timers\n// fire on their own.\n//\n// parent → child { type: \"freeze-vh-units\", referenceVhBase?: number }\n// Rewrites every `vh` in <style> + CSSOM to fixed `px` (kills the\n// vh ↔ auto-resize feedback loop). Idempotent; covers HMR-added\n// styles too. Fire-and-forget.\n//\n// parent → child { type: \"measure-page-height\", settleMs?: number }\n// After `settleMs` (default 2000) posts the page's scrollHeight back\n// as `{ type: \"page-height-measured\", height }` to the requester.\n\ntype IncomingMessage = {\n type?: string;\n settleMs?: number;\n referenceVhBase?: number;\n};\n\ntype IndexableCssRule = CSSRule & {\n cssRules?: CSSRuleList;\n style?: CSSStyleDeclaration;\n};\n\ntype Debouncer = { trigger: () => void; cancel: () => void };\n\nexport type PageHeightBridgeController = {\n freezeVhUnits: (override?: number) => void;\n measurePageHeight: (origin: string, settleMs?: number) => void;\n teardown: () => void;\n};\n\nconst FALLBACK_VHBASE: number = 900;\nconst MIN_VHBASE: number = 400;\nconst DEFAULT_SETTLE_MS: number = 2000;\nconst NEUTRALIZE_DEBOUNCE_MS: number = 16;\n\nconst noop: () => void = (): void => {};\n\nlet started: boolean = false;\n\n/**\n * Installs the parent-driven message listener. Returns a teardown that\n * removes the listener, disconnects any observers attached as a result of\n * `freeze-vh-units`, and clears any pending response timer. Returns a\n * no-op when bailed (already started, SSR, top window).\n */\nexport function setupPageHeightBridge(): () => void {\n if (started) return noop;\n if (typeof window === \"undefined\") return noop;\n if (window.self === window.top) return noop;\n started = true;\n\n const controller: PageHeightBridgeController = createPageHeightBridgeController();\n\n const onMessage = (event: MessageEvent): void => {\n const data: IncomingMessage | null = (event.data ?? null) as IncomingMessage | null;\n if (!data || typeof data !== \"object\") return;\n switch (data.type) {\n case \"freeze-vh-units\": {\n const override: number | undefined =\n typeof data.referenceVhBase === \"number\" ? data.referenceVhBase : undefined;\n controller.freezeVhUnits(override);\n return;\n }\n case \"measure-page-height\": {\n const settleMs: number =\n typeof data.settleMs === \"number\" ? data.settleMs : DEFAULT_SETTLE_MS;\n const origin: string =\n event.origin && event.origin !== \"null\" ? event.origin : \"*\";\n controller.measurePageHeight(origin, settleMs);\n return;\n }\n }\n };\n\n window.addEventListener(\"message\", onMessage);\n\n let torn: boolean = false;\n return (): void => {\n if (torn) return;\n torn = true;\n started = false;\n window.removeEventListener(\"message\", onMessage);\n controller.teardown();\n };\n}\n\nexport function createPageHeightBridgeController(): PageHeightBridgeController {\n let vhCleanups: Array<() => void> | null = null;\n let vhForceRun: (() => void) | null = null;\n let pendingResponse: number | undefined;\n let pendingOrigin: string = \"*\";\n\n return {\n freezeVhUnits: (override: number | undefined): void => {\n if (vhCleanups) {\n vhForceRun?.();\n return;\n }\n const referenceVhBase: number = resolveReferenceVhBase(override);\n vhCleanups = [];\n vhForceRun = startVhNeutralizer(referenceVhBase, vhCleanups);\n },\n\n // Target the requester's origin so the height isn't broadcast to anyone\n // who happens to embed us. Falls back to \"*\" when origin is unavailable\n // (jsdom default, sandboxed iframes with `null` origin).\n measurePageHeight: (origin: string, settleMs: number = DEFAULT_SETTLE_MS): void => {\n pendingOrigin = origin;\n if (pendingResponse !== undefined) window.clearTimeout(pendingResponse);\n pendingResponse = window.setTimeout((): void => {\n requestAnimationFrame((): void => {\n const height: number = measureContentHeight();\n window.parent.postMessage({ type: \"page-height-measured\", height }, pendingOrigin);\n });\n }, settleMs);\n },\n\n teardown: (): void => {\n if (vhCleanups) {\n for (const c of vhCleanups) c();\n vhCleanups = null;\n vhForceRun = null;\n }\n if (pendingResponse !== undefined) window.clearTimeout(pendingResponse);\n },\n };\n}\n\nfunction resolveReferenceVhBase(override: number | undefined): number {\n if (override !== undefined) return override;\n const detected: number = window.innerHeight || 0;\n return detected >= MIN_VHBASE ? detected : FALLBACK_VHBASE;\n}\n\n// Caches keep work proportional to *new* CSS, not total CSS. <head> observer\n// catches `<style>`/`<link>` adds; per-element observers catch HMR text edits.\n// Returns a `forceRun` so the caller can re-trigger neutralization on later\n// parent requests (idempotent — already-rewritten text is skipped via the\n// processed sets).\nfunction startVhNeutralizer(\n referenceVhBase: number,\n cleanups: Array<() => void>,\n): () => void {\n const VH_RE: RegExp = /(\\d+(?:\\.\\d+)?)vh\\b/g;\n const processedStyles: WeakSet<HTMLStyleElement> = new WeakSet();\n const processedSheets: WeakMap<CSSStyleSheet, number> = new WeakMap();\n const watchedStyles: WeakSet<HTMLStyleElement> = new WeakSet();\n const styleObservers: Set<MutationObserver> = new Set();\n\n const neutralize = (): void => {\n const rewrite = (input: string): string =>\n input.replace(VH_RE, (_match: string, n: string): string =>\n `${((parseFloat(n) / 100) * referenceVhBase).toFixed(2)}px`,\n );\n\n document.querySelectorAll<HTMLStyleElement>(\"style\").forEach((el: HTMLStyleElement): void => {\n watchStyleEl(el);\n if (processedStyles.has(el)) return;\n processedStyles.add(el);\n const text: string | null = el.textContent;\n if (!text || text.indexOf(\"vh\") === -1) return;\n const next: string = rewrite(text);\n if (next !== text) el.textContent = next;\n });\n\n for (let i: number = 0; i < document.styleSheets.length; i++) {\n const sheet: CSSStyleSheet | undefined = document.styleSheets[i];\n if (!sheet) continue;\n let rules: CSSRuleList;\n try {\n rules = sheet.cssRules;\n } catch {\n continue; // CORS-protected\n }\n if (processedSheets.get(sheet) === rules.length) continue;\n rewriteVhInRules(rules, rewrite);\n processedSheets.set(sheet, rules.length);\n }\n };\n\n const debouncer: Debouncer = createDebouncer(neutralize, NEUTRALIZE_DEBOUNCE_MS);\n const debouncedNeutralize: () => void = debouncer.trigger;\n cleanups.push(debouncer.cancel);\n\n const watchStyleEl = (el: HTMLStyleElement): void => {\n if (watchedStyles.has(el)) return;\n watchedStyles.add(el);\n const obs: MutationObserver = new MutationObserver((): void => {\n processedStyles.delete(el);\n debouncedNeutralize();\n });\n obs.observe(el, { characterData: true, childList: true, subtree: true });\n styleObservers.add(obs);\n };\n cleanups.push((): void => {\n for (const obs of styleObservers) obs.disconnect();\n styleObservers.clear();\n });\n\n debouncedNeutralize();\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", debouncedNeutralize);\n cleanups.push((): void => document.removeEventListener(\"DOMContentLoaded\", debouncedNeutralize));\n }\n window.addEventListener(\"load\", debouncedNeutralize);\n cleanups.push((): void => window.removeEventListener(\"load\", debouncedNeutralize));\n\n const headObserver: MutationObserver = new MutationObserver((mutations: MutationRecord[]): void => {\n for (const m of mutations) {\n if (containsStylesheetNode(m.addedNodes) || containsStylesheetNode(m.removedNodes)) {\n debouncedNeutralize();\n return;\n }\n }\n });\n cleanups.push((): void => headObserver.disconnect());\n\n const attachHeadObserver = (): void => {\n if (document.head) headObserver.observe(document.head, { childList: true, subtree: false });\n };\n if (document.head) {\n attachHeadObserver();\n } else {\n document.addEventListener(\"DOMContentLoaded\", attachHeadObserver);\n cleanups.push((): void => document.removeEventListener(\"DOMContentLoaded\", attachHeadObserver));\n }\n\n return debouncedNeutralize;\n}\n\nfunction rewriteVhInRules(rules: CSSRuleList, rewrite: (value: string) => string): void {\n for (let i: number = 0; i < rules.length; i++) {\n const rule: IndexableCssRule | undefined = rules[i] as IndexableCssRule | undefined;\n if (!rule) continue;\n if (rule.cssRules) rewriteVhInRules(rule.cssRules, rewrite);\n const style: CSSStyleDeclaration | undefined = rule.style;\n if (!style) continue;\n for (let j: number = 0; j < style.length; j++) {\n const prop: string | undefined = style[j];\n if (!prop) continue;\n const value: string = style.getPropertyValue(prop);\n if (!value || value.indexOf(\"vh\") === -1) continue;\n const next: string = rewrite(value);\n if (next !== value) style.setProperty(prop, next, style.getPropertyPriority(prop));\n }\n }\n}\n\nfunction containsStylesheetNode(nodes: NodeList): boolean {\n for (let i: number = 0; i < nodes.length; i++) {\n const node: Node | undefined = nodes[i];\n if (node instanceof HTMLStyleElement || node instanceof HTMLLinkElement) return true;\n }\n return false;\n}\n\nfunction measureContentHeight(): number {\n return Math.max(\n document.documentElement.scrollHeight,\n document.body?.scrollHeight ?? 0,\n );\n}\n\nfunction createDebouncer(fn: () => void, delayMs: number): Debouncer {\n let timer: number | undefined;\n return {\n trigger: (): void => {\n if (timer !== undefined) window.clearTimeout(timer);\n timer = window.setTimeout(fn, delayMs);\n },\n cancel: (): void => {\n if (timer !== undefined) {\n window.clearTimeout(timer);\n timer = undefined;\n }\n },\n };\n}\n","import { findElementsById, updateElementClasses, updateElementAttribute, collectAllowedAttributes, ALLOWED_ATTRIBUTES, getElementSelectorId, stopAnimations, resumeAnimations, findInstrumentedElement, resolveHoverTarget, positionLabel } from \"./utils.js\";\nimport { createLayerController } from \"./layer-dropdown/controller.js\";\nimport { LAYER_DROPDOWN_ATTR } from \"./layer-dropdown/consts.js\";\nimport { createInlineEditController } from \"../capabilities/inline-edit/index.js\";\nimport { THEME_FONT_PREVIEW_ID } from \"../consts.js\";\nimport { createPageHeightBridgeController } from \"./page-height-bridge.js\";\n\nconst REPOSITION_DELAY_MS = 50;\n\nexport function setupVisualEditAgent() {\n const pageHeightBridge = createPageHeightBridgeController();\n\n // State variables (replacing React useState/useRef)\n let isVisualEditMode = false;\n let isPopoverDragging = false;\n let isDropdownOpen = false;\n let hoverOverlays: HTMLDivElement[] = [];\n let selectedOverlays: HTMLDivElement[] = [];\n let currentHighlightedElements: Element[] = [];\n let selectedElementId: string | null = null;\n let selectedElement: Element | null = null;\n\n // Create overlay element\n const createOverlay = (isSelected = false): HTMLDivElement => {\n const overlay = document.createElement(\"div\");\n overlay.style.position = \"absolute\";\n overlay.style.pointerEvents = \"none\";\n overlay.style.transition = \"all 0.1s ease-in-out\";\n overlay.style.zIndex = \"9999\";\n\n if (isSelected) {\n overlay.style.border = \"2px solid #2563EB\";\n } else {\n overlay.style.border = \"2px solid #95a5fc\";\n overlay.style.backgroundColor = \"rgba(99, 102, 241, 0.05)\";\n }\n\n return overlay;\n };\n\n // Position overlay relative to element\n const positionOverlay = (\n overlay: HTMLDivElement,\n element: Element,\n isSelected = false\n ) => {\n if (!element || !isVisualEditMode) return;\n\n const htmlElement = element as HTMLElement;\n // Force layout recalculation\n void htmlElement.offsetWidth;\n\n const rect = element.getBoundingClientRect();\n overlay.style.top = `${rect.top + window.scrollY}px`;\n overlay.style.left = `${rect.left + window.scrollX}px`;\n overlay.style.width = `${rect.width}px`;\n overlay.style.height = `${rect.height}px`;\n\n // Check if label already exists in overlay\n let label = overlay.querySelector(\"div\") as HTMLDivElement | null;\n\n if (!label) {\n label = document.createElement(\"div\");\n label.textContent = element.tagName.toLowerCase();\n label.style.position = \"absolute\";\n label.style.left = \"-2px\";\n label.style.padding = \"2px 8px\";\n label.style.fontSize = \"11px\";\n label.style.fontWeight = isSelected ? \"500\" : \"400\";\n label.style.color = isSelected ? \"#ffffff\" : \"#526cff\";\n label.style.backgroundColor = isSelected ? \"#2563EB\" : \"#DBEAFE\";\n label.style.borderRadius = \"3px\";\n label.style.minWidth = \"24px\";\n label.style.textAlign = \"center\";\n overlay.appendChild(label);\n }\n\n positionLabel(label, rect);\n };\n\n // --- Inline edit controller ---\n const inlineEdit = createInlineEditController({\n findElementsById,\n getSelectedElementId: () => selectedElementId,\n getSelectedOverlays: () => selectedOverlays,\n positionOverlay,\n clearSelection: () => {\n inlineEdit.clearSelectedMarks(selectedElementId);\n clearSelectedOverlays();\n selectedElementId = null;\n selectedElement = null;\n },\n createSelectionOverlays: (elements, elementId) => {\n elements.forEach((el) => {\n const overlay = createOverlay(true);\n document.body.appendChild(overlay);\n selectedOverlays.push(overlay);\n positionOverlay(overlay, el, true);\n });\n selectedElementId = elementId;\n },\n });\n\n const clearSelection = () => {\n inlineEdit.clearSelectedMarks(selectedElementId);\n clearSelectedOverlays();\n selectedElementId = null;\n selectedElement = null;\n };\n\n // Clear hover overlays\n const clearHoverOverlays = () => {\n hoverOverlays.forEach((overlay) => {\n if (overlay && overlay.parentNode) {\n overlay.remove();\n }\n });\n hoverOverlays = [];\n currentHighlightedElements = [];\n };\n\n const clearSelectedOverlays = () => {\n selectedOverlays.forEach((overlay) => {\n if (overlay && overlay.parentNode) {\n overlay.remove();\n }\n });\n selectedOverlays = [];\n };\n\n const TEXT_TAGS = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'a', 'label'];\n\n const notifyElementSelected = (element: Element) => {\n const htmlElement = element as HTMLElement;\n const rect = element.getBoundingClientRect();\n const svgElement = element as SVGElement;\n const isTextElement = TEXT_TAGS.includes(element.tagName?.toLowerCase());\n\n const arrEl = htmlElement.closest(\"[data-arr-variable-name]\") as HTMLElement | null;\n const staticArrayName = arrEl?.dataset?.arrVariableName || null;\n const rawIdx = arrEl?.dataset?.arrIndex;\n const staticArrayIndex = rawIdx != null ? parseInt(rawIdx, 10) : null;\n const staticArrayField = htmlElement.dataset?.arrField || null;\n\n const collectionEl = htmlElement.closest(\"[data-collection-id]\") as HTMLElement | null;\n const itemFieldEl = htmlElement.closest(\"[data-collection-item-field]\") as HTMLElement | null;\n const itemIdEl = htmlElement.closest(\"[data-collection-item-id]\") as HTMLElement | null;\n\n window.parent.postMessage({\n type: \"element-selected\",\n tagName: element.tagName,\n classes:\n (svgElement.className as unknown as SVGAnimatedString)?.baseVal ||\n element.className ||\n \"\",\n visualSelectorId: getElementSelectorId(element),\n content: isTextElement ? htmlElement.innerText : undefined,\n dataSourceLocation: htmlElement.dataset.sourceLocation,\n isDynamicContent: htmlElement.dataset.dynamicContent === \"true\",\n linenumber: htmlElement.dataset.linenumber,\n filename: htmlElement.dataset.filename,\n position: {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n centerX: rect.left + rect.width / 2,\n centerY: rect.top + rect.height / 2,\n },\n attributes: collectAllowedAttributes(element, ALLOWED_ATTRIBUTES),\n isTextElement,\n staticArrayName,\n staticArrayIndex,\n staticArrayField,\n collectionId: collectionEl?.dataset?.collectionId || null,\n collectionItemField: itemFieldEl?.dataset?.collectionItemField || null,\n collectionItemId: itemIdEl?.dataset?.collectionItemId || null,\n }, \"*\");\n };\n\n // Select an element: create overlays, update state, notify parent\n const selectElement = (element: Element): HTMLDivElement | undefined => {\n const visualSelectorId = getElementSelectorId(element);\n\n clearSelectedOverlays();\n\n const elements = findElementsById(visualSelectorId || null);\n elements.forEach((el) => {\n const overlay = createOverlay(true);\n document.body.appendChild(overlay);\n selectedOverlays.push(overlay);\n positionOverlay(overlay, el, true);\n });\n\n selectedElementId = visualSelectorId || null;\n selectedElement = element;\n clearHoverOverlays();\n notifyElementSelected(element);\n\n return selectedOverlays[0];\n };\n\n const notifyDeselection = (): void => {\n selectedElementId = null;\n window.parent.postMessage({ type: \"unselect-element\" }, \"*\");\n };\n\n // Hover detection via mousemove + elementFromPoint (since app elements have pointer-events: none)\n let lastHoveredSelectorId: string | null = null;\n let pendingMouseMoveRaf: number | null = null;\n\n const clearHoverState = () => {\n clearHoverOverlays();\n lastHoveredSelectorId = null;\n };\n\n const applyHoverOverlays = (selectorId: string) => {\n const elements = findElementsById(selectorId);\n clearHoverOverlays();\n\n elements.forEach((el) => {\n const overlay = createOverlay(false);\n document.body.appendChild(overlay);\n hoverOverlays.push(overlay);\n positionOverlay(overlay, el);\n });\n\n currentHighlightedElements = elements;\n lastHoveredSelectorId = selectorId;\n };\n\n const handleMouseMove = (e: MouseEvent) => {\n if (!isVisualEditMode || isPopoverDragging || inlineEdit.isEditing()) return;\n\n if (pendingMouseMoveRaf !== null) return;\n pendingMouseMoveRaf = requestAnimationFrame(() => {\n pendingMouseMoveRaf = null;\n\n if (isDropdownOpen) { clearHoverState(); return; }\n\n const selectorId = resolveHoverTarget(e.clientX, e.clientY, selectedElementId);\n if (!selectorId) { clearHoverState(); return; }\n if (lastHoveredSelectorId === selectorId) return;\n\n applyHoverOverlays(selectorId);\n });\n };\n\n // Clear hover overlays when mouse leaves the viewport\n const handleMouseLeave = () => {\n if (pendingMouseMoveRaf !== null) {\n cancelAnimationFrame(pendingMouseMoveRaf);\n pendingMouseMoveRaf = null;\n }\n clearHoverState();\n };\n\n // Handle element click\n const handleElementClick = (e: MouseEvent) => {\n if (!isVisualEditMode) return;\n\n const target = e.target as Element;\n\n // Let layer dropdown clicks pass through without interference\n if (target.closest(`[${LAYER_DROPDOWN_ATTR}]`)) return;\n\n // Let clicks inside the editable element pass through to the browser\n // so the user can reposition the cursor and select text naturally.\n if (inlineEdit.enabled && target instanceof HTMLElement && target.contentEditable === \"true\") {\n return;\n }\n\n // Clicking outside the editable element exits inline editing mode.\n if (inlineEdit.isEditing()) {\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n inlineEdit.stopEditing();\n return;\n }\n\n // Close dropdowns when clicking anywhere in iframe if a dropdown is open\n if (isDropdownOpen) {\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n\n window.parent.postMessage({ type: \"close-dropdowns\" }, \"*\");\n return;\n }\n\n // Prevent default behavior immediately when in visual edit mode\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n\n const element = findInstrumentedElement(e.clientX, e.clientY);\n if (!element) {\n return;\n }\n\n const htmlElement = element as HTMLElement;\n const visualSelectorId = getElementSelectorId(element);\n\n const isAlreadySelected =\n selectedElementId === visualSelectorId &&\n htmlElement.dataset.selected === \"true\";\n\n if (isAlreadySelected && inlineEdit.enabled && inlineEdit.canEdit(htmlElement)) {\n inlineEdit.startEditing(htmlElement);\n return;\n }\n\n inlineEdit.stopEditing();\n\n if (inlineEdit.enabled) {\n inlineEdit.markElementsSelected(findElementsById(visualSelectorId));\n }\n\n const selectedOverlay = selectElement(element);\n layerController.attachToOverlay(selectedOverlay, element);\n };\n\n const unselectElement = () => {\n inlineEdit.stopEditing();\n clearSelection();\n };\n\n const updateElementClassesAndReposition = (visualSelectorId: string, classes: string) => {\n const elements = findElementsById(visualSelectorId);\n if (elements.length === 0) return;\n\n updateElementClasses(elements, classes);\n\n // Use a small delay to allow the browser to recalculate layout before repositioning\n setTimeout(() => {\n // Reposition selected overlays\n if (selectedElementId === visualSelectorId) {\n selectedOverlays.forEach((overlay, index) => {\n if (index < elements.length) {\n positionOverlay(overlay, elements[index]!);\n }\n });\n }\n\n // Reposition hover overlays if needed\n if (currentHighlightedElements.length > 0) {\n const hoveredElement = currentHighlightedElements[0] as HTMLElement;\n const hoveredId = hoveredElement?.dataset?.visualSelectorId;\n if (hoveredId === visualSelectorId) {\n hoverOverlays.forEach((overlay, index) => {\n if (index < currentHighlightedElements.length) {\n positionOverlay(overlay, currentHighlightedElements[index]!);\n }\n });\n }\n }\n }, REPOSITION_DELAY_MS);\n };\n\n // Update element attribute by visual selector ID\n const updateElementAttributeAndReposition = (\n visualSelectorId: string,\n attribute: string,\n value: string\n ) => {\n const elements = findElementsById(visualSelectorId);\n if (elements.length === 0) return;\n\n updateElementAttribute(elements, attribute, value);\n\n // Reposition overlays after attribute change (e.g. image src swap can affect layout)\n setTimeout(() => {\n if (selectedElementId === visualSelectorId) {\n selectedOverlays.forEach((overlay, index) => {\n if (index < elements.length) {\n positionOverlay(overlay, elements[index]!);\n }\n });\n }\n }, REPOSITION_DELAY_MS);\n };\n\n const updateElementContent = (visualSelectorId: string, content: string, arrIndex?: number) => {\n let elements = findElementsById(visualSelectorId);\n\n if (elements.length === 0) {\n return;\n }\n\n if (arrIndex != null) {\n elements = elements.filter(\n (el) => (el as HTMLElement).dataset.arrIndex === String(arrIndex)\n );\n }\n\n elements.forEach((element) => {\n (element as HTMLElement).innerText = content;\n });\n\n setTimeout(() => {\n if (selectedElementId === visualSelectorId) {\n selectedOverlays.forEach((overlay, index) => {\n if (index < elements.length) {\n positionOverlay(overlay, elements[index]!);\n }\n });\n }\n }, REPOSITION_DELAY_MS);\n };\n\n // --- Layer dropdown controller ---\n const layerController = createLayerController({\n createPreviewOverlay: (element: Element) => {\n const overlay = createOverlay(false);\n overlay.style.zIndex = \"9998\";\n document.body.appendChild(overlay);\n positionOverlay(overlay, element);\n return overlay;\n },\n getSelectedElementId: () => selectedElementId,\n selectElement,\n onDeselect: notifyDeselection,\n });\n\n // Toggle visual edit mode\n const toggleVisualEditMode = (isEnabled: boolean) => {\n isVisualEditMode = isEnabled;\n\n if (!isEnabled) {\n resumeAnimations();\n inlineEdit.stopEditing();\n clearSelection();\n layerController.cleanup();\n handleMouseLeave();\n document.body.style.cursor = \"default\";\n\n document.removeEventListener(\"mousemove\", handleMouseMove);\n document.removeEventListener(\"mouseleave\", handleMouseLeave);\n document.removeEventListener(\"click\", handleElementClick, true);\n } else {\n document.body.style.cursor = \"crosshair\";\n stopAnimations();\n document.addEventListener(\"mousemove\", handleMouseMove);\n document.addEventListener(\"mouseleave\", handleMouseLeave);\n document.addEventListener(\"click\", handleElementClick, true);\n }\n };\n\n // Handle scroll events to update popover position\n const handleScroll = () => {\n if (selectedElementId) {\n const element = selectedElement;\n if (element && element.isConnected) {\n const rect = element.getBoundingClientRect();\n\n const viewportHeight = window.innerHeight;\n const viewportWidth = window.innerWidth;\n const isInViewport =\n rect.top < viewportHeight &&\n rect.bottom > 0 &&\n rect.left < viewportWidth &&\n rect.right > 0;\n\n const elementPosition = {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n centerX: rect.left + rect.width / 2,\n centerY: rect.top + rect.height / 2,\n };\n\n window.parent.postMessage(\n {\n type: \"element-position-update\",\n position: elementPosition,\n isInViewport: isInViewport,\n visualSelectorId: selectedElementId,\n },\n \"*\"\n );\n }\n }\n };\n\n // Handle messages from parent window\n const handleMessage = (event: MessageEvent) => {\n const message = event.data;\n\n switch (message.type) {\n case \"toggle-visual-edit-mode\":\n toggleVisualEditMode(message.data.enabled);\n if (message.data.specs?.newInlineEditEnabled !== undefined) {\n inlineEdit.enabled = message.data.specs.newInlineEditEnabled;\n }\n break;\n\n case \"update-classes\":\n if (message.data && message.data.classes !== undefined) {\n updateElementClassesAndReposition(\n message.data.visualSelectorId,\n message.data.classes\n );\n } else {\n console.warn(\n \"[VisualEditAgent] Invalid update-classes message:\",\n message\n );\n }\n break;\n\n case \"update-attribute\":\n if (\n message.data &&\n message.data.visualSelectorId &&\n message.data.attribute !== undefined &&\n message.data.value !== undefined\n ) {\n updateElementAttributeAndReposition(\n message.data.visualSelectorId,\n message.data.attribute,\n message.data.value\n );\n } else {\n console.warn(\n \"[VisualEditAgent] Invalid update-attribute message:\",\n message\n );\n }\n break;\n\n case \"unselect-element\":\n unselectElement();\n break;\n\n case \"refresh-page\":\n window.location.reload();\n break;\n\n case \"update-content\":\n if (message.data && message.data.content !== undefined) {\n updateElementContent(\n message.data.visualSelectorId,\n message.data.content,\n message.data.arrIndex\n );\n } else {\n console.warn(\n \"[VisualEditAgent] Invalid update-content message:\",\n message\n );\n }\n break;\n\n case \"request-element-position\":\n if (selectedElementId && selectedElement && selectedElement.isConnected) {\n const rect = selectedElement.getBoundingClientRect();\n\n const viewportHeight = window.innerHeight;\n const viewportWidth = window.innerWidth;\n const isInViewport =\n rect.top < viewportHeight &&\n rect.bottom > 0 &&\n rect.left < viewportWidth &&\n rect.right > 0;\n\n const elementPosition = {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n centerX: rect.left + rect.width / 2,\n centerY: rect.top + rect.height / 2,\n };\n\n window.parent.postMessage(\n {\n type: \"element-position-update\",\n position: elementPosition,\n isInViewport: isInViewport,\n visualSelectorId: selectedElementId,\n },\n \"*\"\n );\n }\n break;\n\n case \"popover-drag-state\":\n if (message.data && message.data.isDragging !== undefined) {\n isPopoverDragging = message.data.isDragging;\n if (message.data.isDragging) {\n clearHoverOverlays();\n }\n }\n break;\n\n case \"dropdown-state\":\n if (message.data && message.data.isOpen !== undefined) {\n isDropdownOpen = message.data.isOpen;\n if (message.data.isOpen) {\n clearHoverOverlays();\n }\n }\n break;\n\n case \"update-theme-variables\":\n if (message.data?.variables) {\n const target = message.data.mode === 'dark'\n ? document.querySelector('.dark') as HTMLElement\n : document.documentElement;\n if (target) {\n for (const [name, value] of Object.entries(message.data.variables)) {\n target.style.setProperty(name, value as string);\n }\n }\n }\n break;\n\n case \"inject-font-import\":\n if (message.data?.fontUrl) {\n let fontStyle = document.getElementById(THEME_FONT_PREVIEW_ID) as HTMLStyleElement | null;\n if (!fontStyle) {\n fontStyle = document.createElement('style');\n fontStyle.id = THEME_FONT_PREVIEW_ID;\n document.head.appendChild(fontStyle);\n }\n fontStyle.textContent = `@import url('${message.data.fontUrl}');`;\n }\n break;\n\n case \"toggle-inline-edit-mode\":\n if (message.data) {\n inlineEdit.handleToggleMessage(message.data);\n }\n break;\n\n case \"freeze-vh-units\":\n pageHeightBridge.freezeVhUnits(\n typeof message.referenceVhBase === \"number\"\n ? message.referenceVhBase\n : undefined\n );\n break;\n\n case \"measure-page-height\":\n pageHeightBridge.measurePageHeight(\n event.origin && event.origin !== \"null\" ? event.origin : \"*\",\n typeof message.settleMs === \"number\" ? message.settleMs : undefined\n );\n break;\n\n default:\n break;\n }\n };\n\n // Handle window resize to reposition overlays\n const handleResize = () => {\n if (selectedElementId) {\n const elements = findElementsById(selectedElementId);\n selectedOverlays.forEach((overlay, index) => {\n if (index < elements.length) {\n positionOverlay(overlay, elements[index]!);\n }\n });\n }\n\n if (currentHighlightedElements.length > 0) {\n hoverOverlays.forEach((overlay, index) => {\n if (index < currentHighlightedElements.length) {\n positionOverlay(overlay, currentHighlightedElements[index]!);\n }\n });\n }\n };\n\n // Initialize: Add IDs to elements that don't have them but have linenumbers\n const elementsWithLineNumber = document.querySelectorAll(\n \"[data-linenumber]:not([data-visual-selector-id])\"\n );\n elementsWithLineNumber.forEach((el, index) => {\n const htmlEl = el as HTMLElement;\n const id = `visual-id-${htmlEl.dataset.filename}-${htmlEl.dataset.linenumber}-${index}`;\n htmlEl.dataset.visualSelectorId = id;\n });\n\n // Create mutation observer to detect layout changes\n const mutationObserver = new MutationObserver((mutations) => {\n const needsUpdate = mutations.some((mutation) => {\n const hasVisualId = (node: Node): boolean => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const el = node as HTMLElement;\n if (el.dataset && el.dataset.visualSelectorId) {\n return true;\n }\n for (let i = 0; i < el.children.length; i++) {\n if (hasVisualId(el.children[i]!)) {\n return true;\n }\n }\n }\n return false;\n };\n\n const isLayoutChange =\n mutation.type === \"attributes\" &&\n (mutation.attributeName === \"style\" ||\n mutation.attributeName === \"class\" ||\n mutation.attributeName === \"width\" ||\n mutation.attributeName === \"height\");\n\n return isLayoutChange && hasVisualId(mutation.target);\n });\n\n if (needsUpdate) {\n setTimeout(handleResize, REPOSITION_DELAY_MS);\n }\n });\n\n // Set up event listeners\n window.addEventListener(\"message\", handleMessage);\n window.addEventListener(\"scroll\", handleScroll, true);\n document.addEventListener(\"scroll\", handleScroll, true);\n window.addEventListener(\"resize\", handleResize);\n window.addEventListener(\"scroll\", handleResize);\n\n // Start observing DOM mutations\n mutationObserver.observe(document.body, {\n attributes: true,\n childList: true,\n subtree: true,\n attributeFilter: [\"style\", \"class\", \"width\", \"height\"],\n });\n\n // Send ready message to parent\n window.parent.postMessage({ type: \"visual-edit-agent-ready\" }, \"*\");\n}\n"],"mappings":"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","names":["positionLabel","label","rect","nearTop","tallEnough","isFullWidth","edgeLeft","insideLeft","isInstrumentedElement","element","htmlEl","getElementSelectorId","ALLOWED_ATTRIBUTES","PLUGIN_ELEMENT_ATTR","findElementsById","id","sourceElements","updateElementClasses","elements","classes","updateElementAttribute","attribute","value","collectAllowedAttributes","allowedAttributes","attributes","attr","val","stopAnimations","animStyle","pointerStyle","target","a","animTarget","resumeAnimations","findInstrumentedElement","x","y","el","resolveHoverTarget","selectedElementId","selectorId","DROPDOWN_CONTAINER_STYLES","DROPDOWN_ITEM_BASE_STYLES","DROPDOWN_ITEM_ACTIVE_COLOR","DROPDOWN_ITEM_ACTIVE_BG","DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT","DROPDOWN_ITEM_HOVER_BG","DEPTH_INDENT_PX","CHEVRON_COLLAPSED","CHEVRON_EXPANDED","CHEVRON_ATTR","BASE_PADDING_PX","LAYER_DROPDOWN_ATTR","MAX_PARENT_DEPTH","MAX_CHILD_DEPTH","applyStyles","element","styles","key","m","getLayerDisplayName","layer","toLayerInfo","depth","info","getElementSelectorId","getInstrumentedDescendants","parent","maxDepth","startDepth","result","walk","el","instrDepth","i","child","isInstrumentedElement","collectInstrumentedParents","selectedElement","parents","current","MAX_PARENT_DEPTH","addParentsToChain","chain","p","addSelfAndDescendantsToChain","selfDepth","descendants","MAX_CHILD_DEPTH","getImmediateInstrParent","collectSiblings","siblings","appendSiblingsWithSelected","selectedSelectorId","seen","sibling","id","buildLayerChain","instrParent","activeDropdown","activeLabel","outsideMousedownHandler","activeOnHoverEnd","activeKeydownHandler","createDropdownItem","layer","isActive","onSelect","onHover","onHoverEnd","item","getLayerDisplayName","applyStyles","DROPDOWN_ITEM_BASE_STYLES","depth","BASE_PADDING_PX","DEPTH_INDENT_PX","DROPDOWN_ITEM_ACTIVE_COLOR","DROPDOWN_ITEM_ACTIVE_BG","DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT","DROPDOWN_ITEM_HOVER_BG","e","createDropdownElement","layers","currentElement","callbacks","container","LAYER_DROPDOWN_ATTR","PLUGIN_ELEMENT_ATTR","DROPDOWN_CONTAINER_STYLES","enhanceLabelWithChevron","label","CHEVRON_ATTR","chevron","CHEVRON_COLLAPSED","setupKeyboardNavigation","dropdown","items","focusedIndex","l","setFocusedItem","index","prev","cur","closeDropdown","setupOutsideClickHandler","skipFirst","target","showDropdown","overlay","chevronEl","CHEVRON_EXPANDED","isDropdownOpen","createLayerController","config","layerPreviewOverlay","escapeHandler","dropdownSourceLayer","clearLayerPreview","showLayerPreview","layer","getElementSelectorId","selectLayer","closeDropdown","firstOverlay","attachToOverlay","restoreSelection","handleLabelClick","e","label","element","layers","currentId","isDropdownOpen","ev","showDropdown","overlay","buildLayerChain","enhanceLabelWithChevron","FOCUS_STYLE_ID","EDITABLE_TAGS","isStaticArrayTextElement","element","passesStructuralChecks","injectFocusOutlineCSS","style","removeFocusOutlineCSS","selectText","range","selection","isEditableTextElement","shouldEnterInlineEditingMode","DEBOUNCE_MS","createInlineEditController","host","currentEditingElement","debouncedSendTimeout","enabled","listenerAbortControllers","repositionOverlays","selectedId","elements","overlay","i","reportEdit","element","originalContent","newContent","svgElement","rect","message","isStaticArrayTextElement","debouncedReport","onTextInput","handleInputEvent","makeEditable","injectFocusOutlineCSS","PLUGIN_ELEMENT_ATTR","abortController","selectText","makeNonEditable","removeFocusOutlineCSS","value","shouldEnterInlineEditingMode","o","el","elementId","data","THEME_FONT_PREVIEW_ID","createPageHeightBridgeController","vhCleanups","vhForceRun","pendingResponse","pendingOrigin","override","referenceVhBase","resolveReferenceVhBase","startVhNeutralizer","origin","settleMs","height","measureContentHeight","c","detected","cleanups","VH_RE","processedStyles","processedSheets","watchedStyles","styleObservers","debouncer","createDebouncer","rewrite","input","_match","n","el","watchStyleEl","text","next","i","sheet","rules","rewriteVhInRules","debouncedNeutralize","obs","headObserver","mutations","m","containsStylesheetNode","attachHeadObserver","rule","style","j","prop","value","nodes","node","fn","delayMs","timer","REPOSITION_DELAY_MS","setupVisualEditAgent","pageHeightBridge","createPageHeightBridgeController","isVisualEditMode","isPopoverDragging","isDropdownOpen","hoverOverlays","selectedOverlays","currentHighlightedElements","selectedElementId","selectedElement","createOverlay","isSelected","overlay","positionOverlay","element","rect","label","positionLabel","inlineEdit","createInlineEditController","findElementsById","clearSelectedOverlays","elements","elementId","el","clearSelection","clearHoverOverlays","TEXT_TAGS","notifyElementSelected","htmlElement","svgElement","isTextElement","arrEl","staticArrayName","rawIdx","staticArrayIndex","staticArrayField","collectionEl","itemFieldEl","itemIdEl","getElementSelectorId","collectAllowedAttributes","ALLOWED_ATTRIBUTES","selectElement","visualSelectorId","notifyDeselection","lastHoveredSelectorId","pendingMouseMoveRaf","clearHoverState","applyHoverOverlays","selectorId","handleMouseMove","e","resolveHoverTarget","handleMouseLeave","handleElementClick","target","LAYER_DROPDOWN_ATTR","findInstrumentedElement","selectedOverlay","layerController","unselectElement","updateElementClassesAndReposition","classes","updateElementClasses","index","updateElementAttributeAndReposition","attribute","value","updateElementAttribute","updateElementContent","content","arrIndex","createLayerController","toggleVisualEditMode","isEnabled","stopAnimations","resumeAnimations","handleScroll","viewportHeight","viewportWidth","isInViewport","elementPosition","handleMessage","event","message","name","fontStyle","THEME_FONT_PREVIEW_ID","handleResize","htmlEl","id","mutationObserver","mutations","mutation","hasVisualId","node","i"]}
|
|
1
|
+
{"version":3,"sources":["../../src/injections/utils.ts","../../src/injections/layer-dropdown/consts.ts","../../src/injections/layer-dropdown/utils.ts","../../src/injections/layer-dropdown/dropdown-ui.ts","../../src/injections/layer-dropdown/controller.ts","../../src/capabilities/inline-edit/dom-utils.ts","../../src/capabilities/inline-edit/controller.ts","../../src/consts.ts","../../src/injections/page-height-bridge.ts","../../src/injections/visual-edit-agent.ts"],"sourcesContent":["const LABEL_HEIGHT = 27;\n\n/**\n * Positions an element-tag label relative to its highlighted overlay.\n *\n * Strategy (in priority order):\n * 1. If the element is near the viewport top AND tall enough (>= 2x label height),\n * place the label **inside** the element at the top-left.\n * 2. If the element is near the viewport top but too short, place the label\n * **below** the element.\n * 3. Otherwise, place the label **above** the element (default).\n *\n * For full-width elements (spanning nearly the entire viewport), the left offset\n * is nudged inward (6px) to prevent clipping against the viewport edge.\n *\n * @param label - The label div to position (style.top and style.left are set).\n * @param rect - The bounding client rect of the highlighted element.\n */\nexport function positionLabel(label: HTMLDivElement, rect: DOMRect): void {\n const nearTop = rect.top < LABEL_HEIGHT;\n const tallEnough = rect.height >= LABEL_HEIGHT * 2;\n const isFullWidth = rect.width >= window.innerWidth - 4;\n const edgeLeft = isFullWidth ? \"8px\" : \"-2px\";\n const insideLeft = isFullWidth ? \"8px\" : \"4px\";\n\n if (nearTop && tallEnough) {\n label.style.top = \"2px\";\n label.style.left = insideLeft;\n } else if (nearTop) {\n label.style.top = `${rect.height + 2}px`;\n label.style.left = edgeLeft;\n } else {\n label.style.top = `-${LABEL_HEIGHT}px`;\n label.style.left = edgeLeft;\n }\n}\n\n/** Check if an element has instrumentation attributes */\nexport function isInstrumentedElement(element: Element): boolean {\n const htmlEl = element as HTMLElement;\n return !!(\n htmlEl.dataset?.sourceLocation || htmlEl.dataset?.visualSelectorId\n );\n}\n\n/** Get the selector ID from an element's data attributes (prefers source-location) */\nexport function getElementSelectorId(element: Element): string | null {\n const htmlEl = element as HTMLElement;\n return (\n htmlEl.dataset?.sourceLocation ||\n htmlEl.dataset?.visualSelectorId ||\n null\n );\n}\n\nexport const ALLOWED_ATTRIBUTES: string[] = [\"src\"];\n\nexport const PLUGIN_ELEMENT_ATTR = \"data-vite-plugin-element\";\n\n/** Find elements by ID - first try data-source-location, fallback to data-visual-selector-id */\nexport function findElementsById(id: string | null): Element[] {\n if (!id) return [];\n const sourceElements = Array.from(\n document.querySelectorAll(`[data-source-location=\"${id}\"]`)\n );\n if (sourceElements.length > 0) {\n return sourceElements;\n }\n return Array.from(\n document.querySelectorAll(`[data-visual-selector-id=\"${id}\"]`)\n );\n}\n\n/**\n * Update element classes by visual selector ID.\n * Uses setAttribute instead of className to support both HTML and SVG elements.\n */\nexport function updateElementClasses(elements: Element[], classes: string): void {\n elements.forEach((element) => {\n element.setAttribute(\"class\", classes);\n });\n}\n\n/** Set a single attribute on all provided elements. */\nexport function updateElementAttribute(elements: Element[], attribute: string, value: string): void {\n if (!ALLOWED_ATTRIBUTES.includes(attribute)) {\n return;\n }\n\n elements.forEach((element) => {\n element.setAttribute(attribute, value);\n });\n}\n\n/** Collect attribute values from an element for a given allowlist. */\nexport function collectAllowedAttributes(element: Element, allowedAttributes: string[]): Record<string, string> {\n const attributes: Record<string, string> = {};\n for (const attr of allowedAttributes) {\n const val = element.getAttribute(attr);\n if (val !== null) {\n attributes[attr] = val;\n }\n }\n return attributes;\n}\n\n/**\n * Freeze all CSS animations and transitions on the page by injecting\n * scoped styles under `[data-visual-edit-active]` and programmatically\n * finishing (or pausing) every running animation.\n *\n * Plugin-owned elements (`[data-vite-plugin-element]`) are excluded so\n * the plugin UI stays animated.\n */\nexport function stopAnimations(): void {\n if (document.getElementById('freeze-animations')) return;\n\n document.documentElement.setAttribute('data-visual-edit-active', '');\n\n const animStyle = document.createElement('style');\n animStyle.id = 'freeze-animations';\n animStyle.textContent = `\n [data-visual-edit-active] *:not([${PLUGIN_ELEMENT_ATTR}]):not([${PLUGIN_ELEMENT_ATTR}] *),\n [data-visual-edit-active] *:not([${PLUGIN_ELEMENT_ATTR}]):not([${PLUGIN_ELEMENT_ATTR}] *)::before,\n [data-visual-edit-active] *:not([${PLUGIN_ELEMENT_ATTR}]):not([${PLUGIN_ELEMENT_ATTR}] *)::after {\n animation-play-state: paused !important;\n transition: none !important;\n }\n `;\n\n const pointerStyle = document.createElement('style');\n pointerStyle.id = 'freeze-pointer-events';\n pointerStyle.textContent = `\n [data-visual-edit-active] * { pointer-events: none !important; }\n [${PLUGIN_ELEMENT_ATTR}], [${PLUGIN_ELEMENT_ATTR}] * { pointer-events: auto !important; }\n `;\n\n const target = document.head || document.documentElement;\n target.appendChild(animStyle);\n target.appendChild(pointerStyle);\n\n document.getAnimations().forEach((a) => {\n // Skip animations on plugin UI elements\n const animTarget = (a.effect as KeyframeEffect)?.target;\n if (animTarget instanceof Element && animTarget.closest(`[${PLUGIN_ELEMENT_ATTR}]`)) return;\n\n try {\n a.finish(); // fast-forward to end state\n } catch {\n a.pause(); // finish() throws on infinite animations — pause instead\n }\n });\n}\n\n/**\n * Resume all previously frozen animations and remove the injected\n * freeze styles. Cleans up the `data-visual-edit-active` attribute\n * from `<html>` so scoped selectors no longer match.\n */\nexport function resumeAnimations(): void {\n const animStyle = document.getElementById('freeze-animations');\n if (!animStyle) return;\n\n animStyle.remove();\n document.getElementById('freeze-pointer-events')?.remove();\n document.documentElement.removeAttribute('data-visual-edit-active');\n\n document.getAnimations().forEach((a) => {\n if (a.playState === 'paused') {\n try { a.play(); } catch { /* animation target may have been removed */ }\n }\n });\n}\n\n/**\n * Hit-test the page at (`x`, `y`) and walk up the DOM to find the\n * nearest ancestor that carries instrumentation attributes\n * (`data-source-location` or `data-visual-selector-id`).\n *\n * Temporarily disables the pointer-events freeze sheet so the\n * browser's native `elementFromPoint` can reach the real target.\n */\nexport function findInstrumentedElement(x: number, y: number): Element | null {\n const pointerStyle = document.getElementById('freeze-pointer-events') as HTMLStyleElement | null;\n if (pointerStyle) pointerStyle.disabled = true;\n\n const el = document.elementFromPoint(x, y);\n\n if (pointerStyle) pointerStyle.disabled = false;\n\n return el?.closest('[data-source-location], [data-visual-selector-id]') ?? null;\n}\n\n/**\n * Resolve which element should be hovered at (`x`, `y`), skipping the\n * currently selected element. Returns the selector ID of the hovered\n * element, or `null` if the point is empty or hits the selected element.\n */\nexport function resolveHoverTarget(x: number, y: number, selectedElementId: string | null): string | null {\n const element = findInstrumentedElement(x, y);\n if (!element) return null;\n\n const selectorId = getElementSelectorId(element);\n\n if (selectorId === selectedElementId) return null;\n\n return selectorId;\n}\n","/** Style constants for the layer dropdown UI */\n\nexport const DROPDOWN_CONTAINER_STYLES: Record<string, string> = {\n position: \"absolute\",\n backgroundColor: \"#ffffff\",\n border: \"1px solid #e2e8f0\",\n borderRadius: \"6px\",\n boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.15)\",\n fontSize: \"12px\",\n minWidth: \"120px\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n zIndex: \"10001\",\n padding: \"4px 0\",\n pointerEvents: \"auto\",\n};\n\nexport const DROPDOWN_ITEM_BASE_STYLES: Record<string, string> = {\n padding: \"4px 12px\",\n cursor: \"pointer\",\n color: \"#334155\",\n backgroundColor: \"transparent\",\n whiteSpace: \"nowrap\",\n lineHeight: \"1.5\",\n fontWeight: \"400\",\n};\n\nexport const DROPDOWN_ITEM_ACTIVE_COLOR = \"#526cff\";\nexport const DROPDOWN_ITEM_ACTIVE_BG = \"#DBEAFE\";\nexport const DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT = \"600\";\n\nexport const DROPDOWN_ITEM_HOVER_BG = \"#f1f5f9\";\n\nexport const DEPTH_INDENT_PX = 10;\n\n/** SVG chevron shown when dropdown is collapsed (click to expand) */\nexport const CHEVRON_COLLAPSED = `<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" style=\"vertical-align:middle;margin-left:4px\"><path d=\"M6 9l6 6 6-6\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"/></svg>`;\n/** SVG chevron shown when dropdown is expanded (click to collapse) */\nexport const CHEVRON_EXPANDED = `<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" style=\"vertical-align:middle;margin-left:4px\"><path d=\"M18 15l-6-6-6 6\" stroke=\"currentColor\" stroke-width=\"2\" fill=\"none\"/></svg>`;\n\nexport const CHEVRON_ATTR = \"data-chevron\";\n\nexport const BASE_PADDING_PX = 12;\n\nexport const LAYER_DROPDOWN_ATTR = \"data-layer-dropdown\";\n\n/** Max instrumented ancestors to show above the selected element */\nexport const MAX_PARENT_DEPTH = 2;\n\n/** Max instrumented depth levels to show below the selected element */\nexport const MAX_CHILD_DEPTH = 2;\n","/** DOM utilities for the layer-dropdown module */\n\nimport { isInstrumentedElement, getElementSelectorId } from \"../utils.js\";\nimport { MAX_PARENT_DEPTH, MAX_CHILD_DEPTH } from \"./consts.js\";\n\nimport type { LayerInfo } from \"./types.js\";\n\n/** Apply a style map to an element */\nexport function applyStyles(element: HTMLElement, styles: Record<string, string>): void {\n for (const key of Object.keys(styles)) {\n element.style.setProperty(\n key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`),\n styles[key]!\n );\n }\n}\n\n/** Display name for a layer — just the real tag name */\nexport function getLayerDisplayName(layer: LayerInfo): string {\n return layer.tagName;\n}\n\nfunction toLayerInfo(element: Element, depth?: number): LayerInfo {\n const info: LayerInfo = {\n element,\n tagName: element.tagName.toLowerCase(),\n selectorId: getElementSelectorId(element),\n };\n if (depth !== undefined) info.depth = depth;\n return info;\n}\n\n/**\n * Collect instrumented descendants up to `maxDepth` instrumented nesting levels.\n * Non-instrumented wrappers are walked through without counting toward depth.\n * Results are in DOM order.\n * When `startDepth` is provided, assigns `depth` to each item during collection.\n */\nexport function getInstrumentedDescendants(\n parent: Element,\n maxDepth: number,\n startDepth?: number\n): LayerInfo[] {\n const result: LayerInfo[] = [];\n\n function walk(el: Element, instrDepth: number): void {\n if (instrDepth > maxDepth) return;\n for (let i = 0; i < el.children.length; i++) {\n const child = el.children[i]!;\n if (isInstrumentedElement(child)) {\n const info: LayerInfo = {\n element: child,\n tagName: child.tagName.toLowerCase(),\n selectorId: getElementSelectorId(child),\n };\n if (startDepth !== undefined) {\n info.depth = startDepth + instrDepth - 1;\n }\n result.push(info);\n walk(child, instrDepth + 1);\n } else {\n walk(child, instrDepth);\n }\n }\n }\n\n walk(parent, 1);\n return result;\n}\n\n/** Collect instrumented ancestors from selected element up to MAX_PARENT_DEPTH (outermost first). */\nfunction collectInstrumentedParents(selectedElement: Element): LayerInfo[] {\n const parents: LayerInfo[] = [];\n let current = selectedElement.parentElement;\n while (\n current &&\n current !== document.documentElement &&\n current !== document.body &&\n parents.length < MAX_PARENT_DEPTH\n ) {\n if (isInstrumentedElement(current)) {\n parents.push(toLayerInfo(current));\n }\n current = current.parentElement;\n }\n parents.reverse();\n return parents;\n}\n\n/** Add parents to chain with depth 0, 1, …; returns depth of selected (parents.length). */\nfunction addParentsToChain(chain: LayerInfo[], parents: LayerInfo[]): number {\n parents.forEach((p, i) => {\n chain.push({ ...p, depth: i });\n });\n return parents.length;\n}\n\n/** Add selected element and its descendants at the given depth. */\nfunction addSelfAndDescendantsToChain(\n chain: LayerInfo[],\n selectedElement: Element,\n selfDepth: number\n): void {\n chain.push(toLayerInfo(selectedElement, selfDepth));\n const descendants = getInstrumentedDescendants(\n selectedElement,\n MAX_CHILD_DEPTH,\n selfDepth + 1\n );\n chain.push(...descendants);\n}\n\n/** Get the innermost instrumented parent's DOM element, or null if none. */\nfunction getImmediateInstrParent(parents: LayerInfo[]): Element | null {\n return parents.at(-1)?.element ?? null;\n}\n\n/** Collect instrumented siblings of the selected element from its parent (DOM order). */\nfunction collectSiblings(parent: Element, selectedElement: Element): LayerInfo[] {\n const siblings = getInstrumentedDescendants(parent, 1);\n if (!siblings.some((s) => s.element === selectedElement)) {\n siblings.push(toLayerInfo(selectedElement));\n }\n return siblings;\n}\n\n/** Add siblings at selfDepth, expanding children only for the selected element. */\nfunction appendSiblingsWithSelected(\n chain: LayerInfo[],\n siblings: LayerInfo[],\n selectedElement: Element,\n selfDepth: number\n): void {\n const selectedSelectorId = getElementSelectorId(selectedElement);\n const seen = new Set<string>();\n for (const sibling of siblings) {\n if (sibling.element === selectedElement) {\n addSelfAndDescendantsToChain(chain, selectedElement, selfDepth);\n if (selectedSelectorId) seen.add(selectedSelectorId);\n } else {\n const id = sibling.selectorId;\n if (id != null) {\n if (id === selectedSelectorId || seen.has(id)) continue;\n seen.add(id);\n }\n chain.push({ ...sibling, depth: selfDepth });\n }\n }\n}\n\n/**\n * Build the layer chain for the dropdown:\n *\n * Parents – up to MAX_PARENT_DEPTH instrumented ancestors, outer → inner.\n * Siblings – instrumented children of the immediate parent, at the same depth.\n * Current – the selected element (highlighted), with children expanded.\n * Children – instrumented descendants within MAX_CHILD_DEPTH levels, DOM order.\n *\n * Each item carries a `depth` for visual indentation.\n */\nexport function buildLayerChain(selectedElement: Element): LayerInfo[] {\n const parents = collectInstrumentedParents(selectedElement);\n const chain: LayerInfo[] = [];\n const selfDepth = addParentsToChain(chain, parents);\n\n const instrParent = getImmediateInstrParent(parents);\n if (instrParent) {\n const siblings = collectSiblings(instrParent, selectedElement);\n appendSiblingsWithSelected(chain, siblings, selectedElement, selfDepth);\n } else {\n addSelfAndDescendantsToChain(chain, selectedElement, selfDepth);\n }\n\n return chain;\n}\n","/** Dropdown UI component for layer navigation */\n\nimport {\n DROPDOWN_CONTAINER_STYLES,\n DROPDOWN_ITEM_BASE_STYLES,\n DROPDOWN_ITEM_ACTIVE_COLOR,\n DROPDOWN_ITEM_ACTIVE_BG,\n DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT,\n DROPDOWN_ITEM_HOVER_BG,\n DEPTH_INDENT_PX,\n BASE_PADDING_PX,\n CHEVRON_COLLAPSED,\n CHEVRON_EXPANDED,\n CHEVRON_ATTR,\n LAYER_DROPDOWN_ATTR,\n} from \"./consts.js\";\nimport { applyStyles, getLayerDisplayName } from \"./utils.js\";\nimport type { LayerInfo, DropdownCallbacks } from \"./types.js\";\nimport { PLUGIN_ELEMENT_ATTR } from \"../utils.js\";\n\nlet activeDropdown: HTMLDivElement | null = null;\nlet activeLabel: HTMLDivElement | null = null;\nlet outsideMousedownHandler: ((e: MouseEvent) => void) | null = null;\nlet activeOnHoverEnd: (() => void) | null = null;\nlet activeKeydownHandler: ((e: KeyboardEvent) => void) | null = null;\n\nfunction createDropdownItem(\n layer: LayerInfo,\n isActive: boolean,\n { onSelect, onHover, onHoverEnd }: DropdownCallbacks\n): HTMLDivElement {\n const item = document.createElement(\"div\");\n item.textContent = getLayerDisplayName(layer);\n applyStyles(item, DROPDOWN_ITEM_BASE_STYLES);\n\n const depth = layer.depth ?? 0;\n if (depth > 0) {\n item.style.paddingLeft = `${BASE_PADDING_PX + depth * DEPTH_INDENT_PX}px`;\n }\n\n if (isActive) {\n item.style.color = DROPDOWN_ITEM_ACTIVE_COLOR;\n item.style.backgroundColor = DROPDOWN_ITEM_ACTIVE_BG;\n item.style.fontWeight = DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT;\n }\n\n item.addEventListener(\"mouseenter\", () => {\n if (!isActive) item.style.backgroundColor = DROPDOWN_ITEM_HOVER_BG;\n if (onHover) onHover(layer);\n });\n\n item.addEventListener(\"mouseleave\", () => {\n if (!isActive) item.style.backgroundColor = \"transparent\";\n if (onHoverEnd) onHoverEnd();\n });\n\n item.addEventListener(\"click\", (e: MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n onSelect(layer);\n });\n\n return item;\n}\n\n/** Create the dropdown DOM element with layer items */\nexport function createDropdownElement(\n layers: LayerInfo[],\n currentElement: Element | null,\n callbacks: DropdownCallbacks\n): HTMLDivElement {\n const container = document.createElement(\"div\");\n container.setAttribute(LAYER_DROPDOWN_ATTR, \"true\");\n container.setAttribute(PLUGIN_ELEMENT_ATTR, \"true\");\n applyStyles(container, DROPDOWN_CONTAINER_STYLES);\n\n layers.forEach((layer) => {\n const isActive = layer.element === currentElement;\n container.appendChild(createDropdownItem(layer, isActive, callbacks));\n });\n\n return container;\n}\n\n/** Add chevron indicator and pointer-events to the label */\nexport function enhanceLabelWithChevron(label: HTMLDivElement): void {\n if (label.querySelector(`[${CHEVRON_ATTR}]`)) return;\n\n const chevron = document.createElement(\"span\");\n chevron.setAttribute(CHEVRON_ATTR, \"true\");\n chevron.style.display = \"inline-flex\";\n chevron.innerHTML = CHEVRON_COLLAPSED;\n label.appendChild(chevron);\n\n label.style.display = \"inline-flex\";\n label.style.alignItems = \"center\";\n label.style.cursor = \"pointer\";\n label.style.userSelect = \"none\";\n label.style.whiteSpace = \"nowrap\";\n label.style.pointerEvents = \"auto\";\n label.setAttribute(LAYER_DROPDOWN_ATTR, \"true\");\n label.setAttribute(PLUGIN_ELEMENT_ATTR, \"true\");\n}\n\nfunction setupKeyboardNavigation(\n dropdown: HTMLDivElement,\n layers: LayerInfo[],\n currentElement: Element | null,\n { onSelect, onHover, onHoverEnd }: DropdownCallbacks\n): void {\n const items = Array.from(dropdown.children) as HTMLDivElement[];\n let focusedIndex = layers.findIndex((l) => l.element === currentElement);\n\n const setFocusedItem = (index: number) => {\n if (focusedIndex >= 0 && focusedIndex < items.length) {\n const prev = items[focusedIndex]!;\n if (prev.style.color !== DROPDOWN_ITEM_ACTIVE_COLOR) {\n prev.style.backgroundColor = \"transparent\";\n }\n }\n focusedIndex = index;\n if (focusedIndex >= 0 && focusedIndex < items.length) {\n const cur = items[focusedIndex]!;\n if (cur.style.color !== DROPDOWN_ITEM_ACTIVE_COLOR) {\n cur.style.backgroundColor = DROPDOWN_ITEM_HOVER_BG;\n }\n cur.scrollIntoView({ block: \"nearest\" });\n if (onHover && focusedIndex >= 0 && focusedIndex < layers.length) {\n onHover(layers[focusedIndex]!);\n }\n }\n };\n\n activeKeydownHandler = (e: KeyboardEvent) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n e.stopPropagation();\n setFocusedItem(focusedIndex < items.length - 1 ? focusedIndex + 1 : 0);\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n e.stopPropagation();\n setFocusedItem(focusedIndex > 0 ? focusedIndex - 1 : items.length - 1);\n } else if (e.key === \"Enter\" && focusedIndex >= 0 && focusedIndex < layers.length) {\n e.preventDefault();\n e.stopPropagation();\n if (onHoverEnd) onHoverEnd();\n onSelect(layers[focusedIndex]!);\n closeDropdown();\n }\n };\n document.addEventListener(\"keydown\", activeKeydownHandler, true);\n}\n\nfunction setupOutsideClickHandler(\n dropdown: HTMLDivElement,\n label: HTMLDivElement\n): void {\n let skipFirst = true;\n outsideMousedownHandler = (e: MouseEvent) => {\n if (skipFirst) { skipFirst = false; return; }\n const target = e.target as Node;\n if (!dropdown.contains(target) && target !== label) {\n closeDropdown();\n }\n };\n document.addEventListener(\"mousedown\", outsideMousedownHandler, true);\n}\n\n/** Show the dropdown below the label element */\nexport function showDropdown(\n label: HTMLDivElement,\n layers: LayerInfo[],\n currentElement: Element | null,\n callbacks: DropdownCallbacks\n): void {\n closeDropdown();\n\n const dropdown = createDropdownElement(\n layers,\n currentElement,\n {\n ...callbacks,\n onSelect: (layer) => {\n if (callbacks.onHoverEnd) callbacks.onHoverEnd();\n callbacks.onSelect(layer);\n closeDropdown();\n },\n }\n );\n\n const overlay = label.parentElement;\n if (!overlay) return;\n\n dropdown.style.top = `${label.offsetTop + label.offsetHeight + 2}px`;\n dropdown.style.left = `${label.offsetLeft}px`;\n\n overlay.appendChild(dropdown);\n activeDropdown = dropdown;\n activeLabel = label;\n const chevronEl = label.querySelector(`[${CHEVRON_ATTR}]`);\n if (chevronEl) {\n chevronEl.innerHTML = CHEVRON_EXPANDED;\n }\n activeOnHoverEnd = callbacks.onHoverEnd ?? null;\n\n setupKeyboardNavigation(dropdown, layers, currentElement, callbacks);\n setupOutsideClickHandler(dropdown, label);\n}\n\n/** Close the active dropdown and clean up listeners */\nexport function closeDropdown(): void {\n const chevronEl = activeLabel?.querySelector(`[${CHEVRON_ATTR}]`);\n if (chevronEl) {\n chevronEl.innerHTML = CHEVRON_COLLAPSED;\n }\n activeLabel = null;\n\n if (activeOnHoverEnd) {\n activeOnHoverEnd();\n activeOnHoverEnd = null;\n }\n\n if (activeDropdown && activeDropdown.parentNode) {\n activeDropdown.remove();\n }\n activeDropdown = null;\n\n if (outsideMousedownHandler) {\n document.removeEventListener(\"mousedown\", outsideMousedownHandler, true);\n outsideMousedownHandler = null;\n }\n\n if (activeKeydownHandler) {\n document.removeEventListener(\"keydown\", activeKeydownHandler, true);\n activeKeydownHandler = null;\n }\n}\n\n/** Check if a dropdown is currently visible */\nexport function isDropdownOpen(): boolean {\n return activeDropdown !== null;\n}\n","/** Controller that encapsulates layer-dropdown integration logic */\n\nimport { getElementSelectorId } from \"../utils.js\";\nimport { buildLayerChain } from \"./utils.js\";\nimport {\n enhanceLabelWithChevron,\n showDropdown,\n closeDropdown,\n isDropdownOpen,\n} from \"./dropdown-ui.js\";\nimport type { LayerInfo, LayerControllerConfig, LayerController } from \"./types.js\";\n\nexport function createLayerController(config: LayerControllerConfig): LayerController {\n let layerPreviewOverlay: HTMLDivElement | null = null;\n let escapeHandler: ((e: KeyboardEvent) => void) | null = null;\n let dropdownSourceLayer: LayerInfo | null = null;\n\n const clearLayerPreview = () => {\n if (layerPreviewOverlay && layerPreviewOverlay.parentNode) {\n layerPreviewOverlay.remove();\n }\n layerPreviewOverlay = null;\n };\n\n const showLayerPreview = (layer: LayerInfo) => {\n clearLayerPreview();\n if (getElementSelectorId(layer.element) === config.getSelectedElementId()) return;\n\n layerPreviewOverlay = config.createPreviewOverlay(layer.element);\n };\n\n const selectLayer = (layer: LayerInfo) => {\n clearLayerPreview();\n closeDropdown();\n if (escapeHandler) {\n document.removeEventListener(\"keydown\", escapeHandler, true);\n escapeHandler = null;\n }\n dropdownSourceLayer = null;\n\n const firstOverlay = config.selectElement(layer.element);\n attachToOverlay(firstOverlay, layer.element);\n };\n\n const restoreSelection = () => {\n if (escapeHandler) {\n document.removeEventListener(\"keydown\", escapeHandler, true);\n escapeHandler = null;\n }\n if (dropdownSourceLayer) {\n selectLayer(dropdownSourceLayer);\n dropdownSourceLayer = null;\n }\n };\n\n const handleLabelClick = (e: MouseEvent, label: HTMLDivElement, element: Element, layers: LayerInfo[], currentId: string | null) => {\n e.stopPropagation();\n e.preventDefault();\n if (isDropdownOpen()) {\n closeDropdown();\n restoreSelection();\n } else {\n dropdownSourceLayer = {\n element,\n tagName: element.tagName.toLowerCase(),\n selectorId: currentId,\n };\n config.onDeselect();\n\n escapeHandler = (ev: KeyboardEvent) => {\n if (ev.key === \"Escape\") {\n ev.stopPropagation();\n closeDropdown();\n restoreSelection();\n }\n };\n document.addEventListener(\"keydown\", escapeHandler, true);\n\n showDropdown(label, layers, element, { onSelect: selectLayer, onHover: showLayerPreview, onHoverEnd: clearLayerPreview });\n }\n };\n\n const attachToOverlay = (\n overlay: HTMLDivElement | undefined,\n element: Element\n ) => {\n if (!overlay) return;\n\n const label = overlay.querySelector(\"div\") as HTMLDivElement | null;\n if (!label) return;\n\n const layers = buildLayerChain(element);\n if (layers.length <= 1) return;\n\n const currentId = getElementSelectorId(element);\n enhanceLabelWithChevron(label);\n\n label.addEventListener(\"click\", (e: MouseEvent) => {\n handleLabelClick(e, label, element, layers, currentId);\n });\n };\n\n const cleanup = () => {\n clearLayerPreview();\n closeDropdown();\n };\n\n return { attachToOverlay, cleanup };\n}\n","const FOCUS_STYLE_ID = \"visual-edit-focus-styles\";\n\nconst EDITABLE_TAGS = [\n \"div\", \"p\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\",\n \"span\", \"li\", \"td\", \"a\", \"button\", \"label\",\n];\n\nexport const isStaticArrayTextElement = (element: HTMLElement): boolean => {\n return !!element.dataset.arrField;\n};\n\nconst passesStructuralChecks = (element: HTMLElement): boolean => {\n if (!EDITABLE_TAGS.includes(element.tagName.toLowerCase())) return false;\n if (!element.textContent?.trim()) return false;\n if (element.querySelector(\"img, video, canvas, svg\")) return false;\n if (element.children?.length > 0) return false;\n return true;\n};\n\nexport const injectFocusOutlineCSS = () => {\n if (document.getElementById(FOCUS_STYLE_ID)) return;\n\n const style = document.createElement(\"style\");\n style.id = FOCUS_STYLE_ID;\n style.textContent = `\n [data-selected=\"true\"][contenteditable=\"true\"]:focus {\n outline: none !important;\n }\n `;\n document.head.appendChild(style);\n};\n\nexport const removeFocusOutlineCSS = () => {\n document.getElementById(FOCUS_STYLE_ID)?.remove();\n};\n\nexport const selectText = (element: HTMLElement) => {\n const range = document.createRange();\n range.selectNodeContents(element);\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(range);\n};\n\nexport const isEditableTextElement = (element: Element): boolean => {\n if (!(element instanceof HTMLElement)) return false;\n if (!passesStructuralChecks(element)) return false;\n if (isStaticArrayTextElement(element)) return true;\n if (element.dataset.dynamicContent === \"true\") return false;\n return true;\n};\n\nexport const shouldEnterInlineEditingMode = (element: Element): boolean => {\n if (!(element instanceof HTMLElement) || element.dataset.selected !== \"true\") {\n return false;\n }\n return isEditableTextElement(element);\n};\n","import type { InlineEditHost, InlineEditController } from \"./types.js\";\nimport {\n injectFocusOutlineCSS,\n removeFocusOutlineCSS,\n selectText,\n shouldEnterInlineEditingMode,\n isStaticArrayTextElement,\n} from \"./dom-utils.js\";\nimport { PLUGIN_ELEMENT_ATTR } from \"../../injections/utils.js\";\n\nconst DEBOUNCE_MS = 500;\n\nexport function createInlineEditController(\n host: InlineEditHost\n): InlineEditController {\n let currentEditingElement: HTMLElement | null = null;\n let debouncedSendTimeout: ReturnType<typeof setTimeout> | null = null;\n let enabled = false;\n const listenerAbortControllers = new WeakMap<HTMLElement, AbortController>();\n\n // --- Private helpers ---\n\n const repositionOverlays = () => {\n const selectedId = host.getSelectedElementId();\n if (!selectedId) return;\n const elements = host.findElementsById(selectedId);\n const overlays = host.getSelectedOverlays();\n overlays.forEach((overlay, i) => {\n if (i < elements.length && elements[i]) {\n host.positionOverlay(overlay, elements[i]);\n }\n });\n };\n\n const reportEdit = (element: HTMLElement) => {\n const originalContent = element.dataset.originalTextContent;\n const newContent = element.textContent;\n\n const svgElement = element as unknown as SVGElement;\n const rect = element.getBoundingClientRect();\n\n const message: Record<string, unknown> = {\n type: \"inline-edit\",\n elementInfo: {\n tagName: element.tagName,\n classes:\n (svgElement.className as unknown as SVGAnimatedString)?.baseVal ||\n element.className ||\n \"\",\n visualSelectorId: host.getSelectedElementId(),\n content: newContent,\n dataSourceLocation: element.dataset.sourceLocation,\n isDynamicContent: element.dataset.dynamicContent === \"true\",\n linenumber: element.dataset.linenumber,\n filename: element.dataset.filename,\n position: {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n centerX: rect.left + rect.width / 2,\n centerY: rect.top + rect.height / 2,\n },\n },\n originalContent,\n newContent,\n };\n\n if (isStaticArrayTextElement(element)) {\n message.arrIndex = element.dataset.arrIndex;\n message.arrVariableName = element.dataset.arrVariableName;\n message.arrField = element.dataset.arrField;\n }\n\n window.parent.postMessage(message, \"*\");\n\n element.dataset.originalTextContent = newContent || \"\";\n };\n\n const debouncedReport = (element: HTMLElement) => {\n if (debouncedSendTimeout) clearTimeout(debouncedSendTimeout);\n debouncedSendTimeout = setTimeout(() => reportEdit(element), DEBOUNCE_MS);\n };\n\n const onTextInput = (element: HTMLElement) => {\n repositionOverlays();\n debouncedReport(element);\n };\n\n const handleInputEvent = function (this: HTMLElement) {\n onTextInput(this);\n };\n\n const makeEditable = (element: HTMLElement) => {\n injectFocusOutlineCSS();\n\n element.dataset.originalTextContent = element.textContent || \"\";\n element.dataset.originalCursor = element.style.cursor;\n element.contentEditable = \"true\";\n element.setAttribute(PLUGIN_ELEMENT_ATTR, \"true\");\n\n const abortController = new AbortController();\n listenerAbortControllers.set(element, abortController);\n element.addEventListener(\"input\", handleInputEvent, {\n signal: abortController.signal,\n });\n\n element.style.cursor = \"text\";\n selectText(element);\n setTimeout(() => {\n if (element.isConnected) {\n element.focus();\n }\n }, 0);\n };\n\n const makeNonEditable = (element: HTMLElement) => {\n const abortController = listenerAbortControllers.get(element);\n if (abortController) {\n abortController.abort();\n listenerAbortControllers.delete(element);\n }\n\n if (!element.isConnected) return;\n\n removeFocusOutlineCSS();\n element.contentEditable = \"false\";\n element.removeAttribute(PLUGIN_ELEMENT_ATTR);\n delete element.dataset.originalTextContent;\n\n if (element.dataset.originalCursor !== undefined) {\n element.style.cursor = element.dataset.originalCursor;\n delete element.dataset.originalCursor;\n }\n };\n\n // --- Public API ---\n\n return {\n get enabled() {\n return enabled;\n },\n set enabled(value: boolean) {\n enabled = value;\n },\n\n isEditing() {\n return currentEditingElement !== null;\n },\n\n getCurrentElement() {\n return currentEditingElement;\n },\n\n canEdit(element: Element) {\n return shouldEnterInlineEditingMode(element);\n },\n\n startEditing(element: HTMLElement) {\n currentEditingElement = element;\n\n host.getSelectedOverlays().forEach((o) => {\n o.style.display = \"none\";\n });\n\n makeEditable(element);\n\n window.parent.postMessage(\n {\n type: \"content-editing-started\",\n visualSelectorId: host.getSelectedElementId(),\n },\n \"*\"\n );\n },\n\n stopEditing() {\n if (!currentEditingElement) return;\n\n if (debouncedSendTimeout) {\n clearTimeout(debouncedSendTimeout);\n debouncedSendTimeout = null;\n }\n\n const element = currentEditingElement;\n makeNonEditable(element);\n\n host.getSelectedOverlays().forEach((o) => {\n o.style.display = \"\";\n });\n\n repositionOverlays();\n\n window.parent.postMessage(\n {\n type: \"content-editing-ended\",\n visualSelectorId: host.getSelectedElementId(),\n },\n \"*\"\n );\n\n currentEditingElement = null;\n },\n\n markElementsSelected(elements: Element[]) {\n elements.forEach((el) => {\n if (el instanceof HTMLElement) {\n el.dataset.selected = \"true\";\n }\n });\n },\n\n clearSelectedMarks(elementId: string | null) {\n if (!elementId) return;\n host.findElementsById(elementId).forEach((el) => {\n if (el instanceof HTMLElement) {\n delete el.dataset.selected;\n }\n });\n },\n\n handleToggleMessage(data: { dataSourceLocation: string; inlineEditingMode: boolean }) {\n if (!enabled) return;\n\n const elements = host.findElementsById(data.dataSourceLocation);\n if (elements.length === 0 || !(elements[0] instanceof HTMLElement)) return;\n\n const element = elements[0];\n\n if (data.inlineEditingMode) {\n if (!shouldEnterInlineEditingMode(element)) return;\n\n // Select the element first if not already selected\n if (host.getSelectedElementId() !== data.dataSourceLocation) {\n this.stopEditing();\n host.clearSelection();\n this.markElementsSelected(elements);\n host.createSelectionOverlays(elements, data.dataSourceLocation);\n }\n this.startEditing(element);\n } else {\n if (currentEditingElement === element) {\n this.stopEditing();\n }\n }\n },\n\n cleanup() {\n this.stopEditing();\n },\n };\n}\n","export const DATA_COLLECTION_ID = \"data-collection-id\";\nexport const DATA_COLLECTION_ITEM_ID = \"data-collection-item-id\";\nexport const DATA_COLLECTION_ITEM_FIELD = \"data-collection-item-field\";\nexport const DATA_COLLECTION_REFERENCE = \"data-collection-reference\";\nexport const DATA_ARR_INDEX = \"data-arr-index\";\nexport const DATA_ARR_VARIABLE_NAME = \"data-arr-variable-name\";\nexport const DATA_ARR_FIELD = \"data-arr-field\";\n\nexport const ALLOWED_CUSTOM_COMPONENTS = [\"Image\", \"Link\"];\nexport const MAX_JSX_DEPTH = 10;\nexport const EXCLUDED_FIELDS = [\"children\", \"length\"];\nexport const THEME_FONT_PREVIEW_ID = \"__theme-font-preview\";\n","// page-height-bridge — postMessage protocol the iframe exposes to its parent.\n// Inert until the parent posts a message; no observers, rewrites, or timers\n// fire on their own.\n//\n// parent → child { type: \"freeze-vh-units\", referenceVhBase?: number }\n// Rewrites every `vh` in <style> + CSSOM to a CSS variable-backed\n// expression (kills the vh ↔ auto-resize feedback loop). Repeated calls\n// update the variable, so callers can rebase without recovering raw CSS.\n// Idempotent; covers HMR-added styles too. Fire-and-forget.\n//\n// parent → child { type: \"measure-page-height\", settleMs?: number }\n// After `settleMs` (default 2000) posts the page's measured content height\n// as `{ type: \"page-height-measured\", height }` to the requester.\n\ntype IncomingMessage = {\n type?: string;\n settleMs?: number;\n referenceVhBase?: number;\n};\n\ntype IndexableCssRule = CSSRule & {\n cssRules?: CSSRuleList;\n style?: CSSStyleDeclaration;\n};\n\ntype Debouncer = { trigger: () => void; cancel: () => void };\n\nexport type PageHeightBridgeController = {\n freezeVhUnits: (override?: number) => void;\n measurePageHeight: (origin: string, settleMs?: number) => void;\n teardown: () => void;\n};\n\nconst FALLBACK_VHBASE: number = 900;\nconst MIN_VHBASE: number = 400;\nconst DEFAULT_SETTLE_MS: number = 2000;\nconst NEUTRALIZE_DEBOUNCE_MS: number = 16;\nconst REFERENCE_VH_BASE_VAR: string = \"--base44-reference-vh-base\";\n\nconst noop: () => void = (): void => {};\n\nlet started: boolean = false;\n\n/**\n * Installs the parent-driven message listener. Returns a teardown that\n * removes the listener, disconnects any observers attached as a result of\n * `freeze-vh-units`, and clears any pending response timer. Returns a\n * no-op when bailed (already started, SSR, top window).\n */\nexport function setupPageHeightBridge(): () => void {\n if (started) return noop;\n if (typeof window === \"undefined\") return noop;\n if (window.self === window.top) return noop;\n started = true;\n\n const controller: PageHeightBridgeController = createPageHeightBridgeController();\n\n const onMessage = (event: MessageEvent): void => {\n const data: IncomingMessage | null = (event.data ?? null) as IncomingMessage | null;\n if (!data || typeof data !== \"object\") return;\n switch (data.type) {\n case \"freeze-vh-units\": {\n const override: number | undefined =\n typeof data.referenceVhBase === \"number\" ? data.referenceVhBase : undefined;\n controller.freezeVhUnits(override);\n return;\n }\n case \"measure-page-height\": {\n const settleMs: number =\n typeof data.settleMs === \"number\" ? data.settleMs : DEFAULT_SETTLE_MS;\n const origin: string =\n event.origin && event.origin !== \"null\" ? event.origin : \"*\";\n controller.measurePageHeight(origin, settleMs);\n return;\n }\n }\n };\n\n window.addEventListener(\"message\", onMessage);\n\n let torn: boolean = false;\n return (): void => {\n if (torn) return;\n torn = true;\n started = false;\n window.removeEventListener(\"message\", onMessage);\n controller.teardown();\n };\n}\n\nexport function createPageHeightBridgeController(): PageHeightBridgeController {\n let vhCleanups: Array<() => void> | null = null;\n let vhForceRun: (() => void) | null = null;\n let pendingResponse: number | undefined;\n let pendingOrigin: string = \"*\";\n\n return {\n freezeVhUnits: (override: number | undefined): void => {\n const referenceVhBase: number = resolveReferenceVhBase(override);\n setReferenceVhBase(referenceVhBase);\n if (vhCleanups) {\n vhForceRun?.();\n return;\n }\n vhCleanups = [];\n vhForceRun = startVhNeutralizer(vhCleanups);\n },\n\n // Target the requester's origin so the height isn't broadcast to anyone\n // who happens to embed us. Falls back to \"*\" when origin is unavailable\n // (jsdom default, sandboxed iframes with `null` origin).\n measurePageHeight: (origin: string, settleMs: number = DEFAULT_SETTLE_MS): void => {\n pendingOrigin = origin;\n if (pendingResponse !== undefined) window.clearTimeout(pendingResponse);\n pendingResponse = window.setTimeout((): void => {\n requestAnimationFrame((): void => {\n const height: number = measureContentHeight();\n window.parent.postMessage({ type: \"page-height-measured\", height }, pendingOrigin);\n });\n }, settleMs);\n },\n\n teardown: (): void => {\n if (vhCleanups) {\n for (const c of vhCleanups) c();\n vhCleanups = null;\n vhForceRun = null;\n }\n if (pendingResponse !== undefined) window.clearTimeout(pendingResponse);\n },\n };\n}\n\nfunction resolveReferenceVhBase(override: number | undefined): number {\n if (override !== undefined) return override;\n const detected: number = window.innerHeight || 0;\n return detected >= MIN_VHBASE ? detected : FALLBACK_VHBASE;\n}\n\nfunction setReferenceVhBase(referenceVhBase: number): void {\n document.documentElement.style.setProperty(REFERENCE_VH_BASE_VAR, `${referenceVhBase}px`);\n}\n\n// Caches keep work proportional to *new* CSS, not total CSS. <head> observer\n// catches `<style>`/`<link>` adds; per-element observers catch HMR text edits.\n// Returns a `forceRun` so the caller can re-trigger neutralization on later\n// parent requests (idempotent — already-rewritten text is skipped via the\n// processed sets).\nfunction startVhNeutralizer(cleanups: Array<() => void>): () => void {\n const VH_RE: RegExp = /(\\d+(?:\\.\\d+)?)vh\\b/g;\n const processedStyles: WeakSet<HTMLStyleElement> = new WeakSet();\n const processedSheets: WeakMap<CSSStyleSheet, number> = new WeakMap();\n const watchedStyles: WeakSet<HTMLStyleElement> = new WeakSet();\n const styleObservers: Set<MutationObserver> = new Set();\n\n const neutralize = (): void => {\n const rewrite = (input: string): string =>\n input.replace(VH_RE, (_match: string, n: string): string =>\n `calc(var(${REFERENCE_VH_BASE_VAR}) * ${formatVhFactor(n)})`,\n );\n\n document.querySelectorAll<HTMLStyleElement>(\"style\").forEach((el: HTMLStyleElement): void => {\n watchStyleEl(el);\n if (processedStyles.has(el)) return;\n processedStyles.add(el);\n const text: string | null = el.textContent;\n if (!text || text.indexOf(\"vh\") === -1) return;\n const next: string = rewrite(text);\n if (next !== text) el.textContent = next;\n });\n\n for (let i: number = 0; i < document.styleSheets.length; i++) {\n const sheet: CSSStyleSheet | undefined = document.styleSheets[i];\n if (!sheet) continue;\n let rules: CSSRuleList;\n try {\n rules = sheet.cssRules;\n } catch {\n continue; // CORS-protected\n }\n if (processedSheets.get(sheet) === rules.length) continue;\n rewriteVhInRules(rules, rewrite);\n processedSheets.set(sheet, rules.length);\n }\n };\n\n const debouncer: Debouncer = createDebouncer(neutralize, NEUTRALIZE_DEBOUNCE_MS);\n const debouncedNeutralize: () => void = debouncer.trigger;\n cleanups.push(debouncer.cancel);\n\n const watchStyleEl = (el: HTMLStyleElement): void => {\n if (watchedStyles.has(el)) return;\n watchedStyles.add(el);\n const obs: MutationObserver = new MutationObserver((): void => {\n processedStyles.delete(el);\n debouncedNeutralize();\n });\n obs.observe(el, { characterData: true, childList: true, subtree: true });\n styleObservers.add(obs);\n };\n cleanups.push((): void => {\n for (const obs of styleObservers) obs.disconnect();\n styleObservers.clear();\n });\n\n debouncedNeutralize();\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", debouncedNeutralize);\n cleanups.push((): void => document.removeEventListener(\"DOMContentLoaded\", debouncedNeutralize));\n }\n window.addEventListener(\"load\", debouncedNeutralize);\n cleanups.push((): void => window.removeEventListener(\"load\", debouncedNeutralize));\n\n const headObserver: MutationObserver = new MutationObserver((mutations: MutationRecord[]): void => {\n for (const m of mutations) {\n if (containsStylesheetNode(m.addedNodes) || containsStylesheetNode(m.removedNodes)) {\n debouncedNeutralize();\n return;\n }\n }\n });\n cleanups.push((): void => headObserver.disconnect());\n\n const attachHeadObserver = (): void => {\n if (document.head) headObserver.observe(document.head, { childList: true, subtree: false });\n };\n if (document.head) {\n attachHeadObserver();\n } else {\n document.addEventListener(\"DOMContentLoaded\", attachHeadObserver);\n cleanups.push((): void => document.removeEventListener(\"DOMContentLoaded\", attachHeadObserver));\n }\n\n return debouncedNeutralize;\n}\n\nfunction formatVhFactor(value: string): string {\n return String(Number((parseFloat(value) / 100).toFixed(6)));\n}\n\nfunction rewriteVhInRules(rules: CSSRuleList, rewrite: (value: string) => string): void {\n for (let i: number = 0; i < rules.length; i++) {\n const rule: IndexableCssRule | undefined = rules[i] as IndexableCssRule | undefined;\n if (!rule) continue;\n if (rule.cssRules) rewriteVhInRules(rule.cssRules, rewrite);\n const style: CSSStyleDeclaration | undefined = rule.style;\n if (!style) continue;\n for (let j: number = 0; j < style.length; j++) {\n const prop: string | undefined = style[j];\n if (!prop) continue;\n const value: string = style.getPropertyValue(prop);\n if (!value || value.indexOf(\"vh\") === -1) continue;\n const next: string = rewrite(value);\n if (next !== value) style.setProperty(prop, next, style.getPropertyPriority(prop));\n }\n }\n}\n\nfunction containsStylesheetNode(nodes: NodeList): boolean {\n for (let i: number = 0; i < nodes.length; i++) {\n const node: Node | undefined = nodes[i];\n if (node instanceof HTMLStyleElement || node instanceof HTMLLinkElement) return true;\n }\n return false;\n}\n\nfunction measureContentHeight(): number {\n const scrollHeight: number = Math.max(\n document.documentElement.scrollHeight,\n document.body?.scrollHeight ?? 0,\n );\n const viewportHeight: number = Math.max(\n window.innerHeight || 0,\n document.documentElement.clientHeight,\n document.body?.clientHeight ?? 0,\n );\n const contentBottom: number = measureElementContentBottom(viewportHeight);\n const referenceVhBase: number = readReferenceVhBase();\n if (contentBottom > 0) return Math.ceil(Math.max(contentBottom, referenceVhBase));\n return Math.ceil(Math.max(scrollHeight, referenceVhBase));\n}\n\nfunction readReferenceVhBase(): number {\n const value: string = document.documentElement.style.getPropertyValue(REFERENCE_VH_BASE_VAR);\n const parsed: number = parseFloat(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction measureElementContentBottom(viewportHeight: number): number {\n if (!document.body) return 0;\n const elements: Element[] = [document.body, ...Array.from(document.body.querySelectorAll(\"*\"))];\n const contentBottoms: WeakMap<Element, number> = new WeakMap();\n const viewportBottom: number = window.scrollY + viewportHeight;\n\n for (let i: number = elements.length - 1; i >= 0; i--) {\n const el: Element | undefined = elements[i];\n if (!el) continue;\n const childContentBottom: number = readChildrenContentBottom(el, contentBottoms);\n const rawBottom: number = readElementBottom(el);\n const selfBottom: number = isViewportStretchedContainer(rawBottom, childContentBottom, viewportBottom)\n ? 0\n : rawBottom;\n contentBottoms.set(el, Math.max(childContentBottom, selfBottom));\n }\n\n return contentBottoms.get(document.body) ?? 0;\n}\n\nfunction readChildrenContentBottom(\n el: Element,\n contentBottoms: WeakMap<Element, number>,\n): number {\n let childContentBottom: number = 0;\n for (let i: number = 0; i < el.children.length; i++) {\n const child: Element | undefined = el.children[i];\n if (!child) continue;\n childContentBottom = Math.max(childContentBottom, contentBottoms.get(child) ?? 0);\n }\n return childContentBottom;\n}\n\nfunction readElementBottom(el: Element): number {\n const computedStyle: CSSStyleDeclaration = window.getComputedStyle(el);\n if (isOutOfFlowDecoration(computedStyle)) return 0;\n const rect: DOMRect = el.getBoundingClientRect();\n if (rect.width === 0 && rect.height === 0) return 0;\n return rect.bottom + window.scrollY + readMarginBottom(computedStyle);\n}\n\nfunction readMarginBottom(computedStyle: CSSStyleDeclaration): number {\n const marginBottom: number = parseFloat(computedStyle.marginBottom);\n return Number.isFinite(marginBottom) ? marginBottom : 0;\n}\n\nfunction isOutOfFlowDecoration(computedStyle: CSSStyleDeclaration): boolean {\n if (computedStyle.position === \"fixed\") return true;\n return computedStyle.position === \"absolute\" && computedStyle.pointerEvents === \"none\";\n}\n\nfunction isViewportStretchedContainer(\n elementBottom: number,\n childBottom: number,\n viewportBottom: number,\n): boolean {\n return (\n childBottom > 0 &&\n Math.abs(elementBottom - viewportBottom) <= 1 &&\n elementBottom - childBottom > 8\n );\n}\n\nfunction createDebouncer(fn: () => void, delayMs: number): Debouncer {\n let timer: number | undefined;\n return {\n trigger: (): void => {\n if (timer !== undefined) window.clearTimeout(timer);\n timer = window.setTimeout(fn, delayMs);\n },\n cancel: (): void => {\n if (timer !== undefined) {\n window.clearTimeout(timer);\n timer = undefined;\n }\n },\n };\n}\n","import { findElementsById, updateElementClasses, updateElementAttribute, collectAllowedAttributes, ALLOWED_ATTRIBUTES, getElementSelectorId, stopAnimations, resumeAnimations, findInstrumentedElement, resolveHoverTarget, positionLabel } from \"./utils.js\";\nimport { createLayerController } from \"./layer-dropdown/controller.js\";\nimport { LAYER_DROPDOWN_ATTR } from \"./layer-dropdown/consts.js\";\nimport { createInlineEditController } from \"../capabilities/inline-edit/index.js\";\nimport { THEME_FONT_PREVIEW_ID } from \"../consts.js\";\nimport { createPageHeightBridgeController } from \"./page-height-bridge.js\";\n\nconst REPOSITION_DELAY_MS = 50;\n\nexport function setupVisualEditAgent() {\n const pageHeightBridge = createPageHeightBridgeController();\n\n // State variables (replacing React useState/useRef)\n let isVisualEditMode = false;\n let isPopoverDragging = false;\n let isDropdownOpen = false;\n let hoverOverlays: HTMLDivElement[] = [];\n let selectedOverlays: HTMLDivElement[] = [];\n let currentHighlightedElements: Element[] = [];\n let selectedElementId: string | null = null;\n let selectedElement: Element | null = null;\n\n // Create overlay element\n const createOverlay = (isSelected = false): HTMLDivElement => {\n const overlay = document.createElement(\"div\");\n overlay.style.position = \"absolute\";\n overlay.style.pointerEvents = \"none\";\n overlay.style.transition = \"all 0.1s ease-in-out\";\n overlay.style.zIndex = \"9999\";\n\n if (isSelected) {\n overlay.style.border = \"2px solid #2563EB\";\n } else {\n overlay.style.border = \"2px solid #95a5fc\";\n overlay.style.backgroundColor = \"rgba(99, 102, 241, 0.05)\";\n }\n\n return overlay;\n };\n\n // Position overlay relative to element\n const positionOverlay = (\n overlay: HTMLDivElement,\n element: Element,\n isSelected = false\n ) => {\n if (!element || !isVisualEditMode) return;\n\n const htmlElement = element as HTMLElement;\n // Force layout recalculation\n void htmlElement.offsetWidth;\n\n const rect = element.getBoundingClientRect();\n overlay.style.top = `${rect.top + window.scrollY}px`;\n overlay.style.left = `${rect.left + window.scrollX}px`;\n overlay.style.width = `${rect.width}px`;\n overlay.style.height = `${rect.height}px`;\n\n // Check if label already exists in overlay\n let label = overlay.querySelector(\"div\") as HTMLDivElement | null;\n\n if (!label) {\n label = document.createElement(\"div\");\n label.textContent = element.tagName.toLowerCase();\n label.style.position = \"absolute\";\n label.style.left = \"-2px\";\n label.style.padding = \"2px 8px\";\n label.style.fontSize = \"11px\";\n label.style.fontWeight = isSelected ? \"500\" : \"400\";\n label.style.color = isSelected ? \"#ffffff\" : \"#526cff\";\n label.style.backgroundColor = isSelected ? \"#2563EB\" : \"#DBEAFE\";\n label.style.borderRadius = \"3px\";\n label.style.minWidth = \"24px\";\n label.style.textAlign = \"center\";\n overlay.appendChild(label);\n }\n\n positionLabel(label, rect);\n };\n\n // --- Inline edit controller ---\n const inlineEdit = createInlineEditController({\n findElementsById,\n getSelectedElementId: () => selectedElementId,\n getSelectedOverlays: () => selectedOverlays,\n positionOverlay,\n clearSelection: () => {\n inlineEdit.clearSelectedMarks(selectedElementId);\n clearSelectedOverlays();\n selectedElementId = null;\n selectedElement = null;\n },\n createSelectionOverlays: (elements, elementId) => {\n elements.forEach((el) => {\n const overlay = createOverlay(true);\n document.body.appendChild(overlay);\n selectedOverlays.push(overlay);\n positionOverlay(overlay, el, true);\n });\n selectedElementId = elementId;\n },\n });\n\n const clearSelection = () => {\n inlineEdit.clearSelectedMarks(selectedElementId);\n clearSelectedOverlays();\n selectedElementId = null;\n selectedElement = null;\n };\n\n // Clear hover overlays\n const clearHoverOverlays = () => {\n hoverOverlays.forEach((overlay) => {\n if (overlay && overlay.parentNode) {\n overlay.remove();\n }\n });\n hoverOverlays = [];\n currentHighlightedElements = [];\n };\n\n const clearSelectedOverlays = () => {\n selectedOverlays.forEach((overlay) => {\n if (overlay && overlay.parentNode) {\n overlay.remove();\n }\n });\n selectedOverlays = [];\n };\n\n const TEXT_TAGS = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'a', 'label'];\n\n const notifyElementSelected = (element: Element) => {\n const htmlElement = element as HTMLElement;\n const rect = element.getBoundingClientRect();\n const svgElement = element as SVGElement;\n const isTextElement = TEXT_TAGS.includes(element.tagName?.toLowerCase());\n\n const arrEl = htmlElement.closest(\"[data-arr-variable-name]\") as HTMLElement | null;\n const staticArrayName = arrEl?.dataset?.arrVariableName || null;\n const rawIdx = arrEl?.dataset?.arrIndex;\n const staticArrayIndex = rawIdx != null ? parseInt(rawIdx, 10) : null;\n const staticArrayField = htmlElement.dataset?.arrField || null;\n\n const collectionEl = htmlElement.closest(\"[data-collection-id]\") as HTMLElement | null;\n const itemFieldEl = htmlElement.closest(\"[data-collection-item-field]\") as HTMLElement | null;\n const itemIdEl = htmlElement.closest(\"[data-collection-item-id]\") as HTMLElement | null;\n\n window.parent.postMessage({\n type: \"element-selected\",\n tagName: element.tagName,\n classes:\n (svgElement.className as unknown as SVGAnimatedString)?.baseVal ||\n element.className ||\n \"\",\n visualSelectorId: getElementSelectorId(element),\n content: isTextElement ? htmlElement.innerText : undefined,\n dataSourceLocation: htmlElement.dataset.sourceLocation,\n isDynamicContent: htmlElement.dataset.dynamicContent === \"true\",\n linenumber: htmlElement.dataset.linenumber,\n filename: htmlElement.dataset.filename,\n position: {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n centerX: rect.left + rect.width / 2,\n centerY: rect.top + rect.height / 2,\n },\n attributes: collectAllowedAttributes(element, ALLOWED_ATTRIBUTES),\n isTextElement,\n staticArrayName,\n staticArrayIndex,\n staticArrayField,\n collectionId: collectionEl?.dataset?.collectionId || null,\n collectionItemField: itemFieldEl?.dataset?.collectionItemField || null,\n collectionItemId: itemIdEl?.dataset?.collectionItemId || null,\n }, \"*\");\n };\n\n // Select an element: create overlays, update state, notify parent\n const selectElement = (element: Element): HTMLDivElement | undefined => {\n const visualSelectorId = getElementSelectorId(element);\n\n clearSelectedOverlays();\n\n const elements = findElementsById(visualSelectorId || null);\n elements.forEach((el) => {\n const overlay = createOverlay(true);\n document.body.appendChild(overlay);\n selectedOverlays.push(overlay);\n positionOverlay(overlay, el, true);\n });\n\n selectedElementId = visualSelectorId || null;\n selectedElement = element;\n clearHoverOverlays();\n notifyElementSelected(element);\n\n return selectedOverlays[0];\n };\n\n const notifyDeselection = (): void => {\n selectedElementId = null;\n window.parent.postMessage({ type: \"unselect-element\" }, \"*\");\n };\n\n // Hover detection via mousemove + elementFromPoint (since app elements have pointer-events: none)\n let lastHoveredSelectorId: string | null = null;\n let pendingMouseMoveRaf: number | null = null;\n\n const clearHoverState = () => {\n clearHoverOverlays();\n lastHoveredSelectorId = null;\n };\n\n const applyHoverOverlays = (selectorId: string) => {\n const elements = findElementsById(selectorId);\n clearHoverOverlays();\n\n elements.forEach((el) => {\n const overlay = createOverlay(false);\n document.body.appendChild(overlay);\n hoverOverlays.push(overlay);\n positionOverlay(overlay, el);\n });\n\n currentHighlightedElements = elements;\n lastHoveredSelectorId = selectorId;\n };\n\n const handleMouseMove = (e: MouseEvent) => {\n if (!isVisualEditMode || isPopoverDragging || inlineEdit.isEditing()) return;\n\n if (pendingMouseMoveRaf !== null) return;\n pendingMouseMoveRaf = requestAnimationFrame(() => {\n pendingMouseMoveRaf = null;\n\n if (isDropdownOpen) { clearHoverState(); return; }\n\n const selectorId = resolveHoverTarget(e.clientX, e.clientY, selectedElementId);\n if (!selectorId) { clearHoverState(); return; }\n if (lastHoveredSelectorId === selectorId) return;\n\n applyHoverOverlays(selectorId);\n });\n };\n\n // Clear hover overlays when mouse leaves the viewport\n const handleMouseLeave = () => {\n if (pendingMouseMoveRaf !== null) {\n cancelAnimationFrame(pendingMouseMoveRaf);\n pendingMouseMoveRaf = null;\n }\n clearHoverState();\n };\n\n // Handle element click\n const handleElementClick = (e: MouseEvent) => {\n if (!isVisualEditMode) return;\n\n const target = e.target as Element;\n\n // Let layer dropdown clicks pass through without interference\n if (target.closest(`[${LAYER_DROPDOWN_ATTR}]`)) return;\n\n // Let clicks inside the editable element pass through to the browser\n // so the user can reposition the cursor and select text naturally.\n if (inlineEdit.enabled && target instanceof HTMLElement && target.contentEditable === \"true\") {\n return;\n }\n\n // Clicking outside the editable element exits inline editing mode.\n if (inlineEdit.isEditing()) {\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n inlineEdit.stopEditing();\n return;\n }\n\n // Close dropdowns when clicking anywhere in iframe if a dropdown is open\n if (isDropdownOpen) {\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n\n window.parent.postMessage({ type: \"close-dropdowns\" }, \"*\");\n return;\n }\n\n // Prevent default behavior immediately when in visual edit mode\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n\n const element = findInstrumentedElement(e.clientX, e.clientY);\n if (!element) {\n return;\n }\n\n const htmlElement = element as HTMLElement;\n const visualSelectorId = getElementSelectorId(element);\n\n const isAlreadySelected =\n selectedElementId === visualSelectorId &&\n htmlElement.dataset.selected === \"true\";\n\n if (isAlreadySelected && inlineEdit.enabled && inlineEdit.canEdit(htmlElement)) {\n inlineEdit.startEditing(htmlElement);\n return;\n }\n\n inlineEdit.stopEditing();\n\n if (inlineEdit.enabled) {\n inlineEdit.markElementsSelected(findElementsById(visualSelectorId));\n }\n\n const selectedOverlay = selectElement(element);\n layerController.attachToOverlay(selectedOverlay, element);\n };\n\n const unselectElement = () => {\n inlineEdit.stopEditing();\n clearSelection();\n };\n\n const updateElementClassesAndReposition = (visualSelectorId: string, classes: string) => {\n const elements = findElementsById(visualSelectorId);\n if (elements.length === 0) return;\n\n updateElementClasses(elements, classes);\n\n // Use a small delay to allow the browser to recalculate layout before repositioning\n setTimeout(() => {\n // Reposition selected overlays\n if (selectedElementId === visualSelectorId) {\n selectedOverlays.forEach((overlay, index) => {\n if (index < elements.length) {\n positionOverlay(overlay, elements[index]!);\n }\n });\n }\n\n // Reposition hover overlays if needed\n if (currentHighlightedElements.length > 0) {\n const hoveredElement = currentHighlightedElements[0] as HTMLElement;\n const hoveredId = hoveredElement?.dataset?.visualSelectorId;\n if (hoveredId === visualSelectorId) {\n hoverOverlays.forEach((overlay, index) => {\n if (index < currentHighlightedElements.length) {\n positionOverlay(overlay, currentHighlightedElements[index]!);\n }\n });\n }\n }\n }, REPOSITION_DELAY_MS);\n };\n\n // Update element attribute by visual selector ID\n const updateElementAttributeAndReposition = (\n visualSelectorId: string,\n attribute: string,\n value: string\n ) => {\n const elements = findElementsById(visualSelectorId);\n if (elements.length === 0) return;\n\n updateElementAttribute(elements, attribute, value);\n\n // Reposition overlays after attribute change (e.g. image src swap can affect layout)\n setTimeout(() => {\n if (selectedElementId === visualSelectorId) {\n selectedOverlays.forEach((overlay, index) => {\n if (index < elements.length) {\n positionOverlay(overlay, elements[index]!);\n }\n });\n }\n }, REPOSITION_DELAY_MS);\n };\n\n const updateElementContent = (visualSelectorId: string, content: string, arrIndex?: number) => {\n let elements = findElementsById(visualSelectorId);\n\n if (elements.length === 0) {\n return;\n }\n\n if (arrIndex != null) {\n elements = elements.filter(\n (el) => (el as HTMLElement).dataset.arrIndex === String(arrIndex)\n );\n }\n\n elements.forEach((element) => {\n (element as HTMLElement).innerText = content;\n });\n\n setTimeout(() => {\n if (selectedElementId === visualSelectorId) {\n selectedOverlays.forEach((overlay, index) => {\n if (index < elements.length) {\n positionOverlay(overlay, elements[index]!);\n }\n });\n }\n }, REPOSITION_DELAY_MS);\n };\n\n // --- Layer dropdown controller ---\n const layerController = createLayerController({\n createPreviewOverlay: (element: Element) => {\n const overlay = createOverlay(false);\n overlay.style.zIndex = \"9998\";\n document.body.appendChild(overlay);\n positionOverlay(overlay, element);\n return overlay;\n },\n getSelectedElementId: () => selectedElementId,\n selectElement,\n onDeselect: notifyDeselection,\n });\n\n // Toggle visual edit mode\n const toggleVisualEditMode = (isEnabled: boolean) => {\n isVisualEditMode = isEnabled;\n\n if (!isEnabled) {\n resumeAnimations();\n inlineEdit.stopEditing();\n clearSelection();\n layerController.cleanup();\n handleMouseLeave();\n document.body.style.cursor = \"default\";\n\n document.removeEventListener(\"mousemove\", handleMouseMove);\n document.removeEventListener(\"mouseleave\", handleMouseLeave);\n document.removeEventListener(\"click\", handleElementClick, true);\n } else {\n document.body.style.cursor = \"crosshair\";\n stopAnimations();\n document.addEventListener(\"mousemove\", handleMouseMove);\n document.addEventListener(\"mouseleave\", handleMouseLeave);\n document.addEventListener(\"click\", handleElementClick, true);\n }\n };\n\n // Handle scroll events to update popover position\n const handleScroll = () => {\n if (selectedElementId) {\n const element = selectedElement;\n if (element && element.isConnected) {\n const rect = element.getBoundingClientRect();\n\n const viewportHeight = window.innerHeight;\n const viewportWidth = window.innerWidth;\n const isInViewport =\n rect.top < viewportHeight &&\n rect.bottom > 0 &&\n rect.left < viewportWidth &&\n rect.right > 0;\n\n const elementPosition = {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n centerX: rect.left + rect.width / 2,\n centerY: rect.top + rect.height / 2,\n };\n\n window.parent.postMessage(\n {\n type: \"element-position-update\",\n position: elementPosition,\n isInViewport: isInViewport,\n visualSelectorId: selectedElementId,\n },\n \"*\"\n );\n }\n }\n };\n\n // Handle messages from parent window\n const handleMessage = (event: MessageEvent) => {\n const message = event.data;\n\n switch (message.type) {\n case \"toggle-visual-edit-mode\":\n toggleVisualEditMode(message.data.enabled);\n if (message.data.specs?.newInlineEditEnabled !== undefined) {\n inlineEdit.enabled = message.data.specs.newInlineEditEnabled;\n }\n break;\n\n case \"update-classes\":\n if (message.data && message.data.classes !== undefined) {\n updateElementClassesAndReposition(\n message.data.visualSelectorId,\n message.data.classes\n );\n } else {\n console.warn(\n \"[VisualEditAgent] Invalid update-classes message:\",\n message\n );\n }\n break;\n\n case \"update-attribute\":\n if (\n message.data &&\n message.data.visualSelectorId &&\n message.data.attribute !== undefined &&\n message.data.value !== undefined\n ) {\n updateElementAttributeAndReposition(\n message.data.visualSelectorId,\n message.data.attribute,\n message.data.value\n );\n } else {\n console.warn(\n \"[VisualEditAgent] Invalid update-attribute message:\",\n message\n );\n }\n break;\n\n case \"unselect-element\":\n unselectElement();\n break;\n\n case \"refresh-page\":\n window.location.reload();\n break;\n\n case \"update-content\":\n if (message.data && message.data.content !== undefined) {\n updateElementContent(\n message.data.visualSelectorId,\n message.data.content,\n message.data.arrIndex\n );\n } else {\n console.warn(\n \"[VisualEditAgent] Invalid update-content message:\",\n message\n );\n }\n break;\n\n case \"request-element-position\":\n if (selectedElementId && selectedElement && selectedElement.isConnected) {\n const rect = selectedElement.getBoundingClientRect();\n\n const viewportHeight = window.innerHeight;\n const viewportWidth = window.innerWidth;\n const isInViewport =\n rect.top < viewportHeight &&\n rect.bottom > 0 &&\n rect.left < viewportWidth &&\n rect.right > 0;\n\n const elementPosition = {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n centerX: rect.left + rect.width / 2,\n centerY: rect.top + rect.height / 2,\n };\n\n window.parent.postMessage(\n {\n type: \"element-position-update\",\n position: elementPosition,\n isInViewport: isInViewport,\n visualSelectorId: selectedElementId,\n },\n \"*\"\n );\n }\n break;\n\n case \"popover-drag-state\":\n if (message.data && message.data.isDragging !== undefined) {\n isPopoverDragging = message.data.isDragging;\n if (message.data.isDragging) {\n clearHoverOverlays();\n }\n }\n break;\n\n case \"dropdown-state\":\n if (message.data && message.data.isOpen !== undefined) {\n isDropdownOpen = message.data.isOpen;\n if (message.data.isOpen) {\n clearHoverOverlays();\n }\n }\n break;\n\n case \"update-theme-variables\":\n if (message.data?.variables) {\n const target = message.data.mode === 'dark'\n ? document.querySelector('.dark') as HTMLElement\n : document.documentElement;\n if (target) {\n for (const [name, value] of Object.entries(message.data.variables)) {\n target.style.setProperty(name, value as string);\n }\n }\n }\n break;\n\n case \"inject-font-import\":\n if (message.data?.fontUrl) {\n let fontStyle = document.getElementById(THEME_FONT_PREVIEW_ID) as HTMLStyleElement | null;\n if (!fontStyle) {\n fontStyle = document.createElement('style');\n fontStyle.id = THEME_FONT_PREVIEW_ID;\n document.head.appendChild(fontStyle);\n }\n fontStyle.textContent = `@import url('${message.data.fontUrl}');`;\n }\n break;\n\n case \"toggle-inline-edit-mode\":\n if (message.data) {\n inlineEdit.handleToggleMessage(message.data);\n }\n break;\n\n case \"freeze-vh-units\":\n pageHeightBridge.freezeVhUnits(\n typeof message.referenceVhBase === \"number\"\n ? message.referenceVhBase\n : undefined\n );\n break;\n\n case \"measure-page-height\":\n pageHeightBridge.measurePageHeight(\n event.origin && event.origin !== \"null\" ? event.origin : \"*\",\n typeof message.settleMs === \"number\" ? message.settleMs : undefined\n );\n break;\n\n default:\n break;\n }\n };\n\n // Handle window resize to reposition overlays\n const handleResize = () => {\n if (selectedElementId) {\n const elements = findElementsById(selectedElementId);\n selectedOverlays.forEach((overlay, index) => {\n if (index < elements.length) {\n positionOverlay(overlay, elements[index]!);\n }\n });\n }\n\n if (currentHighlightedElements.length > 0) {\n hoverOverlays.forEach((overlay, index) => {\n if (index < currentHighlightedElements.length) {\n positionOverlay(overlay, currentHighlightedElements[index]!);\n }\n });\n }\n };\n\n // Initialize: Add IDs to elements that don't have them but have linenumbers\n const elementsWithLineNumber = document.querySelectorAll(\n \"[data-linenumber]:not([data-visual-selector-id])\"\n );\n elementsWithLineNumber.forEach((el, index) => {\n const htmlEl = el as HTMLElement;\n const id = `visual-id-${htmlEl.dataset.filename}-${htmlEl.dataset.linenumber}-${index}`;\n htmlEl.dataset.visualSelectorId = id;\n });\n\n // Create mutation observer to detect layout changes\n const mutationObserver = new MutationObserver((mutations) => {\n const needsUpdate = mutations.some((mutation) => {\n const hasVisualId = (node: Node): boolean => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const el = node as HTMLElement;\n if (el.dataset && el.dataset.visualSelectorId) {\n return true;\n }\n for (let i = 0; i < el.children.length; i++) {\n if (hasVisualId(el.children[i]!)) {\n return true;\n }\n }\n }\n return false;\n };\n\n const isLayoutChange =\n mutation.type === \"attributes\" &&\n (mutation.attributeName === \"style\" ||\n mutation.attributeName === \"class\" ||\n mutation.attributeName === \"width\" ||\n mutation.attributeName === \"height\");\n\n return isLayoutChange && hasVisualId(mutation.target);\n });\n\n if (needsUpdate) {\n setTimeout(handleResize, REPOSITION_DELAY_MS);\n }\n });\n\n // Set up event listeners\n window.addEventListener(\"message\", handleMessage);\n window.addEventListener(\"scroll\", handleScroll, true);\n document.addEventListener(\"scroll\", handleScroll, true);\n window.addEventListener(\"resize\", handleResize);\n window.addEventListener(\"scroll\", handleResize);\n\n // Start observing DOM mutations\n mutationObserver.observe(document.body, {\n attributes: true,\n childList: true,\n subtree: true,\n attributeFilter: [\"style\", \"class\", \"width\", \"height\"],\n });\n\n // Send ready message to parent\n window.parent.postMessage({ type: \"visual-edit-agent-ready\" }, \"*\");\n}\n"],"mappings":"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","names":["positionLabel","label","rect","nearTop","tallEnough","isFullWidth","edgeLeft","insideLeft","isInstrumentedElement","element","htmlEl","getElementSelectorId","ALLOWED_ATTRIBUTES","PLUGIN_ELEMENT_ATTR","findElementsById","id","sourceElements","updateElementClasses","elements","classes","updateElementAttribute","attribute","value","collectAllowedAttributes","allowedAttributes","attributes","attr","val","stopAnimations","animStyle","pointerStyle","target","a","animTarget","resumeAnimations","findInstrumentedElement","x","y","el","resolveHoverTarget","selectedElementId","selectorId","DROPDOWN_CONTAINER_STYLES","DROPDOWN_ITEM_BASE_STYLES","DROPDOWN_ITEM_ACTIVE_COLOR","DROPDOWN_ITEM_ACTIVE_BG","DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT","DROPDOWN_ITEM_HOVER_BG","DEPTH_INDENT_PX","CHEVRON_COLLAPSED","CHEVRON_EXPANDED","CHEVRON_ATTR","BASE_PADDING_PX","LAYER_DROPDOWN_ATTR","MAX_PARENT_DEPTH","MAX_CHILD_DEPTH","applyStyles","element","styles","key","m","getLayerDisplayName","layer","toLayerInfo","depth","info","getElementSelectorId","getInstrumentedDescendants","parent","maxDepth","startDepth","result","walk","el","instrDepth","i","child","isInstrumentedElement","collectInstrumentedParents","selectedElement","parents","current","MAX_PARENT_DEPTH","addParentsToChain","chain","p","addSelfAndDescendantsToChain","selfDepth","descendants","MAX_CHILD_DEPTH","getImmediateInstrParent","collectSiblings","siblings","s","appendSiblingsWithSelected","selectedSelectorId","seen","sibling","id","buildLayerChain","instrParent","activeDropdown","activeLabel","outsideMousedownHandler","activeOnHoverEnd","activeKeydownHandler","createDropdownItem","layer","isActive","onSelect","onHover","onHoverEnd","item","getLayerDisplayName","applyStyles","DROPDOWN_ITEM_BASE_STYLES","depth","BASE_PADDING_PX","DEPTH_INDENT_PX","DROPDOWN_ITEM_ACTIVE_COLOR","DROPDOWN_ITEM_ACTIVE_BG","DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT","DROPDOWN_ITEM_HOVER_BG","e","createDropdownElement","layers","currentElement","callbacks","container","LAYER_DROPDOWN_ATTR","PLUGIN_ELEMENT_ATTR","DROPDOWN_CONTAINER_STYLES","enhanceLabelWithChevron","label","CHEVRON_ATTR","chevron","CHEVRON_COLLAPSED","setupKeyboardNavigation","dropdown","items","focusedIndex","l","setFocusedItem","index","prev","cur","closeDropdown","setupOutsideClickHandler","skipFirst","target","showDropdown","overlay","chevronEl","CHEVRON_EXPANDED","isDropdownOpen","createLayerController","config","layerPreviewOverlay","escapeHandler","dropdownSourceLayer","clearLayerPreview","showLayerPreview","layer","getElementSelectorId","selectLayer","closeDropdown","firstOverlay","attachToOverlay","restoreSelection","handleLabelClick","e","label","element","layers","currentId","isDropdownOpen","ev","showDropdown","overlay","buildLayerChain","enhanceLabelWithChevron","FOCUS_STYLE_ID","EDITABLE_TAGS","isStaticArrayTextElement","element","passesStructuralChecks","injectFocusOutlineCSS","style","removeFocusOutlineCSS","selectText","range","selection","isEditableTextElement","shouldEnterInlineEditingMode","DEBOUNCE_MS","createInlineEditController","host","currentEditingElement","debouncedSendTimeout","enabled","listenerAbortControllers","repositionOverlays","selectedId","elements","overlay","i","reportEdit","element","originalContent","newContent","svgElement","rect","message","isStaticArrayTextElement","debouncedReport","onTextInput","handleInputEvent","makeEditable","injectFocusOutlineCSS","PLUGIN_ELEMENT_ATTR","abortController","selectText","makeNonEditable","removeFocusOutlineCSS","value","shouldEnterInlineEditingMode","o","el","elementId","data","THEME_FONT_PREVIEW_ID","REFERENCE_VH_BASE_VAR","createPageHeightBridgeController","vhCleanups","vhForceRun","pendingResponse","pendingOrigin","override","referenceVhBase","resolveReferenceVhBase","setReferenceVhBase","startVhNeutralizer","origin","settleMs","height","measureContentHeight","c","detected","REFERENCE_VH_BASE_VAR","cleanups","VH_RE","processedStyles","processedSheets","watchedStyles","styleObservers","debouncer","createDebouncer","rewrite","input","_match","n","formatVhFactor","el","watchStyleEl","text","next","i","sheet","rules","rewriteVhInRules","debouncedNeutralize","obs","headObserver","mutations","m","containsStylesheetNode","attachHeadObserver","value","rule","style","j","prop","nodes","node","scrollHeight","viewportHeight","contentBottom","measureElementContentBottom","readReferenceVhBase","parsed","elements","contentBottoms","viewportBottom","childContentBottom","readChildrenContentBottom","rawBottom","readElementBottom","selfBottom","isViewportStretchedContainer","child","computedStyle","isOutOfFlowDecoration","rect","readMarginBottom","marginBottom","elementBottom","childBottom","fn","delayMs","timer","REPOSITION_DELAY_MS","setupVisualEditAgent","pageHeightBridge","createPageHeightBridgeController","isVisualEditMode","isPopoverDragging","isDropdownOpen","hoverOverlays","selectedOverlays","currentHighlightedElements","selectedElementId","selectedElement","createOverlay","isSelected","overlay","positionOverlay","element","rect","label","positionLabel","inlineEdit","createInlineEditController","findElementsById","clearSelectedOverlays","elements","elementId","el","clearSelection","clearHoverOverlays","TEXT_TAGS","notifyElementSelected","htmlElement","svgElement","isTextElement","arrEl","staticArrayName","rawIdx","staticArrayIndex","staticArrayField","collectionEl","itemFieldEl","itemIdEl","getElementSelectorId","collectAllowedAttributes","ALLOWED_ATTRIBUTES","selectElement","visualSelectorId","notifyDeselection","lastHoveredSelectorId","pendingMouseMoveRaf","clearHoverState","applyHoverOverlays","selectorId","handleMouseMove","e","resolveHoverTarget","handleMouseLeave","handleElementClick","target","LAYER_DROPDOWN_ATTR","findInstrumentedElement","selectedOverlay","layerController","unselectElement","updateElementClassesAndReposition","classes","updateElementClasses","index","updateElementAttributeAndReposition","attribute","value","updateElementAttribute","updateElementContent","content","arrIndex","createLayerController","toggleVisualEditMode","isEnabled","stopAnimations","resumeAnimations","handleScroll","viewportHeight","viewportWidth","isInViewport","elementPosition","handleMessage","event","message","name","fontStyle","THEME_FONT_PREVIEW_ID","handleResize","htmlEl","id","mutationObserver","mutations","mutation","hasVisualId","node","i"]}
|
package/package.json
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
// fire on their own.
|
|
4
4
|
//
|
|
5
5
|
// parent → child { type: "freeze-vh-units", referenceVhBase?: number }
|
|
6
|
-
// Rewrites every `vh` in <style> + CSSOM to
|
|
7
|
-
// vh ↔ auto-resize feedback loop).
|
|
8
|
-
//
|
|
6
|
+
// Rewrites every `vh` in <style> + CSSOM to a CSS variable-backed
|
|
7
|
+
// expression (kills the vh ↔ auto-resize feedback loop). Repeated calls
|
|
8
|
+
// update the variable, so callers can rebase without recovering raw CSS.
|
|
9
|
+
// Idempotent; covers HMR-added styles too. Fire-and-forget.
|
|
9
10
|
//
|
|
10
11
|
// parent → child { type: "measure-page-height", settleMs?: number }
|
|
11
|
-
// After `settleMs` (default 2000) posts the page's
|
|
12
|
+
// After `settleMs` (default 2000) posts the page's measured content height
|
|
12
13
|
// as `{ type: "page-height-measured", height }` to the requester.
|
|
13
14
|
|
|
14
15
|
type IncomingMessage = {
|
|
@@ -34,6 +35,7 @@ const FALLBACK_VHBASE: number = 900;
|
|
|
34
35
|
const MIN_VHBASE: number = 400;
|
|
35
36
|
const DEFAULT_SETTLE_MS: number = 2000;
|
|
36
37
|
const NEUTRALIZE_DEBOUNCE_MS: number = 16;
|
|
38
|
+
const REFERENCE_VH_BASE_VAR: string = "--base44-reference-vh-base";
|
|
37
39
|
|
|
38
40
|
const noop: () => void = (): void => {};
|
|
39
41
|
|
|
@@ -94,13 +96,14 @@ export function createPageHeightBridgeController(): PageHeightBridgeController {
|
|
|
94
96
|
|
|
95
97
|
return {
|
|
96
98
|
freezeVhUnits: (override: number | undefined): void => {
|
|
99
|
+
const referenceVhBase: number = resolveReferenceVhBase(override);
|
|
100
|
+
setReferenceVhBase(referenceVhBase);
|
|
97
101
|
if (vhCleanups) {
|
|
98
102
|
vhForceRun?.();
|
|
99
103
|
return;
|
|
100
104
|
}
|
|
101
|
-
const referenceVhBase: number = resolveReferenceVhBase(override);
|
|
102
105
|
vhCleanups = [];
|
|
103
|
-
vhForceRun = startVhNeutralizer(
|
|
106
|
+
vhForceRun = startVhNeutralizer(vhCleanups);
|
|
104
107
|
},
|
|
105
108
|
|
|
106
109
|
// Target the requester's origin so the height isn't broadcast to anyone
|
|
@@ -134,15 +137,16 @@ function resolveReferenceVhBase(override: number | undefined): number {
|
|
|
134
137
|
return detected >= MIN_VHBASE ? detected : FALLBACK_VHBASE;
|
|
135
138
|
}
|
|
136
139
|
|
|
140
|
+
function setReferenceVhBase(referenceVhBase: number): void {
|
|
141
|
+
document.documentElement.style.setProperty(REFERENCE_VH_BASE_VAR, `${referenceVhBase}px`);
|
|
142
|
+
}
|
|
143
|
+
|
|
137
144
|
// Caches keep work proportional to *new* CSS, not total CSS. <head> observer
|
|
138
145
|
// catches `<style>`/`<link>` adds; per-element observers catch HMR text edits.
|
|
139
146
|
// Returns a `forceRun` so the caller can re-trigger neutralization on later
|
|
140
147
|
// parent requests (idempotent — already-rewritten text is skipped via the
|
|
141
148
|
// processed sets).
|
|
142
|
-
function startVhNeutralizer(
|
|
143
|
-
referenceVhBase: number,
|
|
144
|
-
cleanups: Array<() => void>,
|
|
145
|
-
): () => void {
|
|
149
|
+
function startVhNeutralizer(cleanups: Array<() => void>): () => void {
|
|
146
150
|
const VH_RE: RegExp = /(\d+(?:\.\d+)?)vh\b/g;
|
|
147
151
|
const processedStyles: WeakSet<HTMLStyleElement> = new WeakSet();
|
|
148
152
|
const processedSheets: WeakMap<CSSStyleSheet, number> = new WeakMap();
|
|
@@ -152,7 +156,7 @@ function startVhNeutralizer(
|
|
|
152
156
|
const neutralize = (): void => {
|
|
153
157
|
const rewrite = (input: string): string =>
|
|
154
158
|
input.replace(VH_RE, (_match: string, n: string): string =>
|
|
155
|
-
|
|
159
|
+
`calc(var(${REFERENCE_VH_BASE_VAR}) * ${formatVhFactor(n)})`,
|
|
156
160
|
);
|
|
157
161
|
|
|
158
162
|
document.querySelectorAll<HTMLStyleElement>("style").forEach((el: HTMLStyleElement): void => {
|
|
@@ -230,6 +234,10 @@ function startVhNeutralizer(
|
|
|
230
234
|
return debouncedNeutralize;
|
|
231
235
|
}
|
|
232
236
|
|
|
237
|
+
function formatVhFactor(value: string): string {
|
|
238
|
+
return String(Number((parseFloat(value) / 100).toFixed(6)));
|
|
239
|
+
}
|
|
240
|
+
|
|
233
241
|
function rewriteVhInRules(rules: CSSRuleList, rewrite: (value: string) => string): void {
|
|
234
242
|
for (let i: number = 0; i < rules.length; i++) {
|
|
235
243
|
const rule: IndexableCssRule | undefined = rules[i] as IndexableCssRule | undefined;
|
|
@@ -257,10 +265,88 @@ function containsStylesheetNode(nodes: NodeList): boolean {
|
|
|
257
265
|
}
|
|
258
266
|
|
|
259
267
|
function measureContentHeight(): number {
|
|
260
|
-
|
|
268
|
+
const scrollHeight: number = Math.max(
|
|
261
269
|
document.documentElement.scrollHeight,
|
|
262
270
|
document.body?.scrollHeight ?? 0,
|
|
263
271
|
);
|
|
272
|
+
const viewportHeight: number = Math.max(
|
|
273
|
+
window.innerHeight || 0,
|
|
274
|
+
document.documentElement.clientHeight,
|
|
275
|
+
document.body?.clientHeight ?? 0,
|
|
276
|
+
);
|
|
277
|
+
const contentBottom: number = measureElementContentBottom(viewportHeight);
|
|
278
|
+
const referenceVhBase: number = readReferenceVhBase();
|
|
279
|
+
if (contentBottom > 0) return Math.ceil(Math.max(contentBottom, referenceVhBase));
|
|
280
|
+
return Math.ceil(Math.max(scrollHeight, referenceVhBase));
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function readReferenceVhBase(): number {
|
|
284
|
+
const value: string = document.documentElement.style.getPropertyValue(REFERENCE_VH_BASE_VAR);
|
|
285
|
+
const parsed: number = parseFloat(value);
|
|
286
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function measureElementContentBottom(viewportHeight: number): number {
|
|
290
|
+
if (!document.body) return 0;
|
|
291
|
+
const elements: Element[] = [document.body, ...Array.from(document.body.querySelectorAll("*"))];
|
|
292
|
+
const contentBottoms: WeakMap<Element, number> = new WeakMap();
|
|
293
|
+
const viewportBottom: number = window.scrollY + viewportHeight;
|
|
294
|
+
|
|
295
|
+
for (let i: number = elements.length - 1; i >= 0; i--) {
|
|
296
|
+
const el: Element | undefined = elements[i];
|
|
297
|
+
if (!el) continue;
|
|
298
|
+
const childContentBottom: number = readChildrenContentBottom(el, contentBottoms);
|
|
299
|
+
const rawBottom: number = readElementBottom(el);
|
|
300
|
+
const selfBottom: number = isViewportStretchedContainer(rawBottom, childContentBottom, viewportBottom)
|
|
301
|
+
? 0
|
|
302
|
+
: rawBottom;
|
|
303
|
+
contentBottoms.set(el, Math.max(childContentBottom, selfBottom));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return contentBottoms.get(document.body) ?? 0;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function readChildrenContentBottom(
|
|
310
|
+
el: Element,
|
|
311
|
+
contentBottoms: WeakMap<Element, number>,
|
|
312
|
+
): number {
|
|
313
|
+
let childContentBottom: number = 0;
|
|
314
|
+
for (let i: number = 0; i < el.children.length; i++) {
|
|
315
|
+
const child: Element | undefined = el.children[i];
|
|
316
|
+
if (!child) continue;
|
|
317
|
+
childContentBottom = Math.max(childContentBottom, contentBottoms.get(child) ?? 0);
|
|
318
|
+
}
|
|
319
|
+
return childContentBottom;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function readElementBottom(el: Element): number {
|
|
323
|
+
const computedStyle: CSSStyleDeclaration = window.getComputedStyle(el);
|
|
324
|
+
if (isOutOfFlowDecoration(computedStyle)) return 0;
|
|
325
|
+
const rect: DOMRect = el.getBoundingClientRect();
|
|
326
|
+
if (rect.width === 0 && rect.height === 0) return 0;
|
|
327
|
+
return rect.bottom + window.scrollY + readMarginBottom(computedStyle);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function readMarginBottom(computedStyle: CSSStyleDeclaration): number {
|
|
331
|
+
const marginBottom: number = parseFloat(computedStyle.marginBottom);
|
|
332
|
+
return Number.isFinite(marginBottom) ? marginBottom : 0;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function isOutOfFlowDecoration(computedStyle: CSSStyleDeclaration): boolean {
|
|
336
|
+
if (computedStyle.position === "fixed") return true;
|
|
337
|
+
return computedStyle.position === "absolute" && computedStyle.pointerEvents === "none";
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function isViewportStretchedContainer(
|
|
341
|
+
elementBottom: number,
|
|
342
|
+
childBottom: number,
|
|
343
|
+
viewportBottom: number,
|
|
344
|
+
): boolean {
|
|
345
|
+
return (
|
|
346
|
+
childBottom > 0 &&
|
|
347
|
+
Math.abs(elementBottom - viewportBottom) <= 1 &&
|
|
348
|
+
elementBottom - childBottom > 8
|
|
349
|
+
);
|
|
264
350
|
}
|
|
265
351
|
|
|
266
352
|
function createDebouncer(fn: () => void, delayMs: number): Debouncer {
|