@base44-preview/vite-plugin 0.2.22-pr.36.d652cb1 → 0.2.22-pr.37.26664a5

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.
Files changed (120) hide show
  1. package/dist/injections/utils.d.ts +0 -6
  2. package/dist/injections/utils.d.ts.map +1 -1
  3. package/dist/injections/utils.js +0 -25
  4. package/dist/injections/utils.js.map +1 -1
  5. package/dist/injections/visual-edit-agent/capabilities/inline-editing/core.d.ts +25 -0
  6. package/dist/injections/visual-edit-agent/capabilities/inline-editing/core.d.ts.map +1 -0
  7. package/dist/injections/visual-edit-agent/capabilities/inline-editing/core.js +95 -0
  8. package/dist/injections/visual-edit-agent/capabilities/inline-editing/core.js.map +1 -0
  9. package/dist/injections/visual-edit-agent/capabilities/inline-editing/index.d.ts +4 -0
  10. package/dist/injections/visual-edit-agent/capabilities/inline-editing/index.d.ts.map +1 -0
  11. package/dist/injections/visual-edit-agent/capabilities/inline-editing/index.js +4 -0
  12. package/dist/injections/visual-edit-agent/capabilities/inline-editing/index.js.map +1 -0
  13. package/dist/injections/visual-edit-agent/capabilities/inline-editing/styles.d.ts +9 -0
  14. package/dist/injections/visual-edit-agent/capabilities/inline-editing/styles.d.ts.map +1 -0
  15. package/dist/injections/visual-edit-agent/capabilities/inline-editing/styles.js +26 -0
  16. package/dist/injections/visual-edit-agent/capabilities/inline-editing/styles.js.map +1 -0
  17. package/dist/injections/visual-edit-agent/capabilities/inline-editing/validation.d.ts +10 -0
  18. package/dist/injections/visual-edit-agent/capabilities/inline-editing/validation.d.ts.map +1 -0
  19. package/dist/injections/visual-edit-agent/capabilities/inline-editing/validation.js +60 -0
  20. package/dist/injections/visual-edit-agent/capabilities/inline-editing/validation.js.map +1 -0
  21. package/dist/injections/visual-edit-agent/constants.d.ts +10 -0
  22. package/dist/injections/visual-edit-agent/constants.d.ts.map +1 -0
  23. package/dist/injections/visual-edit-agent/constants.js +10 -0
  24. package/dist/injections/visual-edit-agent/constants.js.map +1 -0
  25. package/dist/injections/visual-edit-agent/handlers/click-handlers.d.ts +10 -0
  26. package/dist/injections/visual-edit-agent/handlers/click-handlers.d.ts.map +1 -0
  27. package/dist/injections/visual-edit-agent/handlers/click-handlers.js +107 -0
  28. package/dist/injections/visual-edit-agent/handlers/click-handlers.js.map +1 -0
  29. package/dist/injections/visual-edit-agent/handlers/hover-handlers.d.ts +14 -0
  30. package/dist/injections/visual-edit-agent/handlers/hover-handlers.d.ts.map +1 -0
  31. package/dist/injections/visual-edit-agent/handlers/hover-handlers.js +64 -0
  32. package/dist/injections/visual-edit-agent/handlers/hover-handlers.js.map +1 -0
  33. package/dist/injections/visual-edit-agent/handlers/inline-edit-handlers.d.ts +14 -0
  34. package/dist/injections/visual-edit-agent/handlers/inline-edit-handlers.d.ts.map +1 -0
  35. package/dist/injections/visual-edit-agent/handlers/inline-edit-handlers.js +109 -0
  36. package/dist/injections/visual-edit-agent/handlers/inline-edit-handlers.js.map +1 -0
  37. package/dist/injections/visual-edit-agent/handlers/message-handlers.d.ts +26 -0
  38. package/dist/injections/visual-edit-agent/handlers/message-handlers.d.ts.map +1 -0
  39. package/dist/injections/visual-edit-agent/handlers/message-handlers.js +145 -0
  40. package/dist/injections/visual-edit-agent/handlers/message-handlers.js.map +1 -0
  41. package/dist/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.d.ts +7 -0
  42. package/dist/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.d.ts.map +1 -0
  43. package/dist/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.js +58 -0
  44. package/dist/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.js.map +1 -0
  45. package/dist/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.d.ts +11 -0
  46. package/dist/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.d.ts.map +1 -0
  47. package/dist/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.js +32 -0
  48. package/dist/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.js.map +1 -0
  49. package/dist/injections/visual-edit-agent/handlers/messages/types.d.ts +86 -0
  50. package/dist/injections/visual-edit-agent/handlers/messages/types.d.ts.map +1 -0
  51. package/dist/injections/visual-edit-agent/handlers/messages/types.js +28 -0
  52. package/dist/injections/visual-edit-agent/handlers/messages/types.js.map +1 -0
  53. package/dist/injections/visual-edit-agent/index.d.ts +5 -0
  54. package/dist/injections/visual-edit-agent/index.d.ts.map +1 -0
  55. package/dist/injections/visual-edit-agent/index.js +106 -0
  56. package/dist/injections/visual-edit-agent/index.js.map +1 -0
  57. package/dist/injections/visual-edit-agent/state/agent-state.d.ts +17 -0
  58. package/dist/injections/visual-edit-agent/state/agent-state.d.ts.map +1 -0
  59. package/dist/injections/visual-edit-agent/state/agent-state.js +18 -0
  60. package/dist/injections/visual-edit-agent/state/agent-state.js.map +1 -0
  61. package/dist/injections/visual-edit-agent/ui/overlay.d.ts +26 -0
  62. package/dist/injections/visual-edit-agent/ui/overlay.d.ts.map +1 -0
  63. package/dist/injections/visual-edit-agent/ui/overlay.js +102 -0
  64. package/dist/injections/visual-edit-agent/ui/overlay.js.map +1 -0
  65. package/dist/injections/visual-edit-agent/utils/dom-utils.d.ts +14 -0
  66. package/dist/injections/visual-edit-agent/utils/dom-utils.d.ts.map +1 -0
  67. package/dist/injections/visual-edit-agent/utils/dom-utils.js +34 -0
  68. package/dist/injections/visual-edit-agent/utils/dom-utils.js.map +1 -0
  69. package/dist/injections/visual-edit-agent.d.ts +1 -1
  70. package/dist/injections/visual-edit-agent.d.ts.map +1 -1
  71. package/dist/injections/visual-edit-agent.js +1 -474
  72. package/dist/injections/visual-edit-agent.js.map +1 -1
  73. package/dist/statics/index.mjs +5 -1
  74. package/dist/statics/index.mjs.map +1 -1
  75. package/package.json +1 -1
  76. package/src/injections/utils.ts +0 -34
  77. package/src/injections/visual-edit-agent/README.md +222 -0
  78. package/src/injections/visual-edit-agent/capabilities/inline-editing/core.ts +120 -0
  79. package/src/injections/visual-edit-agent/capabilities/inline-editing/index.ts +10 -0
  80. package/src/injections/visual-edit-agent/capabilities/inline-editing/styles.ts +26 -0
  81. package/src/injections/visual-edit-agent/capabilities/inline-editing/validation.ts +67 -0
  82. package/src/injections/visual-edit-agent/constants.ts +9 -0
  83. package/src/injections/visual-edit-agent/handlers/click-handlers.ts +134 -0
  84. package/src/injections/visual-edit-agent/handlers/hover-handlers.ts +78 -0
  85. package/src/injections/visual-edit-agent/handlers/inline-edit-handlers.ts +141 -0
  86. package/src/injections/visual-edit-agent/handlers/message-handlers.ts +191 -0
  87. package/src/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.ts +70 -0
  88. package/src/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.ts +40 -0
  89. package/src/injections/visual-edit-agent/handlers/messages/types.ts +112 -0
  90. package/src/injections/visual-edit-agent/index.ts +120 -0
  91. package/src/injections/visual-edit-agent/state/agent-state.ts +31 -0
  92. package/src/injections/visual-edit-agent/ui/overlay.ts +123 -0
  93. package/src/injections/visual-edit-agent/utils/dom-utils.ts +39 -0
  94. package/src/injections/visual-edit-agent.ts +1 -577
  95. package/dist/injections/layer-dropdown/consts.d.ts +0 -15
  96. package/dist/injections/layer-dropdown/consts.d.ts.map +0 -1
  97. package/dist/injections/layer-dropdown/consts.js +0 -36
  98. package/dist/injections/layer-dropdown/consts.js.map +0 -1
  99. package/dist/injections/layer-dropdown/controller.d.ts +0 -4
  100. package/dist/injections/layer-dropdown/controller.d.ts.map +0 -1
  101. package/dist/injections/layer-dropdown/controller.js +0 -85
  102. package/dist/injections/layer-dropdown/controller.js.map +0 -1
  103. package/dist/injections/layer-dropdown/dropdown-ui.d.ts +0 -13
  104. package/dist/injections/layer-dropdown/dropdown-ui.d.ts.map +0 -1
  105. package/dist/injections/layer-dropdown/dropdown-ui.js +0 -158
  106. package/dist/injections/layer-dropdown/dropdown-ui.js.map +0 -1
  107. package/dist/injections/layer-dropdown/types.d.ts +0 -21
  108. package/dist/injections/layer-dropdown/types.d.ts.map +0 -1
  109. package/dist/injections/layer-dropdown/types.js +0 -3
  110. package/dist/injections/layer-dropdown/types.js.map +0 -1
  111. package/dist/injections/layer-dropdown/utils.d.ts +0 -24
  112. package/dist/injections/layer-dropdown/utils.d.ts.map +0 -1
  113. package/dist/injections/layer-dropdown/utils.js +0 -150
  114. package/dist/injections/layer-dropdown/utils.js.map +0 -1
  115. package/src/injections/layer-dropdown/LAYERS.md +0 -258
  116. package/src/injections/layer-dropdown/consts.ts +0 -44
  117. package/src/injections/layer-dropdown/controller.ts +0 -105
  118. package/src/injections/layer-dropdown/dropdown-ui.ts +0 -221
  119. package/src/injections/layer-dropdown/types.ts +0 -24
  120. package/src/injections/layer-dropdown/utils.ts +0 -185
