@base44-preview/vite-plugin 0.2.22-pr.36.db00ef7 → 0.2.22-pr.37.68542f2
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/utils.d.ts +0 -6
- package/dist/injections/utils.d.ts.map +1 -1
- package/dist/injections/utils.js +0 -25
- package/dist/injections/utils.js.map +1 -1
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/core.d.ts +25 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/core.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/core.js +78 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/core.js.map +1 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/index.d.ts +4 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/index.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/index.js +4 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/index.js.map +1 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/styles.d.ts +9 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/styles.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/styles.js +26 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/styles.js.map +1 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/validation.d.ts +10 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/validation.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/validation.js +60 -0
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/validation.js.map +1 -0
- package/dist/injections/visual-edit-agent/constants.d.ts +10 -0
- package/dist/injections/visual-edit-agent/constants.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/constants.js +10 -0
- package/dist/injections/visual-edit-agent/constants.js.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/click-handlers.d.ts +10 -0
- package/dist/injections/visual-edit-agent/handlers/click-handlers.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/click-handlers.js +107 -0
- package/dist/injections/visual-edit-agent/handlers/click-handlers.js.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/hover-handlers.d.ts +14 -0
- package/dist/injections/visual-edit-agent/handlers/hover-handlers.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/hover-handlers.js +64 -0
- package/dist/injections/visual-edit-agent/handlers/hover-handlers.js.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/inline-edit-handlers.d.ts +14 -0
- package/dist/injections/visual-edit-agent/handlers/inline-edit-handlers.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/inline-edit-handlers.js +104 -0
- package/dist/injections/visual-edit-agent/handlers/inline-edit-handlers.js.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/message-handlers.d.ts +26 -0
- package/dist/injections/visual-edit-agent/handlers/message-handlers.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/message-handlers.js +145 -0
- package/dist/injections/visual-edit-agent/handlers/message-handlers.js.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.d.ts +7 -0
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.js +42 -0
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.js.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.d.ts +11 -0
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.js +32 -0
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.js.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/messages/types.d.ts +86 -0
- package/dist/injections/visual-edit-agent/handlers/messages/types.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/handlers/messages/types.js +28 -0
- package/dist/injections/visual-edit-agent/handlers/messages/types.js.map +1 -0
- package/dist/injections/visual-edit-agent/index.d.ts +5 -0
- package/dist/injections/visual-edit-agent/index.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/index.js +106 -0
- package/dist/injections/visual-edit-agent/index.js.map +1 -0
- package/dist/injections/visual-edit-agent/state/agent-state.d.ts +17 -0
- package/dist/injections/visual-edit-agent/state/agent-state.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/state/agent-state.js +18 -0
- package/dist/injections/visual-edit-agent/state/agent-state.js.map +1 -0
- package/dist/injections/visual-edit-agent/ui/overlay.d.ts +26 -0
- package/dist/injections/visual-edit-agent/ui/overlay.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/ui/overlay.js +100 -0
- package/dist/injections/visual-edit-agent/ui/overlay.js.map +1 -0
- package/dist/injections/visual-edit-agent/utils/dom-utils.d.ts +14 -0
- package/dist/injections/visual-edit-agent/utils/dom-utils.d.ts.map +1 -0
- package/dist/injections/visual-edit-agent/utils/dom-utils.js +34 -0
- package/dist/injections/visual-edit-agent/utils/dom-utils.js.map +1 -0
- package/dist/injections/visual-edit-agent.d.ts +1 -1
- package/dist/injections/visual-edit-agent.d.ts.map +1 -1
- package/dist/injections/visual-edit-agent.js +1 -474
- package/dist/injections/visual-edit-agent.js.map +1 -1
- package/dist/statics/index.mjs +5 -1
- package/dist/statics/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/injections/utils.ts +0 -34
- package/src/injections/visual-edit-agent/README.md +222 -0
- package/src/injections/visual-edit-agent/capabilities/inline-editing/core.ts +100 -0
- package/src/injections/visual-edit-agent/capabilities/inline-editing/index.ts +10 -0
- package/src/injections/visual-edit-agent/capabilities/inline-editing/styles.ts +26 -0
- package/src/injections/visual-edit-agent/capabilities/inline-editing/validation.ts +67 -0
- package/src/injections/visual-edit-agent/constants.ts +9 -0
- package/src/injections/visual-edit-agent/handlers/click-handlers.ts +134 -0
- package/src/injections/visual-edit-agent/handlers/hover-handlers.ts +78 -0
- package/src/injections/visual-edit-agent/handlers/inline-edit-handlers.ts +136 -0
- package/src/injections/visual-edit-agent/handlers/message-handlers.ts +191 -0
- package/src/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.ts +51 -0
- package/src/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.ts +40 -0
- package/src/injections/visual-edit-agent/handlers/messages/types.ts +112 -0
- package/src/injections/visual-edit-agent/index.ts +120 -0
- package/src/injections/visual-edit-agent/state/agent-state.ts +31 -0
- package/src/injections/visual-edit-agent/ui/overlay.ts +121 -0
- package/src/injections/visual-edit-agent/utils/dom-utils.ts +39 -0
- package/src/injections/visual-edit-agent.ts +1 -577
- package/dist/injections/layer-dropdown/consts.d.ts +0 -15
- package/dist/injections/layer-dropdown/consts.d.ts.map +0 -1
- package/dist/injections/layer-dropdown/consts.js +0 -36
- package/dist/injections/layer-dropdown/consts.js.map +0 -1
- package/dist/injections/layer-dropdown/controller.d.ts +0 -4
- package/dist/injections/layer-dropdown/controller.d.ts.map +0 -1
- package/dist/injections/layer-dropdown/controller.js +0 -85
- package/dist/injections/layer-dropdown/controller.js.map +0 -1
- package/dist/injections/layer-dropdown/dropdown-ui.d.ts +0 -13
- package/dist/injections/layer-dropdown/dropdown-ui.d.ts.map +0 -1
- package/dist/injections/layer-dropdown/dropdown-ui.js +0 -158
- package/dist/injections/layer-dropdown/dropdown-ui.js.map +0 -1
- package/dist/injections/layer-dropdown/types.d.ts +0 -21
- package/dist/injections/layer-dropdown/types.d.ts.map +0 -1
- package/dist/injections/layer-dropdown/types.js +0 -3
- package/dist/injections/layer-dropdown/types.js.map +0 -1
- package/dist/injections/layer-dropdown/utils.d.ts +0 -23
- package/dist/injections/layer-dropdown/utils.d.ts.map +0 -1
- package/dist/injections/layer-dropdown/utils.js +0 -119
- package/dist/injections/layer-dropdown/utils.js.map +0 -1
- package/src/injections/layer-dropdown/consts.ts +0 -44
- package/src/injections/layer-dropdown/controller.ts +0 -105
- package/src/injections/layer-dropdown/dropdown-ui.ts +0 -221
- package/src/injections/layer-dropdown/types.ts +0 -24
- package/src/injections/layer-dropdown/utils.ts +0 -148
|
@@ -1,577 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { createLayerController } from "./layer-dropdown/controller.js";
|
|
3
|
-
import { LAYER_DROPDOWN_ATTR } from "./layer-dropdown/consts.js";
|
|
4
|
-
|
|
5
|
-
export function setupVisualEditAgent() {
|
|
6
|
-
// State variables (replacing React useState/useRef)
|
|
7
|
-
let isVisualEditMode = false;
|
|
8
|
-
let isPopoverDragging = false;
|
|
9
|
-
let isDropdownOpen = false;
|
|
10
|
-
let hoverOverlays: HTMLDivElement[] = [];
|
|
11
|
-
let selectedOverlays: HTMLDivElement[] = [];
|
|
12
|
-
let currentHighlightedElements: Element[] = [];
|
|
13
|
-
let selectedElementId: string | null = null;
|
|
14
|
-
|
|
15
|
-
// Create overlay element
|
|
16
|
-
const createOverlay = (isSelected = false): HTMLDivElement => {
|
|
17
|
-
const overlay = document.createElement("div");
|
|
18
|
-
overlay.style.position = "absolute";
|
|
19
|
-
overlay.style.pointerEvents = "none";
|
|
20
|
-
overlay.style.transition = "all 0.1s ease-in-out";
|
|
21
|
-
overlay.style.zIndex = "9999";
|
|
22
|
-
|
|
23
|
-
if (isSelected) {
|
|
24
|
-
overlay.style.border = "2px solid #2563EB";
|
|
25
|
-
} else {
|
|
26
|
-
overlay.style.border = "2px solid #95a5fc";
|
|
27
|
-
overlay.style.backgroundColor = "rgba(99, 102, 241, 0.05)";
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return overlay;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
// Position overlay relative to element
|
|
34
|
-
const positionOverlay = (
|
|
35
|
-
overlay: HTMLDivElement,
|
|
36
|
-
element: Element,
|
|
37
|
-
isSelected = false
|
|
38
|
-
) => {
|
|
39
|
-
if (!element || !isVisualEditMode) return;
|
|
40
|
-
|
|
41
|
-
const htmlElement = element as HTMLElement;
|
|
42
|
-
// Force layout recalculation
|
|
43
|
-
void htmlElement.offsetWidth;
|
|
44
|
-
|
|
45
|
-
const rect = element.getBoundingClientRect();
|
|
46
|
-
overlay.style.top = `${rect.top + window.scrollY}px`;
|
|
47
|
-
overlay.style.left = `${rect.left + window.scrollX}px`;
|
|
48
|
-
overlay.style.width = `${rect.width}px`;
|
|
49
|
-
overlay.style.height = `${rect.height}px`;
|
|
50
|
-
|
|
51
|
-
// Check if label already exists in overlay
|
|
52
|
-
let label = overlay.querySelector("div") as HTMLDivElement | null;
|
|
53
|
-
|
|
54
|
-
if (!label) {
|
|
55
|
-
label = document.createElement("div");
|
|
56
|
-
label.textContent = element.tagName.toLowerCase();
|
|
57
|
-
label.style.position = "absolute";
|
|
58
|
-
label.style.top = "-27px";
|
|
59
|
-
label.style.left = "-2px";
|
|
60
|
-
label.style.padding = "2px 8px";
|
|
61
|
-
label.style.fontSize = "11px";
|
|
62
|
-
label.style.fontWeight = isSelected ? "500" : "400";
|
|
63
|
-
label.style.color = isSelected ? "#ffffff" : "#526cff";
|
|
64
|
-
label.style.backgroundColor = isSelected ? "#526cff" : "#DBEAFE";
|
|
65
|
-
label.style.borderRadius = "3px";
|
|
66
|
-
label.style.minWidth = "24px";
|
|
67
|
-
label.style.textAlign = "center";
|
|
68
|
-
overlay.appendChild(label);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
// Clear hover overlays
|
|
73
|
-
const clearHoverOverlays = () => {
|
|
74
|
-
hoverOverlays.forEach((overlay) => {
|
|
75
|
-
if (overlay && overlay.parentNode) {
|
|
76
|
-
overlay.remove();
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
hoverOverlays = [];
|
|
80
|
-
currentHighlightedElements = [];
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const clearSelectedOverlays = () => {
|
|
84
|
-
selectedOverlays.forEach((overlay) => {
|
|
85
|
-
if (overlay && overlay.parentNode) {
|
|
86
|
-
overlay.remove();
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
selectedOverlays = [];
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const notifyElementSelected = (element: Element) => {
|
|
93
|
-
const htmlElement = element as HTMLElement;
|
|
94
|
-
const rect = element.getBoundingClientRect();
|
|
95
|
-
const svgElement = element as SVGElement;
|
|
96
|
-
window.parent.postMessage({
|
|
97
|
-
type: "element-selected",
|
|
98
|
-
tagName: element.tagName,
|
|
99
|
-
classes:
|
|
100
|
-
(svgElement.className as unknown as SVGAnimatedString)?.baseVal ||
|
|
101
|
-
element.className ||
|
|
102
|
-
"",
|
|
103
|
-
visualSelectorId: getElementSelectorId(element),
|
|
104
|
-
content: htmlElement.innerText,
|
|
105
|
-
dataSourceLocation: htmlElement.dataset.sourceLocation,
|
|
106
|
-
isDynamicContent: htmlElement.dataset.dynamicContent === "true",
|
|
107
|
-
linenumber: htmlElement.dataset.linenumber,
|
|
108
|
-
filename: htmlElement.dataset.filename,
|
|
109
|
-
position: {
|
|
110
|
-
top: rect.top,
|
|
111
|
-
left: rect.left,
|
|
112
|
-
right: rect.right,
|
|
113
|
-
bottom: rect.bottom,
|
|
114
|
-
width: rect.width,
|
|
115
|
-
height: rect.height,
|
|
116
|
-
centerX: rect.left + rect.width / 2,
|
|
117
|
-
centerY: rect.top + rect.height / 2,
|
|
118
|
-
},
|
|
119
|
-
}, "*");
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
// Select an element: create overlays, update state, notify parent
|
|
123
|
-
const selectElement = (element: Element): HTMLDivElement | undefined => {
|
|
124
|
-
const visualSelectorId = getElementSelectorId(element);
|
|
125
|
-
|
|
126
|
-
clearSelectedOverlays();
|
|
127
|
-
|
|
128
|
-
const elements = findElementsById(visualSelectorId || null);
|
|
129
|
-
elements.forEach((el) => {
|
|
130
|
-
const overlay = createOverlay(true);
|
|
131
|
-
document.body.appendChild(overlay);
|
|
132
|
-
selectedOverlays.push(overlay);
|
|
133
|
-
positionOverlay(overlay, el, true);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
selectedElementId = visualSelectorId || null;
|
|
137
|
-
clearHoverOverlays();
|
|
138
|
-
notifyElementSelected(element);
|
|
139
|
-
|
|
140
|
-
return selectedOverlays[0];
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const unSelectElement = (): void => {
|
|
144
|
-
selectedElementId = null;
|
|
145
|
-
window.parent.postMessage({ type: "unselect-element" }, "*");
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
// Handle mouse over event
|
|
149
|
-
const handleMouseOver = (e: MouseEvent) => {
|
|
150
|
-
if (!isVisualEditMode || isPopoverDragging) return;
|
|
151
|
-
|
|
152
|
-
const target = e.target as Element;
|
|
153
|
-
|
|
154
|
-
// Prevent hover effects when a dropdown is open
|
|
155
|
-
if (isDropdownOpen) {
|
|
156
|
-
clearHoverOverlays();
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Prevent hover effects on SVG path elements
|
|
161
|
-
if (target.tagName.toLowerCase() === "path") {
|
|
162
|
-
clearHoverOverlays();
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Support both data-source-location and data-visual-selector-id
|
|
167
|
-
const element = target.closest(
|
|
168
|
-
"[data-source-location], [data-visual-selector-id]"
|
|
169
|
-
);
|
|
170
|
-
if (!element) {
|
|
171
|
-
clearHoverOverlays();
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Prefer data-source-location, fallback to data-visual-selector-id
|
|
176
|
-
const htmlElement = element as HTMLElement;
|
|
177
|
-
const selectorId =
|
|
178
|
-
htmlElement.dataset.sourceLocation ||
|
|
179
|
-
htmlElement.dataset.visualSelectorId;
|
|
180
|
-
|
|
181
|
-
// Skip if this element is already selected
|
|
182
|
-
if (selectedElementId === selectorId) {
|
|
183
|
-
clearHoverOverlays();
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Find all elements with the same ID
|
|
188
|
-
const elements = findElementsById(selectorId || null);
|
|
189
|
-
|
|
190
|
-
// Clear previous hover overlays
|
|
191
|
-
clearHoverOverlays();
|
|
192
|
-
|
|
193
|
-
// Create overlays for all matching elements
|
|
194
|
-
elements.forEach((el) => {
|
|
195
|
-
const overlay = createOverlay(false);
|
|
196
|
-
document.body.appendChild(overlay);
|
|
197
|
-
hoverOverlays.push(overlay);
|
|
198
|
-
positionOverlay(overlay, el);
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
currentHighlightedElements = elements;
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
// Handle mouse out event
|
|
205
|
-
const handleMouseOut = () => {
|
|
206
|
-
if (isPopoverDragging) return;
|
|
207
|
-
clearHoverOverlays();
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
// Handle element click
|
|
211
|
-
const handleElementClick = (e: MouseEvent) => {
|
|
212
|
-
if (!isVisualEditMode) return;
|
|
213
|
-
|
|
214
|
-
const target = e.target as Element;
|
|
215
|
-
|
|
216
|
-
// Let layer dropdown clicks pass through without interference
|
|
217
|
-
if (target.closest(`[${LAYER_DROPDOWN_ATTR}]`)) return;
|
|
218
|
-
|
|
219
|
-
// Close dropdowns when clicking anywhere in iframe if a dropdown is open
|
|
220
|
-
if (isDropdownOpen) {
|
|
221
|
-
e.preventDefault();
|
|
222
|
-
e.stopPropagation();
|
|
223
|
-
e.stopImmediatePropagation();
|
|
224
|
-
|
|
225
|
-
window.parent.postMessage({ type: "close-dropdowns" }, "*");
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// Prevent clicking on SVG path elements
|
|
230
|
-
if (target.tagName.toLowerCase() === "path") {
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Prevent default behavior immediately when in visual edit mode
|
|
235
|
-
e.preventDefault();
|
|
236
|
-
e.stopPropagation();
|
|
237
|
-
e.stopImmediatePropagation();
|
|
238
|
-
|
|
239
|
-
// Support both data-source-location and data-visual-selector-id
|
|
240
|
-
const element = target.closest(
|
|
241
|
-
"[data-source-location], [data-visual-selector-id]"
|
|
242
|
-
);
|
|
243
|
-
if (!element) {
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const selectedOverlay = selectElement(element);
|
|
248
|
-
layerController.attachToOverlay(selectedOverlay, element);
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
// Unselect the current element
|
|
252
|
-
const unselectElement = () => {
|
|
253
|
-
clearSelectedOverlays();
|
|
254
|
-
selectedElementId = null;
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
const updateElementClassesAndReposition = (visualSelectorId: string, classes: string) => {
|
|
258
|
-
const elements = findElementsById(visualSelectorId);
|
|
259
|
-
if (elements.length === 0) return;
|
|
260
|
-
|
|
261
|
-
updateElementClasses(elements, classes);
|
|
262
|
-
|
|
263
|
-
// Use a small delay to allow the browser to recalculate layout before repositioning
|
|
264
|
-
setTimeout(() => {
|
|
265
|
-
// Reposition selected overlays
|
|
266
|
-
if (selectedElementId === visualSelectorId) {
|
|
267
|
-
selectedOverlays.forEach((overlay, index) => {
|
|
268
|
-
if (index < elements.length) {
|
|
269
|
-
positionOverlay(overlay, elements[index]!);
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// Reposition hover overlays if needed
|
|
275
|
-
if (currentHighlightedElements.length > 0) {
|
|
276
|
-
const hoveredElement = currentHighlightedElements[0] as HTMLElement;
|
|
277
|
-
const hoveredId = hoveredElement?.dataset?.visualSelectorId;
|
|
278
|
-
if (hoveredId === visualSelectorId) {
|
|
279
|
-
hoverOverlays.forEach((overlay, index) => {
|
|
280
|
-
if (index < currentHighlightedElements.length) {
|
|
281
|
-
positionOverlay(overlay, currentHighlightedElements[index]!);
|
|
282
|
-
}
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}, 50);
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
// Update element content by visual selector ID
|
|
290
|
-
const updateElementContent = (visualSelectorId: string, content: string) => {
|
|
291
|
-
const elements = findElementsById(visualSelectorId);
|
|
292
|
-
|
|
293
|
-
if (elements.length === 0) {
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
elements.forEach((element) => {
|
|
298
|
-
(element as HTMLElement).innerText = content;
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
setTimeout(() => {
|
|
302
|
-
if (selectedElementId === visualSelectorId) {
|
|
303
|
-
selectedOverlays.forEach((overlay, index) => {
|
|
304
|
-
if (index < elements.length) {
|
|
305
|
-
positionOverlay(overlay, elements[index]!);
|
|
306
|
-
}
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
}, 50);
|
|
310
|
-
};
|
|
311
|
-
|
|
312
|
-
// --- Layer dropdown controller ---
|
|
313
|
-
const layerController = createLayerController({
|
|
314
|
-
createPreviewOverlay: (element: Element) => {
|
|
315
|
-
const overlay = createOverlay(false);
|
|
316
|
-
overlay.style.zIndex = "9998";
|
|
317
|
-
document.body.appendChild(overlay);
|
|
318
|
-
positionOverlay(overlay, element);
|
|
319
|
-
return overlay;
|
|
320
|
-
},
|
|
321
|
-
getSelectedElementId: () => selectedElementId,
|
|
322
|
-
selectElement,
|
|
323
|
-
onDeselect: unSelectElement,
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
// Toggle visual edit mode
|
|
327
|
-
const toggleVisualEditMode = (isEnabled: boolean) => {
|
|
328
|
-
isVisualEditMode = isEnabled;
|
|
329
|
-
|
|
330
|
-
if (!isEnabled) {
|
|
331
|
-
layerController.cleanup();
|
|
332
|
-
clearHoverOverlays();
|
|
333
|
-
clearSelectedOverlays();
|
|
334
|
-
|
|
335
|
-
currentHighlightedElements = [];
|
|
336
|
-
selectedElementId = null;
|
|
337
|
-
document.body.style.cursor = "default";
|
|
338
|
-
|
|
339
|
-
document.removeEventListener("mouseover", handleMouseOver);
|
|
340
|
-
document.removeEventListener("mouseout", handleMouseOut);
|
|
341
|
-
document.removeEventListener("click", handleElementClick, true);
|
|
342
|
-
} else {
|
|
343
|
-
document.body.style.cursor = "crosshair";
|
|
344
|
-
document.addEventListener("mouseover", handleMouseOver);
|
|
345
|
-
document.addEventListener("mouseout", handleMouseOut);
|
|
346
|
-
document.addEventListener("click", handleElementClick, true);
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
// Handle scroll events to update popover position
|
|
351
|
-
const handleScroll = () => {
|
|
352
|
-
if (selectedElementId) {
|
|
353
|
-
const elements = findElementsById(selectedElementId);
|
|
354
|
-
if (elements.length > 0) {
|
|
355
|
-
const element = elements[0];
|
|
356
|
-
const rect = element!.getBoundingClientRect();
|
|
357
|
-
|
|
358
|
-
const viewportHeight = window.innerHeight;
|
|
359
|
-
const viewportWidth = window.innerWidth;
|
|
360
|
-
const isInViewport =
|
|
361
|
-
rect.top < viewportHeight &&
|
|
362
|
-
rect.bottom > 0 &&
|
|
363
|
-
rect.left < viewportWidth &&
|
|
364
|
-
rect.right > 0;
|
|
365
|
-
|
|
366
|
-
const elementPosition = {
|
|
367
|
-
top: rect.top,
|
|
368
|
-
left: rect.left,
|
|
369
|
-
right: rect.right,
|
|
370
|
-
bottom: rect.bottom,
|
|
371
|
-
width: rect.width,
|
|
372
|
-
height: rect.height,
|
|
373
|
-
centerX: rect.left + rect.width / 2,
|
|
374
|
-
centerY: rect.top + rect.height / 2,
|
|
375
|
-
};
|
|
376
|
-
|
|
377
|
-
window.parent.postMessage(
|
|
378
|
-
{
|
|
379
|
-
type: "element-position-update",
|
|
380
|
-
position: elementPosition,
|
|
381
|
-
isInViewport: isInViewport,
|
|
382
|
-
visualSelectorId: selectedElementId,
|
|
383
|
-
},
|
|
384
|
-
"*"
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
};
|
|
389
|
-
|
|
390
|
-
// Handle messages from parent window
|
|
391
|
-
const handleMessage = (event: MessageEvent) => {
|
|
392
|
-
const message = event.data;
|
|
393
|
-
|
|
394
|
-
switch (message.type) {
|
|
395
|
-
case "toggle-visual-edit-mode":
|
|
396
|
-
toggleVisualEditMode(message.data.enabled);
|
|
397
|
-
break;
|
|
398
|
-
|
|
399
|
-
case "update-classes":
|
|
400
|
-
if (message.data && message.data.classes !== undefined) {
|
|
401
|
-
updateElementClassesAndReposition(
|
|
402
|
-
message.data.visualSelectorId,
|
|
403
|
-
message.data.classes
|
|
404
|
-
);
|
|
405
|
-
} else {
|
|
406
|
-
console.warn(
|
|
407
|
-
"[VisualEditAgent] Invalid update-classes message:",
|
|
408
|
-
message
|
|
409
|
-
);
|
|
410
|
-
}
|
|
411
|
-
break;
|
|
412
|
-
|
|
413
|
-
case "unselect-element":
|
|
414
|
-
unselectElement();
|
|
415
|
-
break;
|
|
416
|
-
|
|
417
|
-
case "refresh-page":
|
|
418
|
-
window.location.reload();
|
|
419
|
-
break;
|
|
420
|
-
|
|
421
|
-
case "update-content":
|
|
422
|
-
if (message.data && message.data.content !== undefined) {
|
|
423
|
-
updateElementContent(
|
|
424
|
-
message.data.visualSelectorId,
|
|
425
|
-
message.data.content
|
|
426
|
-
);
|
|
427
|
-
} else {
|
|
428
|
-
console.warn(
|
|
429
|
-
"[VisualEditAgent] Invalid update-content message:",
|
|
430
|
-
message
|
|
431
|
-
);
|
|
432
|
-
}
|
|
433
|
-
break;
|
|
434
|
-
|
|
435
|
-
case "request-element-position":
|
|
436
|
-
if (selectedElementId) {
|
|
437
|
-
const elements = findElementsById(selectedElementId);
|
|
438
|
-
if (elements.length > 0) {
|
|
439
|
-
const element = elements[0];
|
|
440
|
-
const rect = element!.getBoundingClientRect();
|
|
441
|
-
|
|
442
|
-
const viewportHeight = window.innerHeight;
|
|
443
|
-
const viewportWidth = window.innerWidth;
|
|
444
|
-
const isInViewport =
|
|
445
|
-
rect.top < viewportHeight &&
|
|
446
|
-
rect.bottom > 0 &&
|
|
447
|
-
rect.left < viewportWidth &&
|
|
448
|
-
rect.right > 0;
|
|
449
|
-
|
|
450
|
-
const elementPosition = {
|
|
451
|
-
top: rect.top,
|
|
452
|
-
left: rect.left,
|
|
453
|
-
right: rect.right,
|
|
454
|
-
bottom: rect.bottom,
|
|
455
|
-
width: rect.width,
|
|
456
|
-
height: rect.height,
|
|
457
|
-
centerX: rect.left + rect.width / 2,
|
|
458
|
-
centerY: rect.top + rect.height / 2,
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
window.parent.postMessage(
|
|
462
|
-
{
|
|
463
|
-
type: "element-position-update",
|
|
464
|
-
position: elementPosition,
|
|
465
|
-
isInViewport: isInViewport,
|
|
466
|
-
visualSelectorId: selectedElementId,
|
|
467
|
-
},
|
|
468
|
-
"*"
|
|
469
|
-
);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
break;
|
|
473
|
-
|
|
474
|
-
case "popover-drag-state":
|
|
475
|
-
if (message.data && message.data.isDragging !== undefined) {
|
|
476
|
-
isPopoverDragging = message.data.isDragging;
|
|
477
|
-
if (message.data.isDragging) {
|
|
478
|
-
clearHoverOverlays();
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
break;
|
|
482
|
-
|
|
483
|
-
case "dropdown-state":
|
|
484
|
-
if (message.data && message.data.isOpen !== undefined) {
|
|
485
|
-
isDropdownOpen = message.data.isOpen;
|
|
486
|
-
if (message.data.isOpen) {
|
|
487
|
-
clearHoverOverlays();
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
break;
|
|
491
|
-
|
|
492
|
-
default:
|
|
493
|
-
break;
|
|
494
|
-
}
|
|
495
|
-
};
|
|
496
|
-
|
|
497
|
-
// Handle window resize to reposition overlays
|
|
498
|
-
const handleResize = () => {
|
|
499
|
-
if (selectedElementId) {
|
|
500
|
-
const elements = findElementsById(selectedElementId);
|
|
501
|
-
selectedOverlays.forEach((overlay, index) => {
|
|
502
|
-
if (index < elements.length) {
|
|
503
|
-
positionOverlay(overlay, elements[index]!);
|
|
504
|
-
}
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
if (currentHighlightedElements.length > 0) {
|
|
509
|
-
hoverOverlays.forEach((overlay, index) => {
|
|
510
|
-
if (index < currentHighlightedElements.length) {
|
|
511
|
-
positionOverlay(overlay, currentHighlightedElements[index]!);
|
|
512
|
-
}
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
};
|
|
516
|
-
|
|
517
|
-
// Initialize: Add IDs to elements that don't have them but have linenumbers
|
|
518
|
-
const elementsWithLineNumber = document.querySelectorAll(
|
|
519
|
-
"[data-linenumber]:not([data-visual-selector-id])"
|
|
520
|
-
);
|
|
521
|
-
elementsWithLineNumber.forEach((el, index) => {
|
|
522
|
-
const htmlEl = el as HTMLElement;
|
|
523
|
-
const id = `visual-id-${htmlEl.dataset.filename}-${htmlEl.dataset.linenumber}-${index}`;
|
|
524
|
-
htmlEl.dataset.visualSelectorId = id;
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
// Create mutation observer to detect layout changes
|
|
528
|
-
const mutationObserver = new MutationObserver((mutations) => {
|
|
529
|
-
const needsUpdate = mutations.some((mutation) => {
|
|
530
|
-
const hasVisualId = (node: Node): boolean => {
|
|
531
|
-
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
532
|
-
const el = node as HTMLElement;
|
|
533
|
-
if (el.dataset && el.dataset.visualSelectorId) {
|
|
534
|
-
return true;
|
|
535
|
-
}
|
|
536
|
-
for (let i = 0; i < el.children.length; i++) {
|
|
537
|
-
if (hasVisualId(el.children[i]!)) {
|
|
538
|
-
return true;
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
return false;
|
|
543
|
-
};
|
|
544
|
-
|
|
545
|
-
const isLayoutChange =
|
|
546
|
-
mutation.type === "attributes" &&
|
|
547
|
-
(mutation.attributeName === "style" ||
|
|
548
|
-
mutation.attributeName === "class" ||
|
|
549
|
-
mutation.attributeName === "width" ||
|
|
550
|
-
mutation.attributeName === "height");
|
|
551
|
-
|
|
552
|
-
return isLayoutChange && hasVisualId(mutation.target);
|
|
553
|
-
});
|
|
554
|
-
|
|
555
|
-
if (needsUpdate) {
|
|
556
|
-
setTimeout(handleResize, 50);
|
|
557
|
-
}
|
|
558
|
-
});
|
|
559
|
-
|
|
560
|
-
// Set up event listeners
|
|
561
|
-
window.addEventListener("message", handleMessage);
|
|
562
|
-
window.addEventListener("scroll", handleScroll, true);
|
|
563
|
-
document.addEventListener("scroll", handleScroll, true);
|
|
564
|
-
window.addEventListener("resize", handleResize);
|
|
565
|
-
window.addEventListener("scroll", handleResize);
|
|
566
|
-
|
|
567
|
-
// Start observing DOM mutations
|
|
568
|
-
mutationObserver.observe(document.body, {
|
|
569
|
-
attributes: true,
|
|
570
|
-
childList: true,
|
|
571
|
-
subtree: true,
|
|
572
|
-
attributeFilter: ["style", "class", "width", "height"],
|
|
573
|
-
});
|
|
574
|
-
|
|
575
|
-
// Send ready message to parent
|
|
576
|
-
window.parent.postMessage({ type: "visual-edit-agent-ready" }, "*");
|
|
577
|
-
}
|
|
1
|
+
export { setupVisualEditAgent } from "./visual-edit-agent/index.js";
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/** Style constants for the layer dropdown UI */
|
|
2
|
-
export declare const DROPDOWN_CONTAINER_STYLES: Record<string, string>;
|
|
3
|
-
export declare const DROPDOWN_ITEM_BASE_STYLES: Record<string, string>;
|
|
4
|
-
export declare const DROPDOWN_ITEM_ACTIVE_COLOR = "#526cff";
|
|
5
|
-
export declare const DROPDOWN_ITEM_ACTIVE_BG = "#DBEAFE";
|
|
6
|
-
export declare const DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT = "600";
|
|
7
|
-
export declare const DROPDOWN_ITEM_HOVER_BG = "#f1f5f9";
|
|
8
|
-
export declare const DEPTH_INDENT_PX = 10;
|
|
9
|
-
export declare const LABEL_CHEVRON = " \u25BE";
|
|
10
|
-
export declare const LAYER_DROPDOWN_ATTR = "data-layer-dropdown";
|
|
11
|
-
/** Max instrumented ancestors to show above the selected element */
|
|
12
|
-
export declare const MAX_PARENT_DEPTH = 2;
|
|
13
|
-
/** Max instrumented depth levels to show below the selected element */
|
|
14
|
-
export declare const MAX_CHILD_DEPTH = 2;
|
|
15
|
-
//# sourceMappingURL=consts.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../../../src/injections/layer-dropdown/consts.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAEhD,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAa5D,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQ5D,CAAC;AAEF,eAAO,MAAM,0BAA0B,YAAY,CAAC;AACpD,eAAO,MAAM,uBAAuB,YAAY,CAAC;AACjD,eAAO,MAAM,gCAAgC,QAAQ,CAAC;AAEtD,eAAO,MAAM,sBAAsB,YAAY,CAAC;AAEhD,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC,eAAO,MAAM,aAAa,YAAY,CAAC;AAEvC,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAEzD,oEAAoE;AACpE,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,uEAAuE;AACvE,eAAO,MAAM,eAAe,IAAI,CAAC"}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/** Style constants for the layer dropdown UI */
|
|
2
|
-
export const DROPDOWN_CONTAINER_STYLES = {
|
|
3
|
-
position: "absolute",
|
|
4
|
-
backgroundColor: "#ffffff",
|
|
5
|
-
border: "1px solid #e2e8f0",
|
|
6
|
-
borderRadius: "6px",
|
|
7
|
-
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
8
|
-
fontSize: "12px",
|
|
9
|
-
minWidth: "120px",
|
|
10
|
-
maxHeight: "200px",
|
|
11
|
-
overflowY: "auto",
|
|
12
|
-
zIndex: "10001",
|
|
13
|
-
padding: "4px 0",
|
|
14
|
-
pointerEvents: "auto",
|
|
15
|
-
};
|
|
16
|
-
export const DROPDOWN_ITEM_BASE_STYLES = {
|
|
17
|
-
padding: "4px 12px",
|
|
18
|
-
cursor: "pointer",
|
|
19
|
-
color: "#334155",
|
|
20
|
-
backgroundColor: "transparent",
|
|
21
|
-
whiteSpace: "nowrap",
|
|
22
|
-
lineHeight: "1.5",
|
|
23
|
-
fontWeight: "400",
|
|
24
|
-
};
|
|
25
|
-
export const DROPDOWN_ITEM_ACTIVE_COLOR = "#526cff";
|
|
26
|
-
export const DROPDOWN_ITEM_ACTIVE_BG = "#DBEAFE";
|
|
27
|
-
export const DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT = "600";
|
|
28
|
-
export const DROPDOWN_ITEM_HOVER_BG = "#f1f5f9";
|
|
29
|
-
export const DEPTH_INDENT_PX = 10;
|
|
30
|
-
export const LABEL_CHEVRON = " \u25BE";
|
|
31
|
-
export const LAYER_DROPDOWN_ATTR = "data-layer-dropdown";
|
|
32
|
-
/** Max instrumented ancestors to show above the selected element */
|
|
33
|
-
export const MAX_PARENT_DEPTH = 2;
|
|
34
|
-
/** Max instrumented depth levels to show below the selected element */
|
|
35
|
-
export const MAX_CHILD_DEPTH = 2;
|
|
36
|
-
//# sourceMappingURL=consts.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"consts.js","sourceRoot":"","sources":["../../../src/injections/layer-dropdown/consts.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAEhD,MAAM,CAAC,MAAM,yBAAyB,GAA2B;IAC/D,QAAQ,EAAE,UAAU;IACpB,eAAe,EAAE,SAAS;IAC1B,MAAM,EAAE,mBAAmB;IAC3B,YAAY,EAAE,KAAK;IACnB,SAAS,EAAE,gCAAgC;IAC3C,QAAQ,EAAE,MAAM;IAChB,QAAQ,EAAE,OAAO;IACjB,SAAS,EAAE,OAAO;IAClB,SAAS,EAAE,MAAM;IACjB,MAAM,EAAE,OAAO;IACf,OAAO,EAAE,OAAO;IAChB,aAAa,EAAE,MAAM;CACtB,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAA2B;IAC/D,OAAO,EAAE,UAAU;IACnB,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,SAAS;IAChB,eAAe,EAAE,aAAa;IAC9B,UAAU,EAAE,QAAQ;IACpB,UAAU,EAAE,KAAK;IACjB,UAAU,EAAE,KAAK;CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG,SAAS,CAAC;AACpD,MAAM,CAAC,MAAM,uBAAuB,GAAG,SAAS,CAAC;AACjD,MAAM,CAAC,MAAM,gCAAgC,GAAG,KAAK,CAAC;AAEtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,SAAS,CAAC;AAEhD,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAElC,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,CAAC;AAEvC,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAEzD,oEAAoE;AACpE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,uEAAuE;AACvE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC"}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
/** Controller that encapsulates layer-dropdown integration logic */
|
|
2
|
-
import type { LayerControllerDeps, LayerController } from "./types.js";
|
|
3
|
-
export declare function createLayerController(deps: LayerControllerDeps): LayerController;
|
|
4
|
-
//# sourceMappingURL=controller.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../src/injections/layer-dropdown/controller.ts"],"names":[],"mappings":"AAAA,oEAAoE;AAUpE,OAAO,KAAK,EAAa,mBAAmB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,GAAG,eAAe,CA4FhF"}
|