@base44-preview/vite-plugin 0.3.3-pr.51.205ae5c → 0.3.3-pr.51.4604dab
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/html-injections-plugin.d.ts.map +1 -1
- package/dist/html-injections-plugin.js +30 -28
- package/dist/html-injections-plugin.js.map +1 -1
- 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/dropdown-ui.d.ts.map +1 -1
- package/dist/injections/layer-dropdown/dropdown-ui.js +15 -8
- package/dist/injections/layer-dropdown/dropdown-ui.js.map +1 -1
- package/dist/injections/utils.d.ts +17 -0
- package/dist/injections/utils.d.ts.map +1 -1
- package/dist/injections/utils.js +36 -0
- 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 +2 -22
- package/dist/injections/visual-edit-agent.js.map +1 -1
- package/dist/statics/index.mjs +3 -3
- package/dist/statics/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/html-injections-plugin.ts +30 -28
- package/src/injections/layer-dropdown/consts.ts +6 -4
- package/src/injections/layer-dropdown/dropdown-ui.ts +16 -7
- package/src/injections/utils.ts +37 -0
- package/src/injections/visual-edit-agent.ts +2 -22
|
@@ -11,35 +11,37 @@ type Injection = {
|
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
const ANALYTICS_TRACKER_SCRIPT = `
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
history.pushState
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
history.replaceState
|
|
38
|
-
|
|
14
|
+
if (window.self === window.top) {
|
|
15
|
+
let lastPath = "";
|
|
16
|
+
function getPageNameFromPath(path) {
|
|
17
|
+
const segments = path.split("/").filter(Boolean);
|
|
18
|
+
return segments[0] || null;
|
|
19
|
+
}
|
|
20
|
+
function trackPageView() {
|
|
21
|
+
const path = window.location.pathname;
|
|
22
|
+
if (path === lastPath) return;
|
|
23
|
+
lastPath = path;
|
|
24
|
+
const pageName = getPageNameFromPath(path) || "home";
|
|
25
|
+
const appId = import.meta.env.VITE_BASE44_APP_ID;
|
|
26
|
+
const serverUrl = import.meta.env.VITE_BASE44_BACKEND_URL || "";
|
|
27
|
+
if (!appId) return;
|
|
28
|
+
fetch(\`\${serverUrl}/app-logs/\${appId}/log-user-in-app/\${pageName}\`, {
|
|
29
|
+
method: "POST",
|
|
30
|
+
}).catch(() => {});
|
|
31
|
+
}
|
|
32
|
+
const originalPushState = history.pushState.bind(history);
|
|
33
|
+
history.pushState = function (...args) {
|
|
34
|
+
originalPushState(...args);
|
|
35
|
+
trackPageView();
|
|
36
|
+
};
|
|
37
|
+
const originalReplaceState = history.replaceState.bind(history);
|
|
38
|
+
history.replaceState = function (...args) {
|
|
39
|
+
originalReplaceState(...args);
|
|
40
|
+
trackPageView();
|
|
41
|
+
};
|
|
42
|
+
window.addEventListener("popstate", trackPageView);
|
|
39
43
|
trackPageView();
|
|
40
|
-
}
|
|
41
|
-
window.addEventListener("popstate", trackPageView);
|
|
42
|
-
trackPageView();
|
|
44
|
+
}
|
|
43
45
|
`;
|
|
44
46
|
|
|
45
47
|
const INJECTIONS: Record<string, Injection> = {
|
|
@@ -33,10 +33,12 @@ export const DROPDOWN_ITEM_HOVER_BG = "#f1f5f9";
|
|
|
33
33
|
|
|
34
34
|
export const DEPTH_INDENT_PX = 10;
|
|
35
35
|
|
|
36
|
-
/**
|
|
37
|
-
export const CHEVRON_COLLAPSED = "
|
|
38
|
-
/**
|
|
39
|
-
export const CHEVRON_EXPANDED = "
|
|
36
|
+
/** SVG chevron shown when dropdown is collapsed (click to expand) */
|
|
37
|
+
export const CHEVRON_COLLAPSED = `<svg width="12" height="12" viewBox="0 0 24 24" style="vertical-align:middle;margin-left:4px"><path d="M6 9l6 6 6-6" stroke="currentColor" stroke-width="2" fill="none"/></svg>`;
|
|
38
|
+
/** SVG chevron shown when dropdown is expanded (click to collapse) */
|
|
39
|
+
export const CHEVRON_EXPANDED = `<svg width="12" height="12" viewBox="0 0 24 24" style="vertical-align:middle;margin-left:4px"><path d="M18 15l-6-6-6 6" stroke="currentColor" stroke-width="2" fill="none"/></svg>`;
|
|
40
|
+
|
|
41
|
+
export const CHEVRON_ATTR = "data-chevron";
|
|
40
42
|
|
|
41
43
|
export const BASE_PADDING_PX = 12;
|
|
42
44
|
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
BASE_PADDING_PX,
|
|
12
12
|
CHEVRON_COLLAPSED,
|
|
13
13
|
CHEVRON_EXPANDED,
|
|
14
|
+
CHEVRON_ATTR,
|
|
14
15
|
LAYER_DROPDOWN_ATTR,
|
|
15
16
|
} from "./consts.js";
|
|
16
17
|
import { applyStyles, getLayerDisplayName } from "./utils.js";
|
|
@@ -83,10 +84,16 @@ export function createDropdownElement(
|
|
|
83
84
|
|
|
84
85
|
/** Add chevron indicator and pointer-events to the label */
|
|
85
86
|
export function enhanceLabelWithChevron(label: HTMLDivElement): void {
|
|
86
|
-
|
|
87
|
-
if (t.endsWith(CHEVRON_COLLAPSED) || t.endsWith(CHEVRON_EXPANDED)) return;
|
|
87
|
+
if (label.querySelector(`[${CHEVRON_ATTR}]`)) return;
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
const chevron = document.createElement("span");
|
|
90
|
+
chevron.setAttribute(CHEVRON_ATTR, "true");
|
|
91
|
+
chevron.style.display = "inline-flex";
|
|
92
|
+
chevron.innerHTML = CHEVRON_COLLAPSED;
|
|
93
|
+
label.appendChild(chevron);
|
|
94
|
+
|
|
95
|
+
label.style.display = "inline-flex";
|
|
96
|
+
label.style.alignItems = "center";
|
|
90
97
|
label.style.cursor = "pointer";
|
|
91
98
|
label.style.userSelect = "none";
|
|
92
99
|
label.style.whiteSpace = "nowrap";
|
|
@@ -190,8 +197,9 @@ export function showDropdown(
|
|
|
190
197
|
overlay.appendChild(dropdown);
|
|
191
198
|
activeDropdown = dropdown;
|
|
192
199
|
activeLabel = label;
|
|
193
|
-
|
|
194
|
-
|
|
200
|
+
const chevronEl = label.querySelector(`[${CHEVRON_ATTR}]`);
|
|
201
|
+
if (chevronEl) {
|
|
202
|
+
chevronEl.innerHTML = CHEVRON_EXPANDED;
|
|
195
203
|
}
|
|
196
204
|
activeOnHoverEnd = callbacks.onHoverEnd ?? null;
|
|
197
205
|
|
|
@@ -201,8 +209,9 @@ export function showDropdown(
|
|
|
201
209
|
|
|
202
210
|
/** Close the active dropdown and clean up listeners */
|
|
203
211
|
export function closeDropdown(): void {
|
|
204
|
-
|
|
205
|
-
|
|
212
|
+
const chevronEl = activeLabel?.querySelector(`[${CHEVRON_ATTR}]`);
|
|
213
|
+
if (chevronEl) {
|
|
214
|
+
chevronEl.innerHTML = CHEVRON_COLLAPSED;
|
|
206
215
|
}
|
|
207
216
|
activeLabel = null;
|
|
208
217
|
|
package/src/injections/utils.ts
CHANGED
|
@@ -1,3 +1,40 @@
|
|
|
1
|
+
const LABEL_HEIGHT = 27;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Positions an element-tag label relative to its highlighted overlay.
|
|
5
|
+
*
|
|
6
|
+
* Strategy (in priority order):
|
|
7
|
+
* 1. If the element is near the viewport top AND tall enough (>= 2x label height),
|
|
8
|
+
* place the label **inside** the element at the top-left.
|
|
9
|
+
* 2. If the element is near the viewport top but too short, place the label
|
|
10
|
+
* **below** the element.
|
|
11
|
+
* 3. Otherwise, place the label **above** the element (default).
|
|
12
|
+
*
|
|
13
|
+
* For full-width elements (spanning nearly the entire viewport), the left offset
|
|
14
|
+
* is nudged inward (6px) to prevent clipping against the viewport edge.
|
|
15
|
+
*
|
|
16
|
+
* @param label - The label div to position (style.top and style.left are set).
|
|
17
|
+
* @param rect - The bounding client rect of the highlighted element.
|
|
18
|
+
*/
|
|
19
|
+
export function positionLabel(label: HTMLDivElement, rect: DOMRect): void {
|
|
20
|
+
const nearTop = rect.top < LABEL_HEIGHT;
|
|
21
|
+
const tallEnough = rect.height >= LABEL_HEIGHT * 2;
|
|
22
|
+
const isFullWidth = rect.width >= window.innerWidth - 4;
|
|
23
|
+
const edgeLeft = isFullWidth ? "8px" : "-2px";
|
|
24
|
+
const insideLeft = isFullWidth ? "8px" : "4px";
|
|
25
|
+
|
|
26
|
+
if (nearTop && tallEnough) {
|
|
27
|
+
label.style.top = "2px";
|
|
28
|
+
label.style.left = insideLeft;
|
|
29
|
+
} else if (nearTop) {
|
|
30
|
+
label.style.top = `${rect.height + 2}px`;
|
|
31
|
+
label.style.left = edgeLeft;
|
|
32
|
+
} else {
|
|
33
|
+
label.style.top = `-${LABEL_HEIGHT}px`;
|
|
34
|
+
label.style.left = edgeLeft;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
1
38
|
/** Check if an element has instrumentation attributes */
|
|
2
39
|
export function isInstrumentedElement(element: Element): boolean {
|
|
3
40
|
const htmlEl = element as HTMLElement;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { findElementsById, updateElementClasses, updateElementAttribute, collectAllowedAttributes, ALLOWED_ATTRIBUTES, getElementSelectorId, stopAnimations, resumeAnimations, findInstrumentedElement, resolveHoverTarget } from "./utils.js";
|
|
1
|
+
import { findElementsById, updateElementClasses, updateElementAttribute, collectAllowedAttributes, ALLOWED_ATTRIBUTES, getElementSelectorId, stopAnimations, resumeAnimations, findInstrumentedElement, resolveHoverTarget, positionLabel } from "./utils.js";
|
|
2
2
|
import { createLayerController } from "./layer-dropdown/controller.js";
|
|
3
3
|
import { LAYER_DROPDOWN_ATTR } from "./layer-dropdown/consts.js";
|
|
4
4
|
import { createInlineEditController } from "../capabilities/inline-edit/index.js";
|
|
5
5
|
|
|
6
|
-
const LABEL_HEIGHT = 27;
|
|
7
6
|
const REPOSITION_DELAY_MS = 50;
|
|
8
7
|
|
|
9
8
|
export function setupVisualEditAgent() {
|
|
@@ -35,25 +34,6 @@ export function setupVisualEditAgent() {
|
|
|
35
34
|
return overlay;
|
|
36
35
|
};
|
|
37
36
|
|
|
38
|
-
const positionLabel = (label: HTMLDivElement, rect: DOMRect): void => {
|
|
39
|
-
const nearTop = rect.top < LABEL_HEIGHT;
|
|
40
|
-
const tallEnough = rect.height >= LABEL_HEIGHT * 2;
|
|
41
|
-
const isFullWidth = rect.width >= window.innerWidth - 4;
|
|
42
|
-
const edgeLeft = isFullWidth ? "6px" : "-2px";
|
|
43
|
-
const insideLeft = isFullWidth ? "6px" : "4px";
|
|
44
|
-
|
|
45
|
-
if (nearTop && tallEnough) {
|
|
46
|
-
label.style.top = "2px";
|
|
47
|
-
label.style.left = insideLeft;
|
|
48
|
-
} else if (nearTop) {
|
|
49
|
-
label.style.top = `${rect.height + 2}px`;
|
|
50
|
-
label.style.left = edgeLeft;
|
|
51
|
-
} else {
|
|
52
|
-
label.style.top = `-${LABEL_HEIGHT}px`;
|
|
53
|
-
label.style.left = edgeLeft;
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
37
|
// Position overlay relative to element
|
|
58
38
|
const positionOverlay = (
|
|
59
39
|
overlay: HTMLDivElement,
|
|
@@ -84,7 +64,7 @@ export function setupVisualEditAgent() {
|
|
|
84
64
|
label.style.fontSize = "11px";
|
|
85
65
|
label.style.fontWeight = isSelected ? "500" : "400";
|
|
86
66
|
label.style.color = isSelected ? "#ffffff" : "#526cff";
|
|
87
|
-
label.style.backgroundColor = isSelected ? "#
|
|
67
|
+
label.style.backgroundColor = isSelected ? "#2563EB" : "#DBEAFE";
|
|
88
68
|
label.style.borderRadius = "3px";
|
|
89
69
|
label.style.minWidth = "24px";
|
|
90
70
|
label.style.textAlign = "center";
|