@base44-preview/vite-plugin 0.2.29-pr.45.28c5745 → 0.2.29-pr.45.b9c5a5a
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/capabilities/inline-edit/controller.d.ts.map +1 -1
- package/dist/capabilities/inline-edit/controller.js +3 -0
- package/dist/capabilities/inline-edit/controller.js.map +1 -1
- package/dist/injections/layer-dropdown/dropdown-ui.d.ts.map +1 -1
- package/dist/injections/layer-dropdown/dropdown-ui.js +3 -0
- package/dist/injections/layer-dropdown/dropdown-ui.js.map +1 -1
- package/dist/injections/utils.d.ts +27 -1
- package/dist/injections/utils.d.ts.map +1 -1
- package/dist/injections/utils.js +72 -35
- 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 +4 -13
- package/dist/injections/visual-edit-agent.js.map +1 -1
- package/dist/statics/index.mjs +9 -14
- package/dist/statics/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/capabilities/inline-edit/controller.ts +3 -0
- package/src/injections/layer-dropdown/dropdown-ui.ts +3 -0
- package/src/injections/utils.ts +72 -34
- package/src/injections/visual-edit-agent.ts +4 -14
package/src/injections/utils.ts
CHANGED
|
@@ -18,6 +18,8 @@ export function getElementSelectorId(element: Element): string | null {
|
|
|
18
18
|
|
|
19
19
|
export const ALLOWED_ATTRIBUTES: string[] = ["src"];
|
|
20
20
|
|
|
21
|
+
export const PLUGIN_ELEMENT_ATTR = "data-vite-plugin-element";
|
|
22
|
+
|
|
21
23
|
/** Find elements by ID - first try data-source-location, fallback to data-visual-selector-id */
|
|
22
24
|
export function findElementsById(id: string | null): Element[] {
|
|
23
25
|
if (!id) return [];
|
|
@@ -65,67 +67,103 @@ export function collectAllowedAttributes(element: Element, allowedAttributes: st
|
|
|
65
67
|
return attributes;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Freeze all CSS animations and transitions on the page by injecting
|
|
72
|
+
* scoped styles under `[data-visual-edit-active]` and programmatically
|
|
73
|
+
* finishing (or pausing) every running animation.
|
|
74
|
+
*
|
|
75
|
+
* Plugin-owned elements (`[data-vite-plugin-element]`) are excluded so
|
|
76
|
+
* the plugin UI stays animated.
|
|
77
|
+
*/
|
|
70
78
|
export function stopAnimations(): void {
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
if (document.getElementById('freeze-animations')) return;
|
|
80
|
+
|
|
81
|
+
document.documentElement.setAttribute('data-visual-edit-active', '');
|
|
82
|
+
|
|
83
|
+
const animStyle = document.createElement('style');
|
|
84
|
+
animStyle.id = 'freeze-animations';
|
|
85
|
+
animStyle.textContent = `
|
|
86
|
+
[data-visual-edit-active] *:not([${PLUGIN_ELEMENT_ATTR}]):not([${PLUGIN_ELEMENT_ATTR}] *),
|
|
87
|
+
[data-visual-edit-active] *:not([${PLUGIN_ELEMENT_ATTR}]):not([${PLUGIN_ELEMENT_ATTR}] *)::before,
|
|
88
|
+
[data-visual-edit-active] *:not([${PLUGIN_ELEMENT_ATTR}]):not([${PLUGIN_ELEMENT_ATTR}] *)::after {
|
|
79
89
|
animation-play-state: paused !important;
|
|
80
90
|
transition: none !important;
|
|
81
91
|
}
|
|
82
|
-
body * {
|
|
83
|
-
pointer-events: none !important;
|
|
84
|
-
}
|
|
85
|
-
[data-layer-dropdown],
|
|
86
|
-
[data-layer-dropdown] * {
|
|
87
|
-
pointer-events: auto !important;
|
|
88
|
-
}
|
|
89
|
-
[contenteditable="true"] {
|
|
90
|
-
pointer-events: auto !important;
|
|
91
|
-
}
|
|
92
92
|
`;
|
|
93
|
-
(document.head || document.documentElement).appendChild(style);
|
|
94
93
|
|
|
95
|
-
|
|
94
|
+
const pointerStyle = document.createElement('style');
|
|
95
|
+
pointerStyle.id = 'freeze-pointer-events';
|
|
96
|
+
pointerStyle.textContent = `
|
|
97
|
+
[data-visual-edit-active] * { pointer-events: none !important; }
|
|
98
|
+
[${PLUGIN_ELEMENT_ATTR}], [${PLUGIN_ELEMENT_ATTR}] * { pointer-events: auto !important; }
|
|
99
|
+
`;
|
|
100
|
+
|
|
101
|
+
const target = document.head || document.documentElement;
|
|
102
|
+
target.appendChild(animStyle);
|
|
103
|
+
target.appendChild(pointerStyle);
|
|
104
|
+
|
|
105
|
+
document.getAnimations().forEach((a) => {
|
|
106
|
+
// Skip animations on plugin UI elements
|
|
107
|
+
const animTarget = (a.effect as KeyframeEffect)?.target;
|
|
108
|
+
if (animTarget instanceof Element && animTarget.closest(`[${PLUGIN_ELEMENT_ATTR}]`)) return;
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
a.finish(); // fast-forward to end state
|
|
112
|
+
} catch {
|
|
113
|
+
a.pause(); // finish() throws on infinite animations — pause instead
|
|
114
|
+
}
|
|
115
|
+
});
|
|
96
116
|
}
|
|
97
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Resume all previously frozen animations and remove the injected
|
|
120
|
+
* freeze styles. Cleans up the `data-visual-edit-active` attribute
|
|
121
|
+
* from `<html>` so scoped selectors no longer match.
|
|
122
|
+
*/
|
|
98
123
|
export function resumeAnimations(): void {
|
|
99
|
-
|
|
100
|
-
|
|
124
|
+
const animStyle = document.getElementById('freeze-animations');
|
|
125
|
+
if (!animStyle) return;
|
|
101
126
|
|
|
102
|
-
|
|
127
|
+
animStyle.remove();
|
|
128
|
+
document.getElementById('freeze-pointer-events')?.remove();
|
|
129
|
+
document.documentElement.removeAttribute('data-visual-edit-active');
|
|
103
130
|
|
|
104
131
|
document.getAnimations().forEach((a) => {
|
|
105
|
-
|
|
132
|
+
if (a.playState === 'paused') {
|
|
133
|
+
try { a.play(); } catch { /* animation target may have been removed */ }
|
|
134
|
+
}
|
|
106
135
|
});
|
|
107
136
|
}
|
|
108
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Hit-test the page at (`x`, `y`) and walk up the DOM to find the
|
|
140
|
+
* nearest ancestor that carries instrumentation attributes
|
|
141
|
+
* (`data-source-location` or `data-visual-selector-id`).
|
|
142
|
+
*
|
|
143
|
+
* Temporarily disables the pointer-events freeze sheet so the
|
|
144
|
+
* browser's native `elementFromPoint` can reach the real target.
|
|
145
|
+
*/
|
|
109
146
|
export function findInstrumentedElement(x: number, y: number): Element | null {
|
|
110
|
-
const
|
|
111
|
-
if (
|
|
147
|
+
const pointerStyle = document.getElementById('freeze-pointer-events') as HTMLStyleElement | null;
|
|
148
|
+
if (pointerStyle) pointerStyle.disabled = true;
|
|
112
149
|
|
|
113
150
|
const el = document.elementFromPoint(x, y);
|
|
114
151
|
|
|
115
|
-
if (
|
|
152
|
+
if (pointerStyle) pointerStyle.disabled = false;
|
|
116
153
|
|
|
117
154
|
return el?.closest('[data-source-location], [data-visual-selector-id]') ?? null;
|
|
118
155
|
}
|
|
119
156
|
|
|
120
|
-
/**
|
|
157
|
+
/**
|
|
158
|
+
* Resolve which element should be hovered at (`x`, `y`), skipping the
|
|
159
|
+
* currently selected element. Returns the selector ID of the hovered
|
|
160
|
+
* element, or `null` if the point is empty or hits the selected element.
|
|
161
|
+
*/
|
|
121
162
|
export function resolveHoverTarget(x: number, y: number, selectedElementId: string | null): string | null {
|
|
122
163
|
const element = findInstrumentedElement(x, y);
|
|
123
164
|
if (!element) return null;
|
|
124
165
|
|
|
125
|
-
const
|
|
126
|
-
const selectorId =
|
|
127
|
-
htmlElement.dataset.sourceLocation ||
|
|
128
|
-
htmlElement.dataset.visualSelectorId || null;
|
|
166
|
+
const selectorId = getElementSelectorId(element);
|
|
129
167
|
|
|
130
168
|
if (selectorId === selectedElementId) return null;
|
|
131
169
|
|
|
@@ -196,10 +196,8 @@ export function setupVisualEditAgent() {
|
|
|
196
196
|
let pendingMouseMoveRaf: number | null = null;
|
|
197
197
|
|
|
198
198
|
const clearHoverState = () => {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
lastHoveredSelectorId = null;
|
|
202
|
-
}
|
|
199
|
+
clearHoverOverlays();
|
|
200
|
+
lastHoveredSelectorId = null;
|
|
203
201
|
};
|
|
204
202
|
|
|
205
203
|
const applyHoverOverlays = (selectorId: string) => {
|
|
@@ -240,8 +238,7 @@ export function setupVisualEditAgent() {
|
|
|
240
238
|
cancelAnimationFrame(pendingMouseMoveRaf);
|
|
241
239
|
pendingMouseMoveRaf = null;
|
|
242
240
|
}
|
|
243
|
-
|
|
244
|
-
lastHoveredSelectorId = null;
|
|
241
|
+
clearHoverState();
|
|
245
242
|
};
|
|
246
243
|
|
|
247
244
|
// Handle element click
|
|
@@ -421,14 +418,7 @@ export function setupVisualEditAgent() {
|
|
|
421
418
|
inlineEdit.stopEditing();
|
|
422
419
|
clearSelection();
|
|
423
420
|
layerController.cleanup();
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
currentHighlightedElements = [];
|
|
427
|
-
lastHoveredSelectorId = null;
|
|
428
|
-
if (pendingMouseMoveRaf !== null) {
|
|
429
|
-
cancelAnimationFrame(pendingMouseMoveRaf);
|
|
430
|
-
pendingMouseMoveRaf = null;
|
|
431
|
-
}
|
|
421
|
+
handleMouseLeave();
|
|
432
422
|
document.body.style.cursor = "default";
|
|
433
423
|
|
|
434
424
|
document.removeEventListener("mousemove", handleMouseMove);
|