@@ -0,0 +1,39 @@
1
+ import type { ElementPosition } from "../handlers/messages/types.js";
2
+
3
+ /**
4
+ * Calculate element position from bounding rect
5
+ */
6
+ export function getElementPosition(rect: DOMRect): ElementPosition {
7
+ return {
8
+ top: rect.top,
9
+ left: rect.left,
10
+ right: rect.right,
11
+ bottom: rect.bottom,
12
+ width: rect.width,
13
+ height: rect.height,
14
+ centerX: rect.left + rect.width / 2,
15
+ centerY: rect.top + rect.height / 2,
16
+ };
17
+ }
18
+
19
+ /**
20
+ * Check if element rect is in viewport
21
+ */
22
+ export function isElementInViewport(rect: DOMRect): boolean {
23
+ return (
24
+ rect.top < window.innerHeight &&
25
+ rect.bottom > 0 &&
26
+ rect.left < window.innerWidth &&
27
+ rect.right > 0
28
+ );
29
+ }
30
+
31
+ /**
32
+ * Get element classes (handles both HTML and SVG)
33
+ */
34
+ export function getElementClasses(element: Element): string {
35
+ if (element instanceof SVGElement) {
36
+ return (element.className as unknown as SVGAnimatedString)?.baseVal || "";
37
+ }
38
+ return element.className || "";
39
+ }
@@ -1,577 +1 @@
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";
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"}