@base44-preview/vite-plugin 0.2.24-pr.29.5743fec → 0.2.24-pr.36.31362a5
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/layer-dropdown/consts.d.ts +19 -0
- package/dist/injections/layer-dropdown/consts.d.ts.map +1 -0
- package/dist/injections/layer-dropdown/consts.js +40 -0
- package/dist/injections/layer-dropdown/consts.js.map +1 -0
- package/dist/injections/layer-dropdown/controller.d.ts +4 -0
- package/dist/injections/layer-dropdown/controller.d.ts.map +1 -0
- package/dist/injections/layer-dropdown/controller.js +88 -0
- package/dist/injections/layer-dropdown/controller.js.map +1 -0
- package/dist/injections/layer-dropdown/dropdown-ui.d.ts +13 -0
- package/dist/injections/layer-dropdown/dropdown-ui.d.ts.map +1 -0
- package/dist/injections/layer-dropdown/dropdown-ui.js +172 -0
- package/dist/injections/layer-dropdown/dropdown-ui.js.map +1 -0
- package/dist/injections/layer-dropdown/types.d.ts +26 -0
- package/dist/injections/layer-dropdown/types.d.ts.map +1 -0
- package/dist/injections/layer-dropdown/types.js +3 -0
- package/dist/injections/layer-dropdown/types.js.map +1 -0
- package/dist/injections/layer-dropdown/utils.d.ts +25 -0
- package/dist/injections/layer-dropdown/utils.d.ts.map +1 -0
- package/dist/injections/layer-dropdown/utils.js +131 -0
- package/dist/injections/layer-dropdown/utils.js.map +1 -0
- package/dist/injections/utils.d.ts +4 -5
- package/dist/injections/utils.d.ts.map +1 -1
- package/dist/injections/utils.js +12 -21
- package/dist/injections/utils.js.map +1 -1
- package/dist/injections/visual-edit-agent.d.ts.map +1 -1
- package/dist/injections/visual-edit-agent.js +86 -100
- package/dist/injections/visual-edit-agent.js.map +1 -1
- package/dist/statics/index.mjs +1 -1
- package/dist/statics/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/injections/layer-dropdown/LAYERS.md +258 -0
- package/src/injections/layer-dropdown/consts.ts +49 -0
- package/src/injections/layer-dropdown/controller.ts +109 -0
- package/src/injections/layer-dropdown/dropdown-ui.ts +228 -0
- package/src/injections/layer-dropdown/types.ts +30 -0
- package/src/injections/layer-dropdown/utils.ts +162 -0
- package/src/injections/utils.ts +18 -25
- package/src/injections/visual-edit-agent.ts +97 -126
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { findElementsById, updateElementClasses,
|
|
1
|
+
import { findElementsById, updateElementClasses, getElementSelectorId } from "./utils.js";
|
|
2
|
+
import { createLayerController } from "./layer-dropdown/controller.js";
|
|
3
|
+
import { LAYER_DROPDOWN_ATTR } from "./layer-dropdown/consts.js";
|
|
2
4
|
|
|
3
5
|
export function setupVisualEditAgent() {
|
|
4
6
|
// State variables (replacing React useState/useRef)
|
|
@@ -78,6 +80,75 @@ export function setupVisualEditAgent() {
|
|
|
78
80
|
currentHighlightedElements = [];
|
|
79
81
|
};
|
|
80
82
|
|
|
83
|
+
const clearSelectedOverlays = () => {
|
|
84
|
+
selectedOverlays.forEach((overlay) => {
|
|
85
|
+
if (overlay && overlay.parentNode) {
|
|
86
|
+
overlay.remove();
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
selectedOverlays = [];
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const TEXT_TAGS = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'a', 'label'];
|
|
93
|
+
|
|
94
|
+
const notifyElementSelected = (element: Element) => {
|
|
95
|
+
const htmlElement = element as HTMLElement;
|
|
96
|
+
const rect = element.getBoundingClientRect();
|
|
97
|
+
const svgElement = element as SVGElement;
|
|
98
|
+
const isTextElement = TEXT_TAGS.includes(element.tagName?.toLowerCase());
|
|
99
|
+
window.parent.postMessage({
|
|
100
|
+
type: "element-selected",
|
|
101
|
+
tagName: element.tagName,
|
|
102
|
+
classes:
|
|
103
|
+
(svgElement.className as unknown as SVGAnimatedString)?.baseVal ||
|
|
104
|
+
element.className ||
|
|
105
|
+
"",
|
|
106
|
+
visualSelectorId: getElementSelectorId(element),
|
|
107
|
+
content: isTextElement ? htmlElement.innerText : undefined,
|
|
108
|
+
dataSourceLocation: htmlElement.dataset.sourceLocation,
|
|
109
|
+
isDynamicContent: htmlElement.dataset.dynamicContent === "true",
|
|
110
|
+
linenumber: htmlElement.dataset.linenumber,
|
|
111
|
+
filename: htmlElement.dataset.filename,
|
|
112
|
+
position: {
|
|
113
|
+
top: rect.top,
|
|
114
|
+
left: rect.left,
|
|
115
|
+
right: rect.right,
|
|
116
|
+
bottom: rect.bottom,
|
|
117
|
+
width: rect.width,
|
|
118
|
+
height: rect.height,
|
|
119
|
+
centerX: rect.left + rect.width / 2,
|
|
120
|
+
centerY: rect.top + rect.height / 2,
|
|
121
|
+
},
|
|
122
|
+
isTextElement,
|
|
123
|
+
}, "*");
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// Select an element: create overlays, update state, notify parent
|
|
127
|
+
const selectElement = (element: Element): HTMLDivElement | undefined => {
|
|
128
|
+
const visualSelectorId = getElementSelectorId(element);
|
|
129
|
+
|
|
130
|
+
clearSelectedOverlays();
|
|
131
|
+
|
|
132
|
+
const elements = findElementsById(visualSelectorId || null);
|
|
133
|
+
elements.forEach((el) => {
|
|
134
|
+
const overlay = createOverlay(true);
|
|
135
|
+
document.body.appendChild(overlay);
|
|
136
|
+
selectedOverlays.push(overlay);
|
|
137
|
+
positionOverlay(overlay, el, true);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
selectedElementId = visualSelectorId || null;
|
|
141
|
+
clearHoverOverlays();
|
|
142
|
+
notifyElementSelected(element);
|
|
143
|
+
|
|
144
|
+
return selectedOverlays[0];
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const notifyDeselection = (): void => {
|
|
148
|
+
selectedElementId = null;
|
|
149
|
+
window.parent.postMessage({ type: "unselect-element" }, "*");
|
|
150
|
+
};
|
|
151
|
+
|
|
81
152
|
// Handle mouse over event
|
|
82
153
|
const handleMouseOver = (e: MouseEvent) => {
|
|
83
154
|
if (!isVisualEditMode || isPopoverDragging) return;
|
|
@@ -146,6 +217,9 @@ export function setupVisualEditAgent() {
|
|
|
146
217
|
|
|
147
218
|
const target = e.target as Element;
|
|
148
219
|
|
|
220
|
+
// Let layer dropdown clicks pass through without interference
|
|
221
|
+
if (target.closest(`[${LAYER_DROPDOWN_ATTR}]`)) return;
|
|
222
|
+
|
|
149
223
|
// Close dropdowns when clicking anywhere in iframe if a dropdown is open
|
|
150
224
|
if (isDropdownOpen) {
|
|
151
225
|
e.preventDefault();
|
|
@@ -174,82 +248,13 @@ export function setupVisualEditAgent() {
|
|
|
174
248
|
return;
|
|
175
249
|
}
|
|
176
250
|
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
htmlElement.dataset.sourceLocation ||
|
|
180
|
-
htmlElement.dataset.visualSelectorId;
|
|
181
|
-
|
|
182
|
-
// Clear any existing selected overlays
|
|
183
|
-
selectedOverlays.forEach((overlay) => {
|
|
184
|
-
if (overlay && overlay.parentNode) {
|
|
185
|
-
overlay.remove();
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
selectedOverlays = [];
|
|
189
|
-
|
|
190
|
-
// Find all elements with the same ID
|
|
191
|
-
const elements = findElementsById(visualSelectorId || null);
|
|
192
|
-
|
|
193
|
-
// Create selected overlays for all matching elements
|
|
194
|
-
elements.forEach((el) => {
|
|
195
|
-
const overlay = createOverlay(true);
|
|
196
|
-
document.body.appendChild(overlay);
|
|
197
|
-
selectedOverlays.push(overlay);
|
|
198
|
-
positionOverlay(overlay, el, true);
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
selectedElementId = visualSelectorId || null;
|
|
202
|
-
|
|
203
|
-
// Clear hover overlays
|
|
204
|
-
clearHoverOverlays();
|
|
205
|
-
|
|
206
|
-
// Calculate element position for popover positioning
|
|
207
|
-
const rect = element.getBoundingClientRect();
|
|
208
|
-
const elementPosition = {
|
|
209
|
-
top: rect.top,
|
|
210
|
-
left: rect.left,
|
|
211
|
-
right: rect.right,
|
|
212
|
-
bottom: rect.bottom,
|
|
213
|
-
width: rect.width,
|
|
214
|
-
height: rect.height,
|
|
215
|
-
centerX: rect.left + rect.width / 2,
|
|
216
|
-
centerY: rect.top + rect.height / 2,
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
// Collect allowed element attributes
|
|
220
|
-
const attributes = collectAllowedAttributes(element, ALLOWED_ATTRIBUTES);
|
|
221
|
-
const isTextElement = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'a', 'label'].includes(element.tagName?.toLowerCase());
|
|
222
|
-
|
|
223
|
-
// Send message to parent window with element info including position
|
|
224
|
-
const svgElement = element as SVGElement;
|
|
225
|
-
const elementData = {
|
|
226
|
-
type: "element-selected",
|
|
227
|
-
tagName: element.tagName,
|
|
228
|
-
classes:
|
|
229
|
-
(svgElement.className as unknown as SVGAnimatedString)?.baseVal ||
|
|
230
|
-
element.className ||
|
|
231
|
-
"",
|
|
232
|
-
visualSelectorId: visualSelectorId,
|
|
233
|
-
content: isTextElement ? (element as HTMLElement).innerText : undefined,
|
|
234
|
-
dataSourceLocation: htmlElement.dataset.sourceLocation,
|
|
235
|
-
isDynamicContent: htmlElement.dataset.dynamicContent === "true",
|
|
236
|
-
linenumber: htmlElement.dataset.linenumber,
|
|
237
|
-
filename: htmlElement.dataset.filename,
|
|
238
|
-
position: elementPosition,
|
|
239
|
-
attributes,
|
|
240
|
-
isTextElement: isTextElement,
|
|
241
|
-
};
|
|
242
|
-
window.parent.postMessage(elementData, "*");
|
|
251
|
+
const selectedOverlay = selectElement(element);
|
|
252
|
+
layerController.attachToOverlay(selectedOverlay, element);
|
|
243
253
|
};
|
|
244
254
|
|
|
245
|
-
//
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
if (overlay && overlay.parentNode) {
|
|
249
|
-
overlay.remove();
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
selectedOverlays = [];
|
|
255
|
+
// Clear the current selection
|
|
256
|
+
const clearSelection = () => {
|
|
257
|
+
clearSelectedOverlays();
|
|
253
258
|
selectedElementId = null;
|
|
254
259
|
};
|
|
255
260
|
|
|
@@ -285,29 +290,6 @@ export function setupVisualEditAgent() {
|
|
|
285
290
|
}, 50);
|
|
286
291
|
};
|
|
287
292
|
|
|
288
|
-
// Update element attribute by visual selector ID
|
|
289
|
-
const updateElementAttributeAndReposition = (
|
|
290
|
-
visualSelectorId: string,
|
|
291
|
-
attribute: string,
|
|
292
|
-
value: string
|
|
293
|
-
) => {
|
|
294
|
-
const elements = findElementsById(visualSelectorId);
|
|
295
|
-
if (elements.length === 0) return;
|
|
296
|
-
|
|
297
|
-
updateElementAttribute(elements, attribute, value);
|
|
298
|
-
|
|
299
|
-
// Reposition overlays after attribute change (e.g. image src swap can affect layout)
|
|
300
|
-
setTimeout(() => {
|
|
301
|
-
if (selectedElementId === visualSelectorId) {
|
|
302
|
-
selectedOverlays.forEach((overlay, index) => {
|
|
303
|
-
if (index < elements.length) {
|
|
304
|
-
positionOverlay(overlay, elements[index]!);
|
|
305
|
-
}
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
}, 50);
|
|
309
|
-
};
|
|
310
|
-
|
|
311
293
|
// Update element content by visual selector ID
|
|
312
294
|
const updateElementContent = (visualSelectorId: string, content: string) => {
|
|
313
295
|
const elements = findElementsById(visualSelectorId);
|
|
@@ -331,19 +313,28 @@ export function setupVisualEditAgent() {
|
|
|
331
313
|
}, 50);
|
|
332
314
|
};
|
|
333
315
|
|
|
316
|
+
// --- Layer dropdown controller ---
|
|
317
|
+
const layerController = createLayerController({
|
|
318
|
+
createPreviewOverlay: (element: Element) => {
|
|
319
|
+
const overlay = createOverlay(false);
|
|
320
|
+
overlay.style.zIndex = "9998";
|
|
321
|
+
document.body.appendChild(overlay);
|
|
322
|
+
positionOverlay(overlay, element);
|
|
323
|
+
return overlay;
|
|
324
|
+
},
|
|
325
|
+
getSelectedElementId: () => selectedElementId,
|
|
326
|
+
selectElement,
|
|
327
|
+
onDeselect: notifyDeselection,
|
|
328
|
+
});
|
|
329
|
+
|
|
334
330
|
// Toggle visual edit mode
|
|
335
331
|
const toggleVisualEditMode = (isEnabled: boolean) => {
|
|
336
332
|
isVisualEditMode = isEnabled;
|
|
337
333
|
|
|
338
334
|
if (!isEnabled) {
|
|
335
|
+
layerController.cleanup();
|
|
339
336
|
clearHoverOverlays();
|
|
340
|
-
|
|
341
|
-
selectedOverlays.forEach((overlay) => {
|
|
342
|
-
if (overlay && overlay.parentNode) {
|
|
343
|
-
overlay.remove();
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
selectedOverlays = [];
|
|
337
|
+
clearSelectedOverlays();
|
|
347
338
|
|
|
348
339
|
currentHighlightedElements = [];
|
|
349
340
|
selectedElementId = null;
|
|
@@ -423,28 +414,8 @@ export function setupVisualEditAgent() {
|
|
|
423
414
|
}
|
|
424
415
|
break;
|
|
425
416
|
|
|
426
|
-
case "update-attribute":
|
|
427
|
-
if (
|
|
428
|
-
message.data &&
|
|
429
|
-
message.data.visualSelectorId &&
|
|
430
|
-
message.data.attribute !== undefined &&
|
|
431
|
-
message.data.value !== undefined
|
|
432
|
-
) {
|
|
433
|
-
updateElementAttributeAndReposition(
|
|
434
|
-
message.data.visualSelectorId,
|
|
435
|
-
message.data.attribute,
|
|
436
|
-
message.data.value
|
|
437
|
-
);
|
|
438
|
-
} else {
|
|
439
|
-
console.warn(
|
|
440
|
-
"[VisualEditAgent] Invalid update-attribute message:",
|
|
441
|
-
message
|
|
442
|
-
);
|
|
443
|
-
}
|
|
444
|
-
break;
|
|
445
|
-
|
|
446
417
|
case "unselect-element":
|
|
447
|
-
|
|
418
|
+
clearSelection();
|
|
448
419
|
break;
|
|
449
420
|
|
|
450
421
|
case "refresh-page":
|