@base44-preview/vite-plugin 0.2.22-pr.36.425440e → 0.2.22-pr.36.6dec368
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 +5 -4
- package/dist/injections/layer-dropdown/consts.d.ts.map +1 -1
- package/dist/injections/layer-dropdown/consts.js +5 -4
- package/dist/injections/layer-dropdown/consts.js.map +1 -1
- package/dist/injections/layer-dropdown/controller.d.ts +2 -2
- package/dist/injections/layer-dropdown/controller.d.ts.map +1 -1
- package/dist/injections/layer-dropdown/controller.js +37 -34
- package/dist/injections/layer-dropdown/controller.js.map +1 -1
- package/dist/injections/layer-dropdown/dropdown-ui.d.ts +3 -3
- package/dist/injections/layer-dropdown/dropdown-ui.d.ts.map +1 -1
- package/dist/injections/layer-dropdown/dropdown-ui.js +25 -21
- package/dist/injections/layer-dropdown/dropdown-ui.js.map +1 -1
- package/dist/injections/layer-dropdown/types.d.ts +6 -1
- package/dist/injections/layer-dropdown/types.d.ts.map +1 -1
- package/dist/injections/layer-dropdown/utils.d.ts +2 -1
- package/dist/injections/layer-dropdown/utils.d.ts.map +1 -1
- package/dist/injections/layer-dropdown/utils.js +28 -47
- package/dist/injections/layer-dropdown/utils.js.map +1 -1
- package/dist/injections/visual-edit-agent.js +5 -5
- 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/consts.ts +6 -4
- package/src/injections/layer-dropdown/controller.ts +40 -36
- package/src/injections/layer-dropdown/dropdown-ui.ts +28 -33
- package/src/injections/layer-dropdown/types.ts +7 -1
- package/src/injections/layer-dropdown/utils.ts +30 -53
- package/src/injections/visual-edit-agent.ts +5 -5
|
@@ -8,25 +8,24 @@ import {
|
|
|
8
8
|
DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT,
|
|
9
9
|
DROPDOWN_ITEM_HOVER_BG,
|
|
10
10
|
DEPTH_INDENT_PX,
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
BASE_PADDING_PX,
|
|
12
|
+
CHEVRON_COLLAPSED,
|
|
13
|
+
CHEVRON_EXPANDED,
|
|
13
14
|
LAYER_DROPDOWN_ATTR,
|
|
14
15
|
} from "./consts.js";
|
|
15
16
|
import { applyStyles, getLayerDisplayName } from "./utils.js";
|
|
16
|
-
import type { LayerInfo,
|
|
17
|
+
import type { LayerInfo, DropdownCallbacks } from "./types.js";
|
|
17
18
|
|
|
18
19
|
let activeDropdown: HTMLDivElement | null = null;
|
|
19
20
|
let activeLabel: HTMLDivElement | null = null;
|
|
20
21
|
let outsideMousedownHandler: ((e: MouseEvent) => void) | null = null;
|
|
21
|
-
let activeOnHoverEnd:
|
|
22
|
+
let activeOnHoverEnd: (() => void) | null = null;
|
|
22
23
|
let activeKeydownHandler: ((e: KeyboardEvent) => void) | null = null;
|
|
23
24
|
|
|
24
25
|
function createDropdownItem(
|
|
25
26
|
layer: LayerInfo,
|
|
26
27
|
isActive: boolean,
|
|
27
|
-
onSelect:
|
|
28
|
-
onHover?: OnLayerHover,
|
|
29
|
-
onHoverEnd?: OnLayerHoverEnd
|
|
28
|
+
{ onSelect, onHover, onHoverEnd }: DropdownCallbacks
|
|
30
29
|
): HTMLDivElement {
|
|
31
30
|
const item = document.createElement("div");
|
|
32
31
|
item.textContent = getLayerDisplayName(layer);
|
|
@@ -34,7 +33,7 @@ function createDropdownItem(
|
|
|
34
33
|
|
|
35
34
|
const depth = layer.depth ?? 0;
|
|
36
35
|
if (depth > 0) {
|
|
37
|
-
item.style.paddingLeft = `${
|
|
36
|
+
item.style.paddingLeft = `${BASE_PADDING_PX + depth * DEPTH_INDENT_PX}px`;
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
if (isActive) {
|
|
@@ -66,9 +65,7 @@ function createDropdownItem(
|
|
|
66
65
|
export function createDropdownElement(
|
|
67
66
|
layers: LayerInfo[],
|
|
68
67
|
currentSelectorId: string | null,
|
|
69
|
-
|
|
70
|
-
onHover?: OnLayerHover,
|
|
71
|
-
onHoverEnd?: OnLayerHoverEnd
|
|
68
|
+
callbacks: DropdownCallbacks
|
|
72
69
|
): HTMLDivElement {
|
|
73
70
|
const container = document.createElement("div");
|
|
74
71
|
container.setAttribute(LAYER_DROPDOWN_ATTR, "true");
|
|
@@ -76,7 +73,7 @@ export function createDropdownElement(
|
|
|
76
73
|
|
|
77
74
|
layers.forEach((layer) => {
|
|
78
75
|
const isActive = layer.selectorId === currentSelectorId;
|
|
79
|
-
container.appendChild(createDropdownItem(layer, isActive,
|
|
76
|
+
container.appendChild(createDropdownItem(layer, isActive, callbacks));
|
|
80
77
|
});
|
|
81
78
|
|
|
82
79
|
return container;
|
|
@@ -85,11 +82,12 @@ export function createDropdownElement(
|
|
|
85
82
|
/** Add chevron indicator and pointer-events to the label */
|
|
86
83
|
export function enhanceLabelWithChevron(label: HTMLDivElement): void {
|
|
87
84
|
const t = label.textContent ?? "";
|
|
88
|
-
if (t.endsWith(
|
|
85
|
+
if (t.endsWith(CHEVRON_COLLAPSED) || t.endsWith(CHEVRON_EXPANDED)) return;
|
|
89
86
|
|
|
90
|
-
label.textContent = t +
|
|
87
|
+
label.textContent = t + CHEVRON_COLLAPSED;
|
|
91
88
|
label.style.cursor = "pointer";
|
|
92
89
|
label.style.userSelect = "none";
|
|
90
|
+
label.style.whiteSpace = "nowrap";
|
|
93
91
|
label.style.pointerEvents = "auto";
|
|
94
92
|
label.setAttribute(LAYER_DROPDOWN_ATTR, "true");
|
|
95
93
|
}
|
|
@@ -98,9 +96,7 @@ function setupKeyboardNavigation(
|
|
|
98
96
|
dropdown: HTMLDivElement,
|
|
99
97
|
layers: LayerInfo[],
|
|
100
98
|
currentSelectorId: string | null,
|
|
101
|
-
onSelect:
|
|
102
|
-
onHover?: OnLayerHover,
|
|
103
|
-
onHoverEnd?: OnLayerHoverEnd
|
|
99
|
+
{ onSelect, onHover, onHoverEnd }: DropdownCallbacks
|
|
104
100
|
): void {
|
|
105
101
|
const items = Array.from(dropdown.children) as HTMLDivElement[];
|
|
106
102
|
let focusedIndex = layers.findIndex((l) => l.selectorId === currentSelectorId);
|
|
@@ -163,22 +159,21 @@ export function showDropdown(
|
|
|
163
159
|
label: HTMLDivElement,
|
|
164
160
|
layers: LayerInfo[],
|
|
165
161
|
currentSelectorId: string | null,
|
|
166
|
-
|
|
167
|
-
onHover?: OnLayerHover,
|
|
168
|
-
onHoverEnd?: OnLayerHoverEnd
|
|
162
|
+
callbacks: DropdownCallbacks
|
|
169
163
|
): void {
|
|
170
164
|
closeDropdown();
|
|
171
165
|
|
|
172
166
|
const dropdown = createDropdownElement(
|
|
173
167
|
layers,
|
|
174
168
|
currentSelectorId,
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
onSelect(layer)
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
169
|
+
{
|
|
170
|
+
...callbacks,
|
|
171
|
+
onSelect: (layer) => {
|
|
172
|
+
if (callbacks.onHoverEnd) callbacks.onHoverEnd();
|
|
173
|
+
callbacks.onSelect(layer);
|
|
174
|
+
closeDropdown();
|
|
175
|
+
},
|
|
176
|
+
}
|
|
182
177
|
);
|
|
183
178
|
|
|
184
179
|
const overlay = label.parentElement;
|
|
@@ -190,19 +185,19 @@ export function showDropdown(
|
|
|
190
185
|
overlay.appendChild(dropdown);
|
|
191
186
|
activeDropdown = dropdown;
|
|
192
187
|
activeLabel = label;
|
|
193
|
-
if (label.textContent?.endsWith(
|
|
194
|
-
label.textContent = label.textContent.slice(0, -
|
|
188
|
+
if (label.textContent?.endsWith(CHEVRON_COLLAPSED.trim())) {
|
|
189
|
+
label.textContent = label.textContent.slice(0, -CHEVRON_COLLAPSED.length) + CHEVRON_EXPANDED;
|
|
195
190
|
}
|
|
196
|
-
activeOnHoverEnd = onHoverEnd ?? null;
|
|
191
|
+
activeOnHoverEnd = callbacks.onHoverEnd ?? null;
|
|
197
192
|
|
|
198
|
-
setupKeyboardNavigation(dropdown, layers, currentSelectorId,
|
|
193
|
+
setupKeyboardNavigation(dropdown, layers, currentSelectorId, callbacks);
|
|
199
194
|
setupOutsideClickHandler(dropdown, label);
|
|
200
195
|
}
|
|
201
196
|
|
|
202
197
|
/** Close the active dropdown and clean up listeners */
|
|
203
198
|
export function closeDropdown(): void {
|
|
204
|
-
if (activeLabel?.textContent?.includes(
|
|
205
|
-
activeLabel.textContent = activeLabel.textContent.replace(
|
|
199
|
+
if (activeLabel?.textContent?.includes(CHEVRON_EXPANDED)) {
|
|
200
|
+
activeLabel.textContent = activeLabel.textContent.replace(CHEVRON_EXPANDED, CHEVRON_COLLAPSED);
|
|
206
201
|
}
|
|
207
202
|
activeLabel = null;
|
|
208
203
|
|
|
@@ -11,7 +11,13 @@ export type OnLayerSelect = (layer: LayerInfo) => void;
|
|
|
11
11
|
export type OnLayerHover = (layer: LayerInfo) => void;
|
|
12
12
|
export type OnLayerHoverEnd = () => void;
|
|
13
13
|
|
|
14
|
-
export interface
|
|
14
|
+
export interface DropdownCallbacks {
|
|
15
|
+
onSelect: OnLayerSelect;
|
|
16
|
+
onHover?: OnLayerHover;
|
|
17
|
+
onHoverEnd?: OnLayerHoverEnd;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface LayerControllerConfig {
|
|
15
21
|
createPreviewOverlay: (element: Element) => HTMLDivElement;
|
|
16
22
|
getSelectedElementId: () => string | null;
|
|
17
23
|
selectElement: (element: Element) => HTMLDivElement | undefined;
|
|
@@ -15,14 +15,26 @@ export function getLayerDisplayName(layer: LayerInfo): string {
|
|
|
15
15
|
return layer.tagName;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
function toLayerInfo(element: Element, depth?: number): LayerInfo {
|
|
19
|
+
const info: LayerInfo = {
|
|
20
|
+
element,
|
|
21
|
+
tagName: element.tagName.toLowerCase(),
|
|
22
|
+
selectorId: getElementSelectorId(element),
|
|
23
|
+
};
|
|
24
|
+
if (depth !== undefined) info.depth = depth;
|
|
25
|
+
return info;
|
|
26
|
+
}
|
|
27
|
+
|
|
18
28
|
/**
|
|
19
29
|
* Collect instrumented descendants up to `maxDepth` instrumented nesting levels.
|
|
20
30
|
* Non-instrumented wrappers are walked through without counting toward depth.
|
|
21
31
|
* Results are in DOM order.
|
|
32
|
+
* When `startDepth` is provided, assigns `depth` to each item during collection.
|
|
22
33
|
*/
|
|
23
34
|
export function getInstrumentedDescendants(
|
|
24
35
|
parent: Element,
|
|
25
|
-
maxDepth: number
|
|
36
|
+
maxDepth: number,
|
|
37
|
+
startDepth?: number
|
|
26
38
|
): LayerInfo[] {
|
|
27
39
|
const result: LayerInfo[] = [];
|
|
28
40
|
|
|
@@ -31,11 +43,15 @@ export function getInstrumentedDescendants(
|
|
|
31
43
|
for (let i = 0; i < el.children.length; i++) {
|
|
32
44
|
const child = el.children[i]!;
|
|
33
45
|
if (isInstrumentedElement(child)) {
|
|
34
|
-
|
|
46
|
+
const info: LayerInfo = {
|
|
35
47
|
element: child,
|
|
36
48
|
tagName: child.tagName.toLowerCase(),
|
|
37
49
|
selectorId: getElementSelectorId(child),
|
|
38
|
-
}
|
|
50
|
+
};
|
|
51
|
+
if (startDepth !== undefined) {
|
|
52
|
+
info.depth = startDepth + instrDepth - 1;
|
|
53
|
+
}
|
|
54
|
+
result.push(info);
|
|
39
55
|
walk(child, instrDepth + 1);
|
|
40
56
|
} else {
|
|
41
57
|
walk(child, instrDepth);
|
|
@@ -47,16 +63,6 @@ export function getInstrumentedDescendants(
|
|
|
47
63
|
return result;
|
|
48
64
|
}
|
|
49
65
|
|
|
50
|
-
function toLayerInfo(element: Element, depth?: number): LayerInfo {
|
|
51
|
-
const info: LayerInfo = {
|
|
52
|
-
element,
|
|
53
|
-
tagName: element.tagName.toLowerCase(),
|
|
54
|
-
selectorId: getElementSelectorId(element),
|
|
55
|
-
};
|
|
56
|
-
if (depth !== undefined) info.depth = depth;
|
|
57
|
-
return info;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
66
|
/** Collect instrumented ancestors from selected element up to MAX_PARENT_DEPTH (outermost first). */
|
|
61
67
|
function collectInstrumentedParents(selectedElement: Element): LayerInfo[] {
|
|
62
68
|
const parents: LayerInfo[] = [];
|
|
@@ -76,16 +82,16 @@ function collectInstrumentedParents(selectedElement: Element): LayerInfo[] {
|
|
|
76
82
|
return parents;
|
|
77
83
|
}
|
|
78
84
|
|
|
79
|
-
/**
|
|
80
|
-
function
|
|
85
|
+
/** Add parents to chain with depth 0, 1, …; returns depth of selected (parents.length). */
|
|
86
|
+
function addParentsToChain(chain: LayerInfo[], parents: LayerInfo[]): number {
|
|
81
87
|
parents.forEach((p, i) => {
|
|
82
88
|
chain.push({ ...p, depth: i });
|
|
83
89
|
});
|
|
84
90
|
return parents.length;
|
|
85
91
|
}
|
|
86
92
|
|
|
87
|
-
/**
|
|
88
|
-
function
|
|
93
|
+
/** Add selected element and its descendants at the given depth. */
|
|
94
|
+
function addSelfAndDescendantsToChain(
|
|
89
95
|
chain: LayerInfo[],
|
|
90
96
|
selectedElement: Element,
|
|
91
97
|
selfDepth: number
|
|
@@ -93,15 +99,15 @@ function appendSelfAndDescendants(
|
|
|
93
99
|
chain.push(toLayerInfo(selectedElement, selfDepth));
|
|
94
100
|
const descendants = getInstrumentedDescendants(
|
|
95
101
|
selectedElement,
|
|
96
|
-
MAX_CHILD_DEPTH
|
|
102
|
+
MAX_CHILD_DEPTH,
|
|
103
|
+
selfDepth + 1
|
|
97
104
|
);
|
|
98
|
-
assignDescendantDepths(selectedElement, descendants, selfDepth + 1);
|
|
99
105
|
chain.push(...descendants);
|
|
100
106
|
}
|
|
101
107
|
|
|
102
108
|
/** Get the innermost instrumented parent's DOM element, or null if none. */
|
|
103
109
|
function getImmediateInstrParent(parents: LayerInfo[]): Element | null {
|
|
104
|
-
return parents.
|
|
110
|
+
return parents.at(-1)?.element ?? null;
|
|
105
111
|
}
|
|
106
112
|
|
|
107
113
|
/** Collect instrumented siblings of the selected element from its parent (DOM order). */
|
|
@@ -113,7 +119,7 @@ function collectSiblings(parent: Element, selectedElement: Element): LayerInfo[]
|
|
|
113
119
|
return siblings;
|
|
114
120
|
}
|
|
115
121
|
|
|
116
|
-
/**
|
|
122
|
+
/** Add siblings at selfDepth, expanding children only for the selected element. */
|
|
117
123
|
function appendSiblingsWithSelected(
|
|
118
124
|
chain: LayerInfo[],
|
|
119
125
|
siblings: LayerInfo[],
|
|
@@ -122,7 +128,7 @@ function appendSiblingsWithSelected(
|
|
|
122
128
|
): void {
|
|
123
129
|
for (const sibling of siblings) {
|
|
124
130
|
if (sibling.element === selectedElement) {
|
|
125
|
-
|
|
131
|
+
addSelfAndDescendantsToChain(chain, selectedElement, selfDepth);
|
|
126
132
|
} else {
|
|
127
133
|
chain.push({ ...sibling, depth: selfDepth });
|
|
128
134
|
}
|
|
@@ -142,44 +148,15 @@ function appendSiblingsWithSelected(
|
|
|
142
148
|
export function buildLayerChain(selectedElement: Element): LayerInfo[] {
|
|
143
149
|
const parents = collectInstrumentedParents(selectedElement);
|
|
144
150
|
const chain: LayerInfo[] = [];
|
|
145
|
-
const selfDepth =
|
|
151
|
+
const selfDepth = addParentsToChain(chain, parents);
|
|
146
152
|
|
|
147
153
|
const instrParent = getImmediateInstrParent(parents);
|
|
148
154
|
if (instrParent) {
|
|
149
155
|
const siblings = collectSiblings(instrParent, selectedElement);
|
|
150
156
|
appendSiblingsWithSelected(chain, siblings, selectedElement, selfDepth);
|
|
151
157
|
} else {
|
|
152
|
-
|
|
158
|
+
addSelfAndDescendantsToChain(chain, selectedElement, selfDepth);
|
|
153
159
|
}
|
|
154
160
|
|
|
155
161
|
return chain;
|
|
156
162
|
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Walk the DOM tree again to assign correct visual depth to each descendant.
|
|
160
|
-
* This avoids storing depth during collection and keeps the API simple.
|
|
161
|
-
*/
|
|
162
|
-
function assignDescendantDepths(
|
|
163
|
-
root: Element,
|
|
164
|
-
descendants: LayerInfo[],
|
|
165
|
-
startDepth: number
|
|
166
|
-
): void {
|
|
167
|
-
// Build a set for O(1) lookup
|
|
168
|
-
const descSet = new Set(descendants.map((d) => d.element));
|
|
169
|
-
// Map element → LayerInfo for mutation
|
|
170
|
-
const descMap = new Map(descendants.map((d) => [d.element, d]));
|
|
171
|
-
|
|
172
|
-
function walk(el: Element, instrDepth: number): void {
|
|
173
|
-
for (let i = 0; i < el.children.length; i++) {
|
|
174
|
-
const child = el.children[i]!;
|
|
175
|
-
if (descSet.has(child)) {
|
|
176
|
-
descMap.get(child)!.depth = startDepth + instrDepth - 1;
|
|
177
|
-
walk(child, instrDepth + 1);
|
|
178
|
-
} else {
|
|
179
|
-
walk(child, instrDepth);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
walk(root, 1);
|
|
185
|
-
}
|
|
@@ -140,7 +140,7 @@ export function setupVisualEditAgent() {
|
|
|
140
140
|
return selectedOverlays[0];
|
|
141
141
|
};
|
|
142
142
|
|
|
143
|
-
const
|
|
143
|
+
const notifyDeselection = (): void => {
|
|
144
144
|
selectedElementId = null;
|
|
145
145
|
window.parent.postMessage({ type: "unselect-element" }, "*");
|
|
146
146
|
};
|
|
@@ -248,8 +248,8 @@ export function setupVisualEditAgent() {
|
|
|
248
248
|
layerController.attachToOverlay(selectedOverlay, element);
|
|
249
249
|
};
|
|
250
250
|
|
|
251
|
-
//
|
|
252
|
-
const
|
|
251
|
+
// Clear the current selection
|
|
252
|
+
const clearSelection = () => {
|
|
253
253
|
clearSelectedOverlays();
|
|
254
254
|
selectedElementId = null;
|
|
255
255
|
};
|
|
@@ -320,7 +320,7 @@ export function setupVisualEditAgent() {
|
|
|
320
320
|
},
|
|
321
321
|
getSelectedElementId: () => selectedElementId,
|
|
322
322
|
selectElement,
|
|
323
|
-
onDeselect:
|
|
323
|
+
onDeselect: notifyDeselection,
|
|
324
324
|
});
|
|
325
325
|
|
|
326
326
|
// Toggle visual edit mode
|
|
@@ -411,7 +411,7 @@ export function setupVisualEditAgent() {
|
|
|
411
411
|
break;
|
|
412
412
|
|
|
413
413
|
case "unselect-element":
|
|
414
|
-
|
|
414
|
+
clearSelection();
|
|
415
415
|
break;
|
|
416
416
|
|
|
417
417
|
case "refresh-page":
|