@lego-build/plugins 0.0.13 → 0.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/auto.js +1 -1
- package/dist/chunk-42EQNKDZ.js +911 -0
- package/dist/chunk-57PHJ5T3.js +568 -0
- package/dist/chunk-BOFAT72T.js +774 -0
- package/dist/chunk-BOZW7P43.js +880 -0
- package/dist/chunk-DRJL43HD.js +856 -0
- package/dist/chunk-E2GR3HJ4.js +1016 -0
- package/dist/chunk-EDP4S2JY.js +912 -0
- package/dist/chunk-EIJHWZEB.js +912 -0
- package/dist/chunk-FAFNTLDM.js +573 -0
- package/dist/chunk-GHQ2QAQ5.js +902 -0
- package/dist/chunk-GVQDEL73.js +883 -0
- package/dist/chunk-IMQY5OCI.js +1016 -0
- package/dist/chunk-LWTE7MX6.js +1012 -0
- package/dist/chunk-QK2GGK2P.js +884 -0
- package/dist/chunk-QK7ZLTXS.js +1016 -0
- package/dist/chunk-R4QEYETE.js +912 -0
- package/dist/chunk-RWXQL7F3.js +911 -0
- package/dist/chunk-SFQCNL3M.js +865 -0
- package/dist/chunk-VB47OQT5.js +1012 -0
- package/dist/chunk-WST57QAD.js +572 -0
- package/dist/chunk-XICWYUFH.js +1009 -0
- package/dist/chunk-YMTGNYSY.js +889 -0
- package/dist/chunk-ZCYDXH7R.js +886 -0
- package/dist/index.js +1 -1
- package/dist/react.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,902 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var SKIP_ELEMENTS = /* @__PURE__ */ new Set([
|
|
3
|
+
"html",
|
|
4
|
+
"head",
|
|
5
|
+
"script",
|
|
6
|
+
"style",
|
|
7
|
+
"meta",
|
|
8
|
+
"link",
|
|
9
|
+
"title",
|
|
10
|
+
"noscript",
|
|
11
|
+
"br",
|
|
12
|
+
"wbr",
|
|
13
|
+
"template",
|
|
14
|
+
"slot"
|
|
15
|
+
]);
|
|
16
|
+
var INTERACTIVE_ELEMENTS = /* @__PURE__ */ new Set([
|
|
17
|
+
"a",
|
|
18
|
+
"button",
|
|
19
|
+
"input",
|
|
20
|
+
"select",
|
|
21
|
+
"textarea",
|
|
22
|
+
"label",
|
|
23
|
+
"details",
|
|
24
|
+
"summary",
|
|
25
|
+
"dialog",
|
|
26
|
+
"menu",
|
|
27
|
+
"menuitem"
|
|
28
|
+
]);
|
|
29
|
+
var SEMANTIC_ELEMENTS = /* @__PURE__ */ new Set([
|
|
30
|
+
"header",
|
|
31
|
+
"footer",
|
|
32
|
+
"main",
|
|
33
|
+
"nav",
|
|
34
|
+
"aside",
|
|
35
|
+
"section",
|
|
36
|
+
"article",
|
|
37
|
+
"h1",
|
|
38
|
+
"h2",
|
|
39
|
+
"h3",
|
|
40
|
+
"h4",
|
|
41
|
+
"h5",
|
|
42
|
+
"h6",
|
|
43
|
+
"p",
|
|
44
|
+
"figure",
|
|
45
|
+
"figcaption",
|
|
46
|
+
"ul",
|
|
47
|
+
"ol",
|
|
48
|
+
"li",
|
|
49
|
+
"dl",
|
|
50
|
+
"dt",
|
|
51
|
+
"dd",
|
|
52
|
+
"table",
|
|
53
|
+
"thead",
|
|
54
|
+
"tbody",
|
|
55
|
+
"tr",
|
|
56
|
+
"td",
|
|
57
|
+
"th",
|
|
58
|
+
"form",
|
|
59
|
+
"fieldset",
|
|
60
|
+
"legend",
|
|
61
|
+
"img",
|
|
62
|
+
"video",
|
|
63
|
+
"audio",
|
|
64
|
+
"canvas",
|
|
65
|
+
"svg"
|
|
66
|
+
]);
|
|
67
|
+
var MIN_ELEMENT_SIZE = 8;
|
|
68
|
+
var MOUSEMOVE_DEBOUNCE = 16;
|
|
69
|
+
var CSS_PREVIEW_PROPERTIES = [
|
|
70
|
+
"display",
|
|
71
|
+
"position",
|
|
72
|
+
"width",
|
|
73
|
+
"height",
|
|
74
|
+
"padding",
|
|
75
|
+
"margin",
|
|
76
|
+
"color",
|
|
77
|
+
"background-color",
|
|
78
|
+
"font-size",
|
|
79
|
+
"font-weight"
|
|
80
|
+
];
|
|
81
|
+
function sendToParent(type, payload) {
|
|
82
|
+
window.parent.postMessage({ type, payload }, "*");
|
|
83
|
+
}
|
|
84
|
+
function setupIframeBridge() {
|
|
85
|
+
const pushState = window.history.pushState.bind(window.history);
|
|
86
|
+
const originalPushState = (...args) => {
|
|
87
|
+
pushState(...args);
|
|
88
|
+
sendToParent("IFRAME_URL_CHANGED", window.location.href);
|
|
89
|
+
};
|
|
90
|
+
window.history.pushState = originalPushState;
|
|
91
|
+
const replaceState = window.history.replaceState.bind(window.history);
|
|
92
|
+
const originalReplaceState = (...args) => {
|
|
93
|
+
replaceState(...args);
|
|
94
|
+
sendToParent("IFRAME_URL_CHANGED", window.location.href);
|
|
95
|
+
};
|
|
96
|
+
window.history.replaceState = originalReplaceState;
|
|
97
|
+
window.addEventListener("popstate", () => {
|
|
98
|
+
sendToParent("IFRAME_URL_CHANGED", window.location.href);
|
|
99
|
+
});
|
|
100
|
+
window.addEventListener("message", (e) => {
|
|
101
|
+
const msg = e.data;
|
|
102
|
+
if (!msg?.type) return;
|
|
103
|
+
switch (msg.type) {
|
|
104
|
+
case "NAVIGATE_BACK":
|
|
105
|
+
window.history.back();
|
|
106
|
+
break;
|
|
107
|
+
case "NAVIGATE_FORWARD":
|
|
108
|
+
window.history.forward();
|
|
109
|
+
break;
|
|
110
|
+
case "NAVIGATE_URL":
|
|
111
|
+
if (msg.payload) {
|
|
112
|
+
window.history.pushState({}, "", msg.payload);
|
|
113
|
+
sendToParent("IFRAME_URL_CHANGED", window.location.href);
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
case "REFRESH":
|
|
117
|
+
window.location.reload();
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
function createElementSelectorState() {
|
|
123
|
+
return {
|
|
124
|
+
isActive: false,
|
|
125
|
+
isEditing: false,
|
|
126
|
+
isSelected: false,
|
|
127
|
+
hoveredElement: null,
|
|
128
|
+
selectedElement: null,
|
|
129
|
+
overlay: null,
|
|
130
|
+
selectionOverlay: null,
|
|
131
|
+
tooltip: null,
|
|
132
|
+
cssPanel: null,
|
|
133
|
+
inlineEditor: null,
|
|
134
|
+
depth: 0,
|
|
135
|
+
originalText: "",
|
|
136
|
+
originalHTML: "",
|
|
137
|
+
lastMouseMoveTime: 0,
|
|
138
|
+
pendingMouseMove: null,
|
|
139
|
+
rawTarget: null
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function shouldSkipElement(element) {
|
|
143
|
+
const tagName = element.tagName.toLowerCase();
|
|
144
|
+
if (SKIP_ELEMENTS.has(tagName)) return true;
|
|
145
|
+
if (element.id?.startsWith("lego-element-selector")) return true;
|
|
146
|
+
const style = window.getComputedStyle(element);
|
|
147
|
+
if (style.display === "none" || style.visibility === "hidden") return true;
|
|
148
|
+
const rect = element.getBoundingClientRect();
|
|
149
|
+
if (rect.width < MIN_ELEMENT_SIZE && rect.height < MIN_ELEMENT_SIZE) return true;
|
|
150
|
+
if (rect.width === 0 && rect.height === 0 && !element.children.length) return true;
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
function getElementPriority(element) {
|
|
154
|
+
const tagName = element.tagName.toLowerCase();
|
|
155
|
+
let score = 0;
|
|
156
|
+
if (INTERACTIVE_ELEMENTS.has(tagName)) score += 100;
|
|
157
|
+
if (SEMANTIC_ELEMENTS.has(tagName)) score += 50;
|
|
158
|
+
if (element.hasAttribute("data-locator-path")) score += 200;
|
|
159
|
+
if (element.id) score += 20;
|
|
160
|
+
if (element.className && typeof element.className === "string") {
|
|
161
|
+
const classes = element.className.split(" ").filter((c) => c && !c.startsWith("__"));
|
|
162
|
+
score += Math.min(classes.length * 5, 25);
|
|
163
|
+
}
|
|
164
|
+
const textContent = element.textContent?.trim() || "";
|
|
165
|
+
if (textContent.length > 0 && textContent.length < 200) score += 15;
|
|
166
|
+
if ((tagName === "div" || tagName === "span") && !element.id && !element.className) {
|
|
167
|
+
score -= 30;
|
|
168
|
+
}
|
|
169
|
+
if (element.hasAttribute("role")) score += 25;
|
|
170
|
+
const attrs = element.attributes;
|
|
171
|
+
for (let i = 0; i < attrs.length; i++) {
|
|
172
|
+
if (attrs[i].name.startsWith("aria-")) {
|
|
173
|
+
score += 10;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return score;
|
|
178
|
+
}
|
|
179
|
+
function findBestElement(target) {
|
|
180
|
+
if (shouldSkipElement(target)) {
|
|
181
|
+
const parent = target.parentElement;
|
|
182
|
+
if (parent && parent !== document.body && parent !== document.documentElement) {
|
|
183
|
+
return findBestElement(parent);
|
|
184
|
+
}
|
|
185
|
+
return target;
|
|
186
|
+
}
|
|
187
|
+
const targetPriority = getElementPriority(target);
|
|
188
|
+
if (targetPriority < 20) {
|
|
189
|
+
const parent = target.parentElement;
|
|
190
|
+
if (parent && parent !== document.body && parent !== document.documentElement) {
|
|
191
|
+
const parentPriority = getElementPriority(parent);
|
|
192
|
+
if (parentPriority > targetPriority + 30) {
|
|
193
|
+
return findBestElement(parent);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
let current = target;
|
|
198
|
+
while (current && current !== document.body) {
|
|
199
|
+
const tagName = current.tagName.toLowerCase();
|
|
200
|
+
if (INTERACTIVE_ELEMENTS.has(tagName)) {
|
|
201
|
+
return current;
|
|
202
|
+
}
|
|
203
|
+
if (current !== target && SEMANTIC_ELEMENTS.has(tagName)) {
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
current = current.parentElement;
|
|
207
|
+
}
|
|
208
|
+
return target;
|
|
209
|
+
}
|
|
210
|
+
function getElementsAtPoint(x, y) {
|
|
211
|
+
const elements = [];
|
|
212
|
+
const allElements = document.elementsFromPoint(x, y);
|
|
213
|
+
for (const el of allElements) {
|
|
214
|
+
if (el === document.documentElement || el === document.body) continue;
|
|
215
|
+
if (shouldSkipElement(el)) continue;
|
|
216
|
+
elements.push(el);
|
|
217
|
+
}
|
|
218
|
+
return elements;
|
|
219
|
+
}
|
|
220
|
+
function getElementAtPoint(x, y) {
|
|
221
|
+
const elements = getElementsAtPoint(x, y);
|
|
222
|
+
if (elements.length === 0) return null;
|
|
223
|
+
return findBestElement(elements[0]);
|
|
224
|
+
}
|
|
225
|
+
function getBreadcrumb(element, maxDepth = 4) {
|
|
226
|
+
const parts = [];
|
|
227
|
+
let current = element;
|
|
228
|
+
let depth = 0;
|
|
229
|
+
while (current && current !== document.body && depth < maxDepth) {
|
|
230
|
+
const tagName = current.tagName.toLowerCase();
|
|
231
|
+
let part = tagName;
|
|
232
|
+
if (current.id) {
|
|
233
|
+
part += `#${current.id}`;
|
|
234
|
+
} else if (current.className && typeof current.className === "string") {
|
|
235
|
+
const classes = current.className.split(" ").filter((c) => c && !c.startsWith("__") && c.length < 20);
|
|
236
|
+
if (classes.length > 0) {
|
|
237
|
+
part += `.${classes[0]}`;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
parts.unshift(part);
|
|
241
|
+
current = current.parentElement;
|
|
242
|
+
depth++;
|
|
243
|
+
}
|
|
244
|
+
if (current && current !== document.body) {
|
|
245
|
+
parts.unshift("...");
|
|
246
|
+
}
|
|
247
|
+
return parts.join(" \u203A ");
|
|
248
|
+
}
|
|
249
|
+
function getCSSPreview(element) {
|
|
250
|
+
const style = window.getComputedStyle(element);
|
|
251
|
+
const result = {};
|
|
252
|
+
for (const prop of CSS_PREVIEW_PROPERTIES) {
|
|
253
|
+
const value = style.getPropertyValue(prop);
|
|
254
|
+
if (value && value !== "none" && value !== "auto" && value !== "normal") {
|
|
255
|
+
if (prop.includes("color") && value.startsWith("rgb")) {
|
|
256
|
+
result[prop] = rgbToHex(value);
|
|
257
|
+
} else {
|
|
258
|
+
result[prop] = value;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return result;
|
|
263
|
+
}
|
|
264
|
+
function rgbToHex(rgb) {
|
|
265
|
+
const match = rgb.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
|
|
266
|
+
if (!match) return rgb;
|
|
267
|
+
const r = parseInt(match[1]).toString(16).padStart(2, "0");
|
|
268
|
+
const g = parseInt(match[2]).toString(16).padStart(2, "0");
|
|
269
|
+
const b = parseInt(match[3]).toString(16).padStart(2, "0");
|
|
270
|
+
return `#${r}${g}${b}`;
|
|
271
|
+
}
|
|
272
|
+
function createOverlay() {
|
|
273
|
+
const overlay = document.createElement("div");
|
|
274
|
+
overlay.id = "lego-element-selector-overlay";
|
|
275
|
+
overlay.style.cssText = `
|
|
276
|
+
position: fixed;
|
|
277
|
+
pointer-events: none;
|
|
278
|
+
z-index: 2147483645;
|
|
279
|
+
background: rgba(59, 130, 246, 0.08);
|
|
280
|
+
border: 2px solid #3b82f6;
|
|
281
|
+
border-radius: 6px;
|
|
282
|
+
transition: all 0.08s ease-out;
|
|
283
|
+
box-shadow: 0 0 0 1px rgba(59, 130, 246, 0.3), inset 0 0 20px rgba(59, 130, 246, 0.05);
|
|
284
|
+
`;
|
|
285
|
+
document.body.appendChild(overlay);
|
|
286
|
+
return overlay;
|
|
287
|
+
}
|
|
288
|
+
function createSelectionOverlay() {
|
|
289
|
+
const overlay = document.createElement("div");
|
|
290
|
+
overlay.id = "lego-element-selector-selection";
|
|
291
|
+
overlay.style.cssText = `
|
|
292
|
+
position: fixed;
|
|
293
|
+
pointer-events: none;
|
|
294
|
+
z-index: 2147483646;
|
|
295
|
+
background: rgba(34, 197, 94, 0.1);
|
|
296
|
+
border: 2px solid #22c55e;
|
|
297
|
+
border-radius: 6px;
|
|
298
|
+
box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.15), 0 0 20px rgba(34, 197, 94, 0.2);
|
|
299
|
+
transition: all 0.12s ease-out;
|
|
300
|
+
animation: lego-pulse 2s ease-in-out infinite;
|
|
301
|
+
`;
|
|
302
|
+
if (!document.getElementById("lego-selector-styles")) {
|
|
303
|
+
const styleSheet = document.createElement("style");
|
|
304
|
+
styleSheet.id = "lego-selector-styles";
|
|
305
|
+
styleSheet.textContent = `
|
|
306
|
+
@keyframes lego-pulse {
|
|
307
|
+
0%, 100% { box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.15), 0 0 20px rgba(34, 197, 94, 0.2); }
|
|
308
|
+
50% { box-shadow: 0 0 0 5px rgba(34, 197, 94, 0.1), 0 0 30px rgba(34, 197, 94, 0.3); }
|
|
309
|
+
}
|
|
310
|
+
`;
|
|
311
|
+
document.head.appendChild(styleSheet);
|
|
312
|
+
}
|
|
313
|
+
document.body.appendChild(overlay);
|
|
314
|
+
return overlay;
|
|
315
|
+
}
|
|
316
|
+
function createTooltip() {
|
|
317
|
+
const tooltip = document.createElement("div");
|
|
318
|
+
tooltip.id = "lego-element-selector-tooltip";
|
|
319
|
+
tooltip.style.cssText = `
|
|
320
|
+
position: fixed;
|
|
321
|
+
pointer-events: none;
|
|
322
|
+
z-index: 2147483647;
|
|
323
|
+
background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
|
|
324
|
+
color: white;
|
|
325
|
+
padding: 8px 12px;
|
|
326
|
+
border-radius: 8px;
|
|
327
|
+
font-family: ui-sans-serif, system-ui, sans-serif;
|
|
328
|
+
font-size: 12px;
|
|
329
|
+
max-width: 400px;
|
|
330
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
|
331
|
+
transition: all 0.1s ease-out;
|
|
332
|
+
backdrop-filter: blur(8px);
|
|
333
|
+
`;
|
|
334
|
+
document.body.appendChild(tooltip);
|
|
335
|
+
return tooltip;
|
|
336
|
+
}
|
|
337
|
+
function createCSSPanel() {
|
|
338
|
+
const panel = document.createElement("div");
|
|
339
|
+
panel.id = "lego-element-selector-css";
|
|
340
|
+
panel.style.cssText = `
|
|
341
|
+
position: fixed;
|
|
342
|
+
pointer-events: none;
|
|
343
|
+
z-index: 2147483646;
|
|
344
|
+
background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
|
|
345
|
+
color: white;
|
|
346
|
+
padding: 10px 14px;
|
|
347
|
+
border-radius: 8px;
|
|
348
|
+
font-family: ui-monospace, monospace;
|
|
349
|
+
font-size: 11px;
|
|
350
|
+
max-width: 280px;
|
|
351
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
|
352
|
+
transition: all 0.15s ease-out;
|
|
353
|
+
opacity: 0;
|
|
354
|
+
transform: translateY(4px);
|
|
355
|
+
backdrop-filter: blur(8px);
|
|
356
|
+
`;
|
|
357
|
+
document.body.appendChild(panel);
|
|
358
|
+
return panel;
|
|
359
|
+
}
|
|
360
|
+
function updateCSSPanel(state, element) {
|
|
361
|
+
if (!state.cssPanel) {
|
|
362
|
+
state.cssPanel = createCSSPanel();
|
|
363
|
+
}
|
|
364
|
+
const cssInfo = getCSSPreview(element);
|
|
365
|
+
const entries = Object.entries(cssInfo);
|
|
366
|
+
if (entries.length === 0) {
|
|
367
|
+
state.cssPanel.style.opacity = "0";
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const html = entries.map(([prop, value]) => {
|
|
371
|
+
const colorDot = prop.includes("color") && value.startsWith("#") ? `<span style="display:inline-block;width:10px;height:10px;border-radius:2px;background:${value};margin-right:6px;vertical-align:middle;border:1px solid rgba(255,255,255,0.2);"></span>` : "";
|
|
372
|
+
return `<div style="display:flex;justify-content:space-between;align-items:center;padding:2px 0;">
|
|
373
|
+
<span style="color:#94a3b8;">${prop}:</span>
|
|
374
|
+
<span style="color:#e2e8f0;margin-left:12px;">${colorDot}${value}</span>
|
|
375
|
+
</div>`;
|
|
376
|
+
}).join("");
|
|
377
|
+
state.cssPanel.innerHTML = `
|
|
378
|
+
<div style="font-weight:600;color:#60a5fa;margin-bottom:6px;font-size:10px;text-transform:uppercase;letter-spacing:0.5px;">CSS Properties</div>
|
|
379
|
+
${html}
|
|
380
|
+
`;
|
|
381
|
+
const rect = element.getBoundingClientRect();
|
|
382
|
+
const tooltipHeight = state.tooltip?.offsetHeight || 40;
|
|
383
|
+
let panelTop = rect.top - tooltipHeight - 60;
|
|
384
|
+
const panelLeft = Math.min(rect.left, window.innerWidth - 300);
|
|
385
|
+
if (panelTop < 8) {
|
|
386
|
+
panelTop = rect.bottom + tooltipHeight + 16;
|
|
387
|
+
}
|
|
388
|
+
state.cssPanel.style.top = `${panelTop}px`;
|
|
389
|
+
state.cssPanel.style.left = `${Math.max(8, panelLeft)}px`;
|
|
390
|
+
state.cssPanel.style.opacity = "1";
|
|
391
|
+
state.cssPanel.style.transform = "translateY(0)";
|
|
392
|
+
}
|
|
393
|
+
function enableInlineEditing(state, element, onSave, onCancel) {
|
|
394
|
+
const originalOutline = element.style.outline;
|
|
395
|
+
const originalBoxShadow = element.style.boxShadow;
|
|
396
|
+
const originalBackground = element.style.background;
|
|
397
|
+
element.contentEditable = "true";
|
|
398
|
+
element.style.outline = "2px solid #3b82f6";
|
|
399
|
+
element.style.boxShadow = "0 0 0 4px rgba(59, 130, 246, 0.2)";
|
|
400
|
+
element.style.background = "rgba(59, 130, 246, 0.05)";
|
|
401
|
+
element.style.borderRadius = "4px";
|
|
402
|
+
const marker = document.createElement("div");
|
|
403
|
+
marker.id = "lego-inline-editor";
|
|
404
|
+
marker.style.display = "none";
|
|
405
|
+
marker.dataset.originalOutline = originalOutline;
|
|
406
|
+
marker.dataset.originalBoxShadow = originalBoxShadow;
|
|
407
|
+
marker.dataset.originalBackground = originalBackground;
|
|
408
|
+
document.body.appendChild(marker);
|
|
409
|
+
element.focus();
|
|
410
|
+
const range = document.createRange();
|
|
411
|
+
range.selectNodeContents(element);
|
|
412
|
+
range.collapse(false);
|
|
413
|
+
const selection = window.getSelection();
|
|
414
|
+
selection?.removeAllRanges();
|
|
415
|
+
selection?.addRange(range);
|
|
416
|
+
const handleKeyDown = (e) => {
|
|
417
|
+
if (e.key === "Escape") {
|
|
418
|
+
e.preventDefault();
|
|
419
|
+
e.stopPropagation();
|
|
420
|
+
onCancel();
|
|
421
|
+
} else if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
|
|
422
|
+
e.preventDefault();
|
|
423
|
+
e.stopPropagation();
|
|
424
|
+
onSave();
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
const handleBlur = (e) => {
|
|
428
|
+
setTimeout(() => {
|
|
429
|
+
if (document.activeElement !== element && state.isEditing) {
|
|
430
|
+
onSave();
|
|
431
|
+
}
|
|
432
|
+
}, 100);
|
|
433
|
+
};
|
|
434
|
+
element.addEventListener("keydown", handleKeyDown);
|
|
435
|
+
element.addEventListener("blur", handleBlur);
|
|
436
|
+
marker.__cleanup = () => {
|
|
437
|
+
element.removeEventListener("keydown", handleKeyDown);
|
|
438
|
+
element.removeEventListener("blur", handleBlur);
|
|
439
|
+
element.contentEditable = "false";
|
|
440
|
+
element.style.outline = originalOutline;
|
|
441
|
+
element.style.boxShadow = originalBoxShadow;
|
|
442
|
+
element.style.background = originalBackground;
|
|
443
|
+
element.style.borderRadius = "";
|
|
444
|
+
window.getSelection()?.removeAllRanges();
|
|
445
|
+
};
|
|
446
|
+
return marker;
|
|
447
|
+
}
|
|
448
|
+
function getElementTextContent(element) {
|
|
449
|
+
return element.innerText?.trim() || element.textContent?.trim() || "";
|
|
450
|
+
}
|
|
451
|
+
function getElementDepth(element) {
|
|
452
|
+
let depth = 0;
|
|
453
|
+
let current = element;
|
|
454
|
+
while (current && current !== document.body) {
|
|
455
|
+
depth++;
|
|
456
|
+
current = current.parentElement;
|
|
457
|
+
}
|
|
458
|
+
return depth;
|
|
459
|
+
}
|
|
460
|
+
function updateOverlayPosition(state, element, overlay) {
|
|
461
|
+
const targetElement = element || state.hoveredElement;
|
|
462
|
+
const targetOverlay = overlay || state.overlay;
|
|
463
|
+
if (!targetElement || !targetOverlay) return;
|
|
464
|
+
const rect = targetElement.getBoundingClientRect();
|
|
465
|
+
targetOverlay.style.top = `${rect.top}px`;
|
|
466
|
+
targetOverlay.style.left = `${rect.left}px`;
|
|
467
|
+
targetOverlay.style.width = `${rect.width}px`;
|
|
468
|
+
targetOverlay.style.height = `${rect.height}px`;
|
|
469
|
+
}
|
|
470
|
+
function updateTooltipPosition(state) {
|
|
471
|
+
if (!state.hoveredElement || !state.tooltip) return;
|
|
472
|
+
const rect = state.hoveredElement.getBoundingClientRect();
|
|
473
|
+
const viewportWidth = window.innerWidth;
|
|
474
|
+
let tooltipTop = rect.top - 32;
|
|
475
|
+
let tooltipLeft = rect.left;
|
|
476
|
+
if (tooltipTop < 8) {
|
|
477
|
+
tooltipTop = rect.bottom + 8;
|
|
478
|
+
}
|
|
479
|
+
const estimatedTooltipWidth = state.tooltip.offsetWidth || 150;
|
|
480
|
+
if (tooltipLeft + estimatedTooltipWidth > viewportWidth - 8) {
|
|
481
|
+
tooltipLeft = viewportWidth - estimatedTooltipWidth - 8;
|
|
482
|
+
}
|
|
483
|
+
if (tooltipLeft < 8) {
|
|
484
|
+
tooltipLeft = 8;
|
|
485
|
+
}
|
|
486
|
+
state.tooltip.style.top = `${tooltipTop}px`;
|
|
487
|
+
state.tooltip.style.left = `${tooltipLeft}px`;
|
|
488
|
+
}
|
|
489
|
+
function updateSelectionOverlayPosition(state) {
|
|
490
|
+
if (!state.selectedElement || !state.selectionOverlay) return;
|
|
491
|
+
updateOverlayPosition(state, state.selectedElement, state.selectionOverlay);
|
|
492
|
+
}
|
|
493
|
+
function getElementInfo(element) {
|
|
494
|
+
const filePath = element.getAttribute("data-locator-path") || "";
|
|
495
|
+
const line = element.getAttribute("data-locator-line");
|
|
496
|
+
const depth = getElementDepth(element);
|
|
497
|
+
const id = element.id ? `#${element.id}` : "";
|
|
498
|
+
const classes = element.className && typeof element.className === "string" ? element.className.split(" ").filter((c) => c).map((c) => `.${c}`).join("") : "";
|
|
499
|
+
return {
|
|
500
|
+
tagName: element.tagName.toLowerCase(),
|
|
501
|
+
selector: element.tagName.toLowerCase() + id + classes.slice(0, 50),
|
|
502
|
+
filePath,
|
|
503
|
+
line: line ? parseInt(line) : void 0,
|
|
504
|
+
depth,
|
|
505
|
+
rect: element.getBoundingClientRect()
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
function highlightElement(state, element) {
|
|
509
|
+
state.hoveredElement = element;
|
|
510
|
+
if (!state.overlay) {
|
|
511
|
+
state.overlay = createOverlay();
|
|
512
|
+
}
|
|
513
|
+
if (!state.tooltip) {
|
|
514
|
+
state.tooltip = createTooltip();
|
|
515
|
+
}
|
|
516
|
+
state.overlay.style.display = "block";
|
|
517
|
+
state.tooltip.style.display = "block";
|
|
518
|
+
const info = getElementInfo(element);
|
|
519
|
+
const breadcrumb = getBreadcrumb(element);
|
|
520
|
+
state.depth = info.depth;
|
|
521
|
+
const isSelectedElement = state.isSelected && state.selectedElement === element;
|
|
522
|
+
const priority = getElementPriority(element);
|
|
523
|
+
const priorityIndicator = priority >= 100 ? "\u{1F3AF}" : priority >= 50 ? "\u{1F4E6}" : "";
|
|
524
|
+
const tagBadgeColor = INTERACTIVE_ELEMENTS.has(info.tagName) ? "#22c55e" : SEMANTIC_ELEMENTS.has(info.tagName) ? "#3b82f6" : "#64748b";
|
|
525
|
+
state.tooltip.innerHTML = `
|
|
526
|
+
<div style="display:flex;flex-direction:column;gap:6px;">
|
|
527
|
+
<div style="display:flex;align-items:center;gap:8px;">
|
|
528
|
+
<span style="background:${tagBadgeColor};padding:2px 8px;border-radius:4px;font-family:ui-monospace,monospace;font-size:11px;font-weight:600;">
|
|
529
|
+
${priorityIndicator} ${info.selector}
|
|
530
|
+
</span>
|
|
531
|
+
${info.filePath ? `<span style="color:#94a3b8;font-size:11px;">\u{1F4C4} ${info.filePath.split("/").pop()}${info.line ? `:${info.line}` : ""}</span>` : ""}
|
|
532
|
+
</div>
|
|
533
|
+
<div style="color:#64748b;font-size:10px;font-family:ui-monospace,monospace;">
|
|
534
|
+
${breadcrumb}
|
|
535
|
+
</div>
|
|
536
|
+
<div style="color:#94a3b8;font-size:10px;border-top:1px solid rgba(255,255,255,0.1);padding-top:6px;margin-top:2px;">
|
|
537
|
+
${isSelectedElement ? `<span style="color:#22c55e;">\u2713 Selected</span> \xB7 Click to edit \xB7 <kbd style="background:#334155;padding:1px 4px;border-radius:3px;">E</kbd> quick edit` : state.isSelected ? `Click to select` : `Click select \xB7 Double-click edit \xB7 <kbd style="background:#334155;padding:1px 4px;border-radius:3px;">\u2191\u2193\u2190\u2192</kbd> navigate`}
|
|
538
|
+
</div>
|
|
539
|
+
</div>
|
|
540
|
+
`;
|
|
541
|
+
updateOverlayPosition(state);
|
|
542
|
+
updateTooltipPosition(state);
|
|
543
|
+
updateCSSPanel(state, element);
|
|
544
|
+
sendToParent("HOVER_ELEMENT", {
|
|
545
|
+
tagName: info.tagName,
|
|
546
|
+
rect: info.rect,
|
|
547
|
+
filePath: info.filePath || void 0,
|
|
548
|
+
line: info.line,
|
|
549
|
+
depth: info.depth,
|
|
550
|
+
breadcrumb
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
function navigateDOM(state, direction) {
|
|
554
|
+
if (!state.hoveredElement) return;
|
|
555
|
+
let target = null;
|
|
556
|
+
switch (direction) {
|
|
557
|
+
case "parent":
|
|
558
|
+
target = state.hoveredElement.parentElement;
|
|
559
|
+
if (target && target === document.body) target = null;
|
|
560
|
+
break;
|
|
561
|
+
case "child":
|
|
562
|
+
target = state.hoveredElement.firstElementChild;
|
|
563
|
+
break;
|
|
564
|
+
case "next":
|
|
565
|
+
target = state.hoveredElement.nextElementSibling;
|
|
566
|
+
break;
|
|
567
|
+
case "prev":
|
|
568
|
+
target = state.hoveredElement.previousElementSibling;
|
|
569
|
+
break;
|
|
570
|
+
}
|
|
571
|
+
if (target && target !== document.documentElement && target !== document.body) {
|
|
572
|
+
highlightElement(state, target);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
function setupElementSelector() {
|
|
576
|
+
const state = createElementSelectorState();
|
|
577
|
+
function saveInlineEdit() {
|
|
578
|
+
if (!state.inlineEditor || !state.selectedElement) return;
|
|
579
|
+
const newText = getElementTextContent(state.selectedElement);
|
|
580
|
+
const info = getElementInfo(state.selectedElement);
|
|
581
|
+
if (newText !== state.originalText && info.filePath) {
|
|
582
|
+
sendToParent("SAVE_INLINE_EDIT", {
|
|
583
|
+
filePath: info.filePath,
|
|
584
|
+
originalContent: state.originalText,
|
|
585
|
+
newContent: newText,
|
|
586
|
+
line: info.line
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
exitEditMode();
|
|
590
|
+
}
|
|
591
|
+
function cancelInlineEdit() {
|
|
592
|
+
if (state.selectedElement && state.originalHTML !== void 0) {
|
|
593
|
+
state.selectedElement.innerHTML = state.originalHTML;
|
|
594
|
+
}
|
|
595
|
+
sendToParent("CANCEL_INLINE_EDIT");
|
|
596
|
+
exitEditMode();
|
|
597
|
+
}
|
|
598
|
+
function exitEditMode() {
|
|
599
|
+
state.isEditing = false;
|
|
600
|
+
if (state.inlineEditor) {
|
|
601
|
+
const cleanup = state.inlineEditor.__cleanup;
|
|
602
|
+
if (cleanup) cleanup();
|
|
603
|
+
state.inlineEditor.remove();
|
|
604
|
+
state.inlineEditor = null;
|
|
605
|
+
}
|
|
606
|
+
clearSelection();
|
|
607
|
+
if (state.cssPanel) {
|
|
608
|
+
state.cssPanel.style.opacity = "0";
|
|
609
|
+
}
|
|
610
|
+
if (state.isActive && state.hoveredElement) {
|
|
611
|
+
if (state.overlay) state.overlay.style.display = "block";
|
|
612
|
+
if (state.tooltip) state.tooltip.style.display = "block";
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
function enterEditMode() {
|
|
616
|
+
if (!state.selectedElement) return;
|
|
617
|
+
state.isEditing = true;
|
|
618
|
+
state.originalHTML = state.selectedElement.innerHTML;
|
|
619
|
+
if (state.overlay) state.overlay.style.display = "none";
|
|
620
|
+
if (state.tooltip) state.tooltip.style.display = "none";
|
|
621
|
+
if (state.selectionOverlay) state.selectionOverlay.style.display = "none";
|
|
622
|
+
if (state.cssPanel) state.cssPanel.style.opacity = "0";
|
|
623
|
+
state.inlineEditor = enableInlineEditing(state, state.selectedElement, saveInlineEdit, cancelInlineEdit);
|
|
624
|
+
const info = getElementInfo(state.selectedElement);
|
|
625
|
+
sendToParent("START_INLINE_EDIT", {
|
|
626
|
+
tagName: info.tagName,
|
|
627
|
+
filePath: info.filePath,
|
|
628
|
+
line: info.line,
|
|
629
|
+
text: state.originalText
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
function clearSelection() {
|
|
633
|
+
state.isSelected = false;
|
|
634
|
+
state.selectedElement = null;
|
|
635
|
+
state.originalText = "";
|
|
636
|
+
state.originalHTML = "";
|
|
637
|
+
if (state.selectionOverlay) {
|
|
638
|
+
state.selectionOverlay.style.display = "none";
|
|
639
|
+
}
|
|
640
|
+
if (state.cssPanel) {
|
|
641
|
+
state.cssPanel.style.opacity = "0";
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
function selectElement() {
|
|
645
|
+
if (!state.hoveredElement) return;
|
|
646
|
+
if (state.isSelected && state.selectedElement === state.hoveredElement) {
|
|
647
|
+
enterEditMode();
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
if (state.isSelected) {
|
|
651
|
+
clearSelection();
|
|
652
|
+
}
|
|
653
|
+
state.isSelected = true;
|
|
654
|
+
state.selectedElement = state.hoveredElement;
|
|
655
|
+
const info = getElementInfo(state.hoveredElement);
|
|
656
|
+
const text = getElementTextContent(state.hoveredElement);
|
|
657
|
+
const cssInfo = getCSSPreview(state.hoveredElement);
|
|
658
|
+
const breadcrumb = getBreadcrumb(state.hoveredElement);
|
|
659
|
+
state.originalText = text;
|
|
660
|
+
if (!state.selectionOverlay) {
|
|
661
|
+
state.selectionOverlay = createSelectionOverlay();
|
|
662
|
+
}
|
|
663
|
+
state.selectionOverlay.style.display = "block";
|
|
664
|
+
updateSelectionOverlayPosition(state);
|
|
665
|
+
if (state.tooltip) {
|
|
666
|
+
const tagBadgeColor = INTERACTIVE_ELEMENTS.has(info.tagName) ? "#22c55e" : SEMANTIC_ELEMENTS.has(info.tagName) ? "#3b82f6" : "#64748b";
|
|
667
|
+
state.tooltip.innerHTML = `
|
|
668
|
+
<div style="display:flex;flex-direction:column;gap:6px;">
|
|
669
|
+
<div style="display:flex;align-items:center;gap:8px;">
|
|
670
|
+
<span style="background:${tagBadgeColor};padding:2px 8px;border-radius:4px;font-family:ui-monospace,monospace;font-size:11px;font-weight:600;">
|
|
671
|
+
\u2713 ${info.selector}
|
|
672
|
+
</span>
|
|
673
|
+
${info.filePath ? `<span style="color:#94a3b8;font-size:11px;">\u{1F4C4} ${info.filePath.split("/").pop()}${info.line ? `:${info.line}` : ""}</span>` : ""}
|
|
674
|
+
</div>
|
|
675
|
+
<div style="color:#64748b;font-size:10px;font-family:ui-monospace,monospace;">
|
|
676
|
+
${breadcrumb}
|
|
677
|
+
</div>
|
|
678
|
+
<div style="color:#22c55e;font-size:10px;border-top:1px solid rgba(255,255,255,0.1);padding-top:6px;margin-top:2px;">
|
|
679
|
+
\u2713 Selected \xB7 Click again to edit \xB7 <kbd style="background:#334155;padding:1px 4px;border-radius:3px;">Enter</kbd> or <kbd style="background:#334155;padding:1px 4px;border-radius:3px;">E</kbd>
|
|
680
|
+
</div>
|
|
681
|
+
</div>
|
|
682
|
+
`;
|
|
683
|
+
}
|
|
684
|
+
sendToParent("CLICK_ELEMENT", {
|
|
685
|
+
tagName: info.tagName,
|
|
686
|
+
filePath: info.filePath,
|
|
687
|
+
line: info.line,
|
|
688
|
+
depth: info.depth,
|
|
689
|
+
text,
|
|
690
|
+
cssInfo
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
function startEditing() {
|
|
694
|
+
if (!state.hoveredElement) return;
|
|
695
|
+
state.selectedElement = state.hoveredElement;
|
|
696
|
+
const info = getElementInfo(state.hoveredElement);
|
|
697
|
+
const text = getElementTextContent(state.hoveredElement);
|
|
698
|
+
state.originalText = text;
|
|
699
|
+
sendToParent("CLICK_ELEMENT", {
|
|
700
|
+
tagName: info.tagName,
|
|
701
|
+
filePath: info.filePath,
|
|
702
|
+
line: info.line,
|
|
703
|
+
depth: info.depth,
|
|
704
|
+
text
|
|
705
|
+
});
|
|
706
|
+
enterEditMode();
|
|
707
|
+
}
|
|
708
|
+
const handleMouseMove = (e) => {
|
|
709
|
+
if (!state.isActive || state.isEditing) return;
|
|
710
|
+
const now = performance.now();
|
|
711
|
+
if (now - state.lastMouseMoveTime < MOUSEMOVE_DEBOUNCE) {
|
|
712
|
+
if (state.pendingMouseMove) cancelAnimationFrame(state.pendingMouseMove);
|
|
713
|
+
state.pendingMouseMove = requestAnimationFrame(() => processMouseMove(e));
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
state.lastMouseMoveTime = now;
|
|
717
|
+
processMouseMove(e);
|
|
718
|
+
};
|
|
719
|
+
const processMouseMove = (e) => {
|
|
720
|
+
const element = getElementAtPoint(e.clientX, e.clientY);
|
|
721
|
+
if (!element) return;
|
|
722
|
+
if (element === state.hoveredElement) return;
|
|
723
|
+
state.rawTarget = e.target;
|
|
724
|
+
highlightElement(state, element);
|
|
725
|
+
};
|
|
726
|
+
const handleScroll = () => {
|
|
727
|
+
if (state.isActive && state.hoveredElement && !state.isEditing) {
|
|
728
|
+
updateOverlayPosition(state);
|
|
729
|
+
updateTooltipPosition(state);
|
|
730
|
+
updateCSSPanel(state, state.hoveredElement);
|
|
731
|
+
}
|
|
732
|
+
if (state.isSelected && state.selectedElement) {
|
|
733
|
+
updateSelectionOverlayPosition(state);
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
const handleResize = () => {
|
|
737
|
+
if (state.isActive && state.hoveredElement && !state.isEditing) {
|
|
738
|
+
updateOverlayPosition(state);
|
|
739
|
+
updateTooltipPosition(state);
|
|
740
|
+
updateCSSPanel(state, state.hoveredElement);
|
|
741
|
+
}
|
|
742
|
+
if (state.isSelected && state.selectedElement) {
|
|
743
|
+
updateSelectionOverlayPosition(state);
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
const handleKeyDown = (e) => {
|
|
747
|
+
if (!state.isActive) return;
|
|
748
|
+
if (state.isEditing) {
|
|
749
|
+
if (e.key === "Escape") {
|
|
750
|
+
e.preventDefault();
|
|
751
|
+
cancelInlineEdit();
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
switch (e.key) {
|
|
757
|
+
case "Escape":
|
|
758
|
+
if (state.isSelected) {
|
|
759
|
+
e.preventDefault();
|
|
760
|
+
clearSelection();
|
|
761
|
+
} else {
|
|
762
|
+
sendToParent("SELECTOR_EXIT", true);
|
|
763
|
+
}
|
|
764
|
+
break;
|
|
765
|
+
case "ArrowUp":
|
|
766
|
+
e.preventDefault();
|
|
767
|
+
navigateDOM(state, "parent");
|
|
768
|
+
break;
|
|
769
|
+
case "ArrowDown":
|
|
770
|
+
e.preventDefault();
|
|
771
|
+
navigateDOM(state, "child");
|
|
772
|
+
break;
|
|
773
|
+
case "ArrowLeft":
|
|
774
|
+
e.preventDefault();
|
|
775
|
+
navigateDOM(state, "prev");
|
|
776
|
+
break;
|
|
777
|
+
case "ArrowRight":
|
|
778
|
+
e.preventDefault();
|
|
779
|
+
navigateDOM(state, "next");
|
|
780
|
+
break;
|
|
781
|
+
case "Enter":
|
|
782
|
+
e.preventDefault();
|
|
783
|
+
if (state.isSelected && state.selectedElement === state.hoveredElement) {
|
|
784
|
+
enterEditMode();
|
|
785
|
+
} else {
|
|
786
|
+
selectElement();
|
|
787
|
+
}
|
|
788
|
+
break;
|
|
789
|
+
case "e":
|
|
790
|
+
case "E":
|
|
791
|
+
if (state.hoveredElement) {
|
|
792
|
+
e.preventDefault();
|
|
793
|
+
startEditing();
|
|
794
|
+
}
|
|
795
|
+
break;
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
const handleClick = (e) => {
|
|
799
|
+
if (!state.isActive) return;
|
|
800
|
+
if (state.isEditing) {
|
|
801
|
+
const target = e.target;
|
|
802
|
+
if (state.selectedElement?.contains(target) || target === state.selectedElement) {
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
e.preventDefault();
|
|
806
|
+
e.stopPropagation();
|
|
807
|
+
e.stopImmediatePropagation();
|
|
808
|
+
saveInlineEdit();
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
e.preventDefault();
|
|
812
|
+
e.stopPropagation();
|
|
813
|
+
e.stopImmediatePropagation();
|
|
814
|
+
selectElement();
|
|
815
|
+
};
|
|
816
|
+
const handleDoubleClick = (e) => {
|
|
817
|
+
if (!state.isActive || state.isEditing) return;
|
|
818
|
+
e.preventDefault();
|
|
819
|
+
e.stopPropagation();
|
|
820
|
+
e.stopImmediatePropagation();
|
|
821
|
+
startEditing();
|
|
822
|
+
};
|
|
823
|
+
const activateSelector = () => {
|
|
824
|
+
state.isActive = true;
|
|
825
|
+
document.addEventListener("mousemove", handleMouseMove, true);
|
|
826
|
+
document.addEventListener("click", handleClick, true);
|
|
827
|
+
document.addEventListener("dblclick", handleDoubleClick, true);
|
|
828
|
+
document.addEventListener("keydown", handleKeyDown, true);
|
|
829
|
+
window.addEventListener("scroll", handleScroll, true);
|
|
830
|
+
window.addEventListener("resize", handleResize);
|
|
831
|
+
document.body.style.cursor = "crosshair";
|
|
832
|
+
state.overlay = createOverlay();
|
|
833
|
+
state.tooltip = createTooltip();
|
|
834
|
+
};
|
|
835
|
+
const deactivateSelector = () => {
|
|
836
|
+
state.isActive = false;
|
|
837
|
+
state.isEditing = false;
|
|
838
|
+
state.isSelected = false;
|
|
839
|
+
if (state.pendingMouseMove) {
|
|
840
|
+
cancelAnimationFrame(state.pendingMouseMove);
|
|
841
|
+
state.pendingMouseMove = null;
|
|
842
|
+
}
|
|
843
|
+
document.removeEventListener("mousemove", handleMouseMove, true);
|
|
844
|
+
document.removeEventListener("click", handleClick, true);
|
|
845
|
+
document.removeEventListener("dblclick", handleDoubleClick, true);
|
|
846
|
+
document.removeEventListener("keydown", handleKeyDown, true);
|
|
847
|
+
window.removeEventListener("scroll", handleScroll, true);
|
|
848
|
+
window.removeEventListener("resize", handleResize);
|
|
849
|
+
if (state.overlay) {
|
|
850
|
+
state.overlay.remove();
|
|
851
|
+
state.overlay = null;
|
|
852
|
+
}
|
|
853
|
+
if (state.selectionOverlay) {
|
|
854
|
+
state.selectionOverlay.remove();
|
|
855
|
+
state.selectionOverlay = null;
|
|
856
|
+
}
|
|
857
|
+
if (state.tooltip) {
|
|
858
|
+
state.tooltip.remove();
|
|
859
|
+
state.tooltip = null;
|
|
860
|
+
}
|
|
861
|
+
if (state.cssPanel) {
|
|
862
|
+
state.cssPanel.remove();
|
|
863
|
+
state.cssPanel = null;
|
|
864
|
+
}
|
|
865
|
+
if (state.inlineEditor) {
|
|
866
|
+
state.inlineEditor.remove();
|
|
867
|
+
state.inlineEditor = null;
|
|
868
|
+
}
|
|
869
|
+
state.hoveredElement = null;
|
|
870
|
+
state.selectedElement = null;
|
|
871
|
+
state.rawTarget = null;
|
|
872
|
+
state.originalText = "";
|
|
873
|
+
document.body.style.cursor = "";
|
|
874
|
+
state.depth = 0;
|
|
875
|
+
};
|
|
876
|
+
window.addEventListener("message", (e) => {
|
|
877
|
+
const msg = e.data;
|
|
878
|
+
if (msg.type === "TOGGLE_ELEMENT_SELECTOR") {
|
|
879
|
+
if (msg.payload) {
|
|
880
|
+
activateSelector();
|
|
881
|
+
} else {
|
|
882
|
+
deactivateSelector();
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
function initIframeBridge() {
|
|
888
|
+
try {
|
|
889
|
+
if (window.parent !== window) {
|
|
890
|
+
setupIframeBridge();
|
|
891
|
+
setupElementSelector();
|
|
892
|
+
}
|
|
893
|
+
} catch {
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
export {
|
|
898
|
+
sendToParent,
|
|
899
|
+
setupIframeBridge,
|
|
900
|
+
setupElementSelector,
|
|
901
|
+
initIframeBridge
|
|
902
|
+
};
|