@base44-preview/vite-plugin 1.0.20-pr.85.5e3dff7 → 1.0.21-pr.86.3f04404
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/navigation-notifier.js +0 -5
- package/dist/injections/navigation-notifier.js.map +1 -1
- package/dist/injections/utils.d.ts +1 -1
- package/dist/injections/utils.d.ts.map +1 -1
- package/dist/injections/utils.js +6 -2
- 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 +7 -31
- package/dist/injections/visual-edit-agent.js.map +1 -1
- package/dist/processors/static-array-processor.d.ts +2 -0
- package/dist/processors/static-array-processor.d.ts.map +1 -1
- package/dist/processors/static-array-processor.js +41 -2
- package/dist/processors/static-array-processor.js.map +1 -1
- package/dist/statics/index.mjs +7 -7
- package/dist/statics/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/injections/navigation-notifier.ts +0 -6
- package/src/injections/utils.ts +8 -2
- package/src/injections/visual-edit-agent.ts +11 -31
- package/src/processors/static-array-processor.ts +51 -2
package/package.json
CHANGED
|
@@ -32,12 +32,6 @@ if (window.self !== window.top) {
|
|
|
32
32
|
// Handle browser back/forward navigation
|
|
33
33
|
window.addEventListener("popstate", notifyNavigation);
|
|
34
34
|
|
|
35
|
-
// NOTE: parent-driven `navigate-to-route` (client-side navigation) is handled
|
|
36
|
-
// in the visual-edit agent (`visual-edit-agent.ts`), not here, so it can also
|
|
37
|
-
// clean up stale edit selection/overlays after the route change. The
|
|
38
|
-
// `pushState` patch above still fires `app_changed_url` when the agent
|
|
39
|
-
// navigates, so the parent gets its ack.
|
|
40
|
-
|
|
41
35
|
// Notify initial URL on load
|
|
42
36
|
window.parent?.postMessage(
|
|
43
37
|
{
|
package/src/injections/utils.ts
CHANGED
|
@@ -82,13 +82,19 @@ export function updateElementClasses(elements: Element[], classes: string): void
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
/** Set a single attribute on all provided elements. */
|
|
85
|
-
export function updateElementAttribute(elements: Element[], attribute: string, value: string): void {
|
|
85
|
+
export function updateElementAttribute(elements: Element[], attribute: string, value: string, arrIndex?: number | string): void {
|
|
86
86
|
if (!ALLOWED_ATTRIBUTES.includes(attribute)) {
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
const targetArrIndex = arrIndex != null ? String(arrIndex) : null;
|
|
90
91
|
elements.forEach((element) => {
|
|
91
|
-
|
|
92
|
+
if (
|
|
93
|
+
targetArrIndex === null ||
|
|
94
|
+
(element as HTMLElement).dataset.arrIndex === targetArrIndex
|
|
95
|
+
) {
|
|
96
|
+
element.setAttribute(attribute, value);
|
|
97
|
+
}
|
|
92
98
|
});
|
|
93
99
|
}
|
|
94
100
|
|
|
@@ -368,12 +368,19 @@ export function setupVisualEditAgent() {
|
|
|
368
368
|
const updateElementAttributeAndReposition = (
|
|
369
369
|
visualSelectorId: string,
|
|
370
370
|
attribute: string,
|
|
371
|
-
value: string
|
|
371
|
+
value: string,
|
|
372
|
+
arrIndex?: number | string
|
|
372
373
|
) => {
|
|
373
374
|
const elements = findElementsById(visualSelectorId);
|
|
374
375
|
if (elements.length === 0) return;
|
|
375
376
|
|
|
376
|
-
|
|
377
|
+
const targetArrIndex =
|
|
378
|
+
arrIndex ??
|
|
379
|
+
(selectedElementId === visualSelectorId
|
|
380
|
+
? (selectedElement as HTMLElement | null)?.dataset.arrIndex
|
|
381
|
+
: undefined);
|
|
382
|
+
|
|
383
|
+
updateElementAttribute(elements, attribute, value, targetArrIndex);
|
|
377
384
|
|
|
378
385
|
// Reposition overlays after attribute change (e.g. image src swap can affect layout)
|
|
379
386
|
setTimeout(() => {
|
|
@@ -505,34 +512,6 @@ export function setupVisualEditAgent() {
|
|
|
505
512
|
}
|
|
506
513
|
break;
|
|
507
514
|
|
|
508
|
-
case "navigate-to-route": {
|
|
509
|
-
// Parent-driven CLIENT-SIDE navigation (no document reload). The canvas
|
|
510
|
-
// keeps a single pre-booted iframe and switches which page it shows by
|
|
511
|
-
// posting this instead of swapping `src`. We pushState to the new path
|
|
512
|
-
// and dispatch popstate so the app's router (React Router et al.)
|
|
513
|
-
// re-renders the matched route. Handled HERE (in the visual-edit agent)
|
|
514
|
-
// rather than navigation-notifier so we can also clean up edit state:
|
|
515
|
-
// the previous route's selection/overlays point at now-detached nodes.
|
|
516
|
-
// Accept both flat (`message.path`) and nested (`message.data.path`).
|
|
517
|
-
const navPath = (message.data && message.data.path) || message.path;
|
|
518
|
-
if (typeof navPath === "string" && navPath.startsWith("/")) {
|
|
519
|
-
const replace = (message.data && message.data.replace) || message.replace;
|
|
520
|
-
if (replace) {
|
|
521
|
-
history.replaceState(history.state, "", navPath);
|
|
522
|
-
} else {
|
|
523
|
-
history.pushState(history.state, "", navPath);
|
|
524
|
-
}
|
|
525
|
-
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
526
|
-
// Drop stale selection/hover overlays from the previous page. The
|
|
527
|
-
// agent's listeners are document-level (persist across client-side
|
|
528
|
-
// nav) and elements carry build-injected data-source-location, so
|
|
529
|
-
// selection keeps working on the new route without re-instrumenting.
|
|
530
|
-
clearSelection();
|
|
531
|
-
clearHoverOverlays();
|
|
532
|
-
}
|
|
533
|
-
break;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
515
|
case "update-classes":
|
|
537
516
|
if (message.data && message.data.classes !== undefined) {
|
|
538
517
|
updateElementClassesAndReposition(
|
|
@@ -557,7 +536,8 @@ export function setupVisualEditAgent() {
|
|
|
557
536
|
updateElementAttributeAndReposition(
|
|
558
537
|
message.data.visualSelectorId,
|
|
559
538
|
message.data.attribute,
|
|
560
|
-
message.data.value
|
|
539
|
+
message.data.value,
|
|
540
|
+
message.data.arrIndex
|
|
561
541
|
);
|
|
562
542
|
} else {
|
|
563
543
|
console.warn(
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
DATA_ARR_INDEX,
|
|
5
5
|
DATA_ARR_VARIABLE_NAME,
|
|
6
6
|
DATA_ARR_FIELD,
|
|
7
|
+
MAX_JSX_DEPTH,
|
|
7
8
|
} from "../consts.js";
|
|
8
9
|
import { JSXAttributeUtils, StaticValueUtils } from "./utils/shared-utils.js";
|
|
9
10
|
|
|
10
|
-
|
|
11
11
|
const GENERATED_INDEX_PARAM = "__arrIdx__";
|
|
12
12
|
|
|
13
13
|
interface ArrayMapInfo {
|
|
@@ -69,6 +69,9 @@ export class StaticArrayProcessor {
|
|
|
69
69
|
path: NodePath<t.JSXOpeningElement>,
|
|
70
70
|
callbackParam: string
|
|
71
71
|
): string | null {
|
|
72
|
+
const imageSrcFieldPath = this.findImageSrcFieldPath(path, callbackParam);
|
|
73
|
+
if (imageSrcFieldPath) return imageSrcFieldPath;
|
|
74
|
+
|
|
72
75
|
const parentElement = path.parentPath;
|
|
73
76
|
if (!parentElement?.isJSXElement()) return null;
|
|
74
77
|
|
|
@@ -80,6 +83,35 @@ export class StaticArrayProcessor {
|
|
|
80
83
|
return null;
|
|
81
84
|
}
|
|
82
85
|
|
|
86
|
+
private findImageSrcFieldPath(
|
|
87
|
+
path: NodePath<t.JSXOpeningElement>,
|
|
88
|
+
callbackParam: string
|
|
89
|
+
): string | null {
|
|
90
|
+
const elementName = this.types.isJSXIdentifier(path.node.name)
|
|
91
|
+
? path.node.name.name
|
|
92
|
+
: null;
|
|
93
|
+
if (elementName !== "img" && elementName !== "Image") return null;
|
|
94
|
+
|
|
95
|
+
for (const attr of path.get("attributes")) {
|
|
96
|
+
if (!attr.isJSXAttribute()) continue;
|
|
97
|
+
|
|
98
|
+
const attrName = attr.get("name");
|
|
99
|
+
if (!attrName.isJSXIdentifier() || attrName.node.name !== "src") {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const value = attr.get("value");
|
|
104
|
+
if (!value.isJSXExpressionContainer()) return null;
|
|
105
|
+
|
|
106
|
+
const expression = value.get("expression");
|
|
107
|
+
if (!expression.isMemberExpression()) return null;
|
|
108
|
+
|
|
109
|
+
return this.extractFieldPath(expression, callbackParam);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
83
115
|
private extractFieldPathFromChild(
|
|
84
116
|
child: NodePath<t.JSXElement["children"][number]>,
|
|
85
117
|
callbackParam: string
|
|
@@ -96,6 +128,9 @@ export class StaticArrayProcessor {
|
|
|
96
128
|
expr: NodePath<t.MemberExpression>,
|
|
97
129
|
callbackParam: string
|
|
98
130
|
): string | null {
|
|
131
|
+
const keyedLookup = this.extractKeyedLookupFieldPath(expr, callbackParam);
|
|
132
|
+
if (keyedLookup) return keyedLookup;
|
|
133
|
+
|
|
99
134
|
const parts = this.collectMemberExpressionParts(expr);
|
|
100
135
|
if (!parts) return null;
|
|
101
136
|
|
|
@@ -103,6 +138,20 @@ export class StaticArrayProcessor {
|
|
|
103
138
|
return rootName === callbackParam ? propertyNames.join(".") : null;
|
|
104
139
|
}
|
|
105
140
|
|
|
141
|
+
private extractKeyedLookupFieldPath(
|
|
142
|
+
expr: NodePath<t.MemberExpression>,
|
|
143
|
+
callbackParam: string
|
|
144
|
+
): string | null {
|
|
145
|
+
const object = expr.get("object");
|
|
146
|
+
if (!expr.node.computed || !object.isIdentifier()) return null;
|
|
147
|
+
|
|
148
|
+
const property = expr.get("property");
|
|
149
|
+
if (!property.isMemberExpression()) return null;
|
|
150
|
+
|
|
151
|
+
const keyFieldPath = this.extractFieldPath(property, callbackParam);
|
|
152
|
+
return keyFieldPath ? `${object.node.name}[${keyFieldPath}]` : null;
|
|
153
|
+
}
|
|
154
|
+
|
|
106
155
|
private collectMemberExpressionParts(
|
|
107
156
|
expr: NodePath<t.MemberExpression>
|
|
108
157
|
): { rootName: string; propertyNames: string[] } | null {
|
|
@@ -156,7 +205,7 @@ export class StaticArrayProcessor {
|
|
|
156
205
|
|
|
157
206
|
private findParentArrayMap(
|
|
158
207
|
path: NodePath<t.JSXOpeningElement>,
|
|
159
|
-
maxDepth: number =
|
|
208
|
+
maxDepth: number = MAX_JSX_DEPTH
|
|
160
209
|
): ArrayMapInfo | null {
|
|
161
210
|
let currentPath: NodePath = path;
|
|
162
211
|
let depth = 0;
|