@base44/vite-plugin 0.2.26 → 0.2.28
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 +3 -0
- package/dist/capabilities/inline-edit/controller.d.ts.map +1 -0
- package/dist/capabilities/inline-edit/controller.js +200 -0
- package/dist/capabilities/inline-edit/controller.js.map +1 -0
- package/dist/capabilities/inline-edit/dom-utils.d.ts +7 -0
- package/dist/capabilities/inline-edit/dom-utils.d.ts.map +1 -0
- package/dist/capabilities/inline-edit/dom-utils.js +59 -0
- package/dist/capabilities/inline-edit/dom-utils.js.map +1 -0
- package/dist/capabilities/inline-edit/index.d.ts +3 -0
- package/dist/capabilities/inline-edit/index.d.ts.map +1 -0
- package/dist/capabilities/inline-edit/index.js +2 -0
- package/dist/capabilities/inline-edit/index.js.map +1 -0
- package/dist/capabilities/inline-edit/types.d.ts +25 -0
- package/dist/capabilities/inline-edit/types.d.ts.map +1 -0
- package/dist/capabilities/inline-edit/types.js +2 -0
- package/dist/capabilities/inline-edit/types.js.map +1 -0
- package/dist/injections/visual-edit-agent.d.ts.map +1 -1
- package/dist/injections/visual-edit-agent.js +86 -16
- package/dist/injections/visual-edit-agent.js.map +1 -1
- package/dist/statics/index.mjs +5 -1
- package/dist/statics/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/capabilities/inline-edit/controller.ts +251 -0
- package/src/capabilities/inline-edit/dom-utils.ts +58 -0
- package/src/capabilities/inline-edit/index.ts +2 -0
- package/src/capabilities/inline-edit/types.ts +30 -0
- package/src/injections/visual-edit-agent.ts +105 -16
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../src/capabilities/inline-edit/controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAWvE,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,cAAc,GACnB,oBAAoB,CA6OtB"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { injectFocusOutlineCSS, removeFocusOutlineCSS, selectText, shouldEnterInlineEditingMode, isStaticArrayTextElement, } from "./dom-utils.js";
|
|
2
|
+
const DEBOUNCE_MS = 500;
|
|
3
|
+
export function createInlineEditController(host) {
|
|
4
|
+
let currentEditingElement = null;
|
|
5
|
+
let debouncedSendTimeout = null;
|
|
6
|
+
let enabled = false;
|
|
7
|
+
const listenerAbortControllers = new WeakMap();
|
|
8
|
+
// --- Private helpers ---
|
|
9
|
+
const repositionOverlays = () => {
|
|
10
|
+
const selectedId = host.getSelectedElementId();
|
|
11
|
+
if (!selectedId)
|
|
12
|
+
return;
|
|
13
|
+
const elements = host.findElementsById(selectedId);
|
|
14
|
+
const overlays = host.getSelectedOverlays();
|
|
15
|
+
overlays.forEach((overlay, i) => {
|
|
16
|
+
if (i < elements.length && elements[i]) {
|
|
17
|
+
host.positionOverlay(overlay, elements[i]);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
const reportEdit = (element) => {
|
|
22
|
+
const originalContent = element.dataset.originalTextContent;
|
|
23
|
+
const newContent = element.textContent;
|
|
24
|
+
const svgElement = element;
|
|
25
|
+
const rect = element.getBoundingClientRect();
|
|
26
|
+
const message = {
|
|
27
|
+
type: "inline-edit",
|
|
28
|
+
elementInfo: {
|
|
29
|
+
tagName: element.tagName,
|
|
30
|
+
classes: svgElement.className?.baseVal ||
|
|
31
|
+
element.className ||
|
|
32
|
+
"",
|
|
33
|
+
visualSelectorId: host.getSelectedElementId(),
|
|
34
|
+
content: newContent,
|
|
35
|
+
dataSourceLocation: element.dataset.sourceLocation,
|
|
36
|
+
isDynamicContent: element.dataset.dynamicContent === "true",
|
|
37
|
+
linenumber: element.dataset.linenumber,
|
|
38
|
+
filename: element.dataset.filename,
|
|
39
|
+
position: {
|
|
40
|
+
top: rect.top,
|
|
41
|
+
left: rect.left,
|
|
42
|
+
right: rect.right,
|
|
43
|
+
bottom: rect.bottom,
|
|
44
|
+
width: rect.width,
|
|
45
|
+
height: rect.height,
|
|
46
|
+
centerX: rect.left + rect.width / 2,
|
|
47
|
+
centerY: rect.top + rect.height / 2,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
originalContent,
|
|
51
|
+
newContent,
|
|
52
|
+
};
|
|
53
|
+
if (isStaticArrayTextElement(element)) {
|
|
54
|
+
message.arrIndex = element.dataset.arrIndex;
|
|
55
|
+
message.arrVariableName = element.dataset.arrVariableName;
|
|
56
|
+
message.arrField = element.dataset.arrField;
|
|
57
|
+
}
|
|
58
|
+
window.parent.postMessage(message, "*");
|
|
59
|
+
element.dataset.originalTextContent = newContent || "";
|
|
60
|
+
};
|
|
61
|
+
const debouncedReport = (element) => {
|
|
62
|
+
if (debouncedSendTimeout)
|
|
63
|
+
clearTimeout(debouncedSendTimeout);
|
|
64
|
+
debouncedSendTimeout = setTimeout(() => reportEdit(element), DEBOUNCE_MS);
|
|
65
|
+
};
|
|
66
|
+
const onTextInput = (element) => {
|
|
67
|
+
repositionOverlays();
|
|
68
|
+
debouncedReport(element);
|
|
69
|
+
};
|
|
70
|
+
const handleInputEvent = function () {
|
|
71
|
+
onTextInput(this);
|
|
72
|
+
};
|
|
73
|
+
const makeEditable = (element) => {
|
|
74
|
+
injectFocusOutlineCSS();
|
|
75
|
+
element.dataset.originalTextContent = element.textContent || "";
|
|
76
|
+
element.dataset.originalCursor = element.style.cursor;
|
|
77
|
+
element.contentEditable = "true";
|
|
78
|
+
const abortController = new AbortController();
|
|
79
|
+
listenerAbortControllers.set(element, abortController);
|
|
80
|
+
element.addEventListener("input", handleInputEvent, {
|
|
81
|
+
signal: abortController.signal,
|
|
82
|
+
});
|
|
83
|
+
element.style.cursor = "text";
|
|
84
|
+
selectText(element);
|
|
85
|
+
setTimeout(() => {
|
|
86
|
+
if (element.isConnected) {
|
|
87
|
+
element.focus();
|
|
88
|
+
}
|
|
89
|
+
}, 0);
|
|
90
|
+
};
|
|
91
|
+
const makeNonEditable = (element) => {
|
|
92
|
+
const abortController = listenerAbortControllers.get(element);
|
|
93
|
+
if (abortController) {
|
|
94
|
+
abortController.abort();
|
|
95
|
+
listenerAbortControllers.delete(element);
|
|
96
|
+
}
|
|
97
|
+
if (!element.isConnected)
|
|
98
|
+
return;
|
|
99
|
+
removeFocusOutlineCSS();
|
|
100
|
+
element.contentEditable = "false";
|
|
101
|
+
delete element.dataset.originalTextContent;
|
|
102
|
+
if (element.dataset.originalCursor !== undefined) {
|
|
103
|
+
element.style.cursor = element.dataset.originalCursor;
|
|
104
|
+
delete element.dataset.originalCursor;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
// --- Public API ---
|
|
108
|
+
return {
|
|
109
|
+
get enabled() {
|
|
110
|
+
return enabled;
|
|
111
|
+
},
|
|
112
|
+
set enabled(value) {
|
|
113
|
+
enabled = value;
|
|
114
|
+
},
|
|
115
|
+
isEditing() {
|
|
116
|
+
return currentEditingElement !== null;
|
|
117
|
+
},
|
|
118
|
+
getCurrentElement() {
|
|
119
|
+
return currentEditingElement;
|
|
120
|
+
},
|
|
121
|
+
canEdit(element) {
|
|
122
|
+
return shouldEnterInlineEditingMode(element);
|
|
123
|
+
},
|
|
124
|
+
startEditing(element) {
|
|
125
|
+
currentEditingElement = element;
|
|
126
|
+
host.getSelectedOverlays().forEach((o) => {
|
|
127
|
+
o.style.display = "none";
|
|
128
|
+
});
|
|
129
|
+
makeEditable(element);
|
|
130
|
+
window.parent.postMessage({
|
|
131
|
+
type: "content-editing-started",
|
|
132
|
+
visualSelectorId: host.getSelectedElementId(),
|
|
133
|
+
}, "*");
|
|
134
|
+
},
|
|
135
|
+
stopEditing() {
|
|
136
|
+
if (!currentEditingElement)
|
|
137
|
+
return;
|
|
138
|
+
if (debouncedSendTimeout) {
|
|
139
|
+
clearTimeout(debouncedSendTimeout);
|
|
140
|
+
debouncedSendTimeout = null;
|
|
141
|
+
}
|
|
142
|
+
const element = currentEditingElement;
|
|
143
|
+
makeNonEditable(element);
|
|
144
|
+
host.getSelectedOverlays().forEach((o) => {
|
|
145
|
+
o.style.display = "";
|
|
146
|
+
});
|
|
147
|
+
repositionOverlays();
|
|
148
|
+
window.parent.postMessage({
|
|
149
|
+
type: "content-editing-ended",
|
|
150
|
+
visualSelectorId: host.getSelectedElementId(),
|
|
151
|
+
}, "*");
|
|
152
|
+
currentEditingElement = null;
|
|
153
|
+
},
|
|
154
|
+
markElementsSelected(elements) {
|
|
155
|
+
elements.forEach((el) => {
|
|
156
|
+
if (el instanceof HTMLElement) {
|
|
157
|
+
el.dataset.selected = "true";
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
},
|
|
161
|
+
clearSelectedMarks(elementId) {
|
|
162
|
+
if (!elementId)
|
|
163
|
+
return;
|
|
164
|
+
host.findElementsById(elementId).forEach((el) => {
|
|
165
|
+
if (el instanceof HTMLElement) {
|
|
166
|
+
delete el.dataset.selected;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
},
|
|
170
|
+
handleToggleMessage(data) {
|
|
171
|
+
if (!enabled)
|
|
172
|
+
return;
|
|
173
|
+
const elements = host.findElementsById(data.dataSourceLocation);
|
|
174
|
+
if (elements.length === 0 || !(elements[0] instanceof HTMLElement))
|
|
175
|
+
return;
|
|
176
|
+
const element = elements[0];
|
|
177
|
+
if (data.inlineEditingMode) {
|
|
178
|
+
if (!shouldEnterInlineEditingMode(element))
|
|
179
|
+
return;
|
|
180
|
+
// Select the element first if not already selected
|
|
181
|
+
if (host.getSelectedElementId() !== data.dataSourceLocation) {
|
|
182
|
+
this.stopEditing();
|
|
183
|
+
host.clearSelection();
|
|
184
|
+
this.markElementsSelected(elements);
|
|
185
|
+
host.createSelectionOverlays(elements, data.dataSourceLocation);
|
|
186
|
+
}
|
|
187
|
+
this.startEditing(element);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
if (currentEditingElement === element) {
|
|
191
|
+
this.stopEditing();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
cleanup() {
|
|
196
|
+
this.stopEditing();
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../../../src/capabilities/inline-edit/controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const isStaticArrayTextElement: (element: HTMLElement) => boolean;
|
|
2
|
+
export declare const injectFocusOutlineCSS: () => void;
|
|
3
|
+
export declare const removeFocusOutlineCSS: () => void;
|
|
4
|
+
export declare const selectText: (element: HTMLElement) => void;
|
|
5
|
+
export declare const isEditableTextElement: (element: Element) => boolean;
|
|
6
|
+
export declare const shouldEnterInlineEditingMode: (element: Element) => boolean;
|
|
7
|
+
//# sourceMappingURL=dom-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom-utils.d.ts","sourceRoot":"","sources":["../../../src/capabilities/inline-edit/dom-utils.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,wBAAwB,GAAI,SAAS,WAAW,KAAG,OAE/D,CAAC;AAUF,eAAO,MAAM,qBAAqB,YAWjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,YAEjC,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,SAAS,WAAW,SAM9C,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,SAAS,OAAO,KAAG,OAMxD,CAAC;AAEF,eAAO,MAAM,4BAA4B,GAAI,SAAS,OAAO,KAAG,OAK/D,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const FOCUS_STYLE_ID = "visual-edit-focus-styles";
|
|
2
|
+
const EDITABLE_TAGS = [
|
|
3
|
+
"div", "p", "h1", "h2", "h3", "h4", "h5", "h6",
|
|
4
|
+
"span", "li", "td", "a", "button", "label",
|
|
5
|
+
];
|
|
6
|
+
export const isStaticArrayTextElement = (element) => {
|
|
7
|
+
return !!element.dataset.arrField;
|
|
8
|
+
};
|
|
9
|
+
const passesStructuralChecks = (element) => {
|
|
10
|
+
if (!EDITABLE_TAGS.includes(element.tagName.toLowerCase()))
|
|
11
|
+
return false;
|
|
12
|
+
if (!element.textContent?.trim())
|
|
13
|
+
return false;
|
|
14
|
+
if (element.querySelector("img, video, canvas, svg"))
|
|
15
|
+
return false;
|
|
16
|
+
if (element.children?.length > 0)
|
|
17
|
+
return false;
|
|
18
|
+
return true;
|
|
19
|
+
};
|
|
20
|
+
export const injectFocusOutlineCSS = () => {
|
|
21
|
+
if (document.getElementById(FOCUS_STYLE_ID))
|
|
22
|
+
return;
|
|
23
|
+
const style = document.createElement("style");
|
|
24
|
+
style.id = FOCUS_STYLE_ID;
|
|
25
|
+
style.textContent = `
|
|
26
|
+
[data-selected="true"][contenteditable="true"]:focus {
|
|
27
|
+
outline: none !important;
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
30
|
+
document.head.appendChild(style);
|
|
31
|
+
};
|
|
32
|
+
export const removeFocusOutlineCSS = () => {
|
|
33
|
+
document.getElementById(FOCUS_STYLE_ID)?.remove();
|
|
34
|
+
};
|
|
35
|
+
export const selectText = (element) => {
|
|
36
|
+
const range = document.createRange();
|
|
37
|
+
range.selectNodeContents(element);
|
|
38
|
+
const selection = window.getSelection();
|
|
39
|
+
selection?.removeAllRanges();
|
|
40
|
+
selection?.addRange(range);
|
|
41
|
+
};
|
|
42
|
+
export const isEditableTextElement = (element) => {
|
|
43
|
+
if (!(element instanceof HTMLElement))
|
|
44
|
+
return false;
|
|
45
|
+
if (!passesStructuralChecks(element))
|
|
46
|
+
return false;
|
|
47
|
+
if (isStaticArrayTextElement(element))
|
|
48
|
+
return true;
|
|
49
|
+
if (element.dataset.dynamicContent === "true")
|
|
50
|
+
return false;
|
|
51
|
+
return true;
|
|
52
|
+
};
|
|
53
|
+
export const shouldEnterInlineEditingMode = (element) => {
|
|
54
|
+
if (!(element instanceof HTMLElement) || element.dataset.selected !== "true") {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
return isEditableTextElement(element);
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=dom-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom-utils.js","sourceRoot":"","sources":["../../../src/capabilities/inline-edit/dom-utils.ts"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAAG,0BAA0B,CAAC;AAElD,MAAM,aAAa,GAAG;IACpB,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAC9C,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO;CAC3C,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,OAAoB,EAAW,EAAE;IACxE,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC;AACpC,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,CAAC,OAAoB,EAAW,EAAE;IAC/D,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IACzE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE;QAAE,OAAO,KAAK,CAAC;IAC/C,IAAI,OAAO,CAAC,aAAa,CAAC,yBAAyB,CAAC;QAAE,OAAO,KAAK,CAAC;IACnE,IAAI,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACxC,IAAI,QAAQ,CAAC,cAAc,CAAC,cAAc,CAAC;QAAE,OAAO;IAEpD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,GAAG,cAAc,CAAC;IAC1B,KAAK,CAAC,WAAW,GAAG;;;;GAInB,CAAC;IACF,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACxC,QAAQ,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;AACpD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAoB,EAAE,EAAE;IACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,KAAK,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;IACxC,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAAgB,EAAW,EAAE;IACjE,IAAI,CAAC,CAAC,OAAO,YAAY,WAAW,CAAC;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACnD,IAAI,wBAAwB,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,OAAO,CAAC,OAAO,CAAC,cAAc,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,OAAgB,EAAW,EAAE;IACxE,IAAI,CAAC,CAAC,OAAO,YAAY,WAAW,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;QAC7E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/capabilities/inline-edit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAC7D,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/capabilities/inline-edit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface InlineEditHost {
|
|
2
|
+
findElementsById(id: string | null): Element[];
|
|
3
|
+
getSelectedElementId(): string | null;
|
|
4
|
+
getSelectedOverlays(): HTMLDivElement[];
|
|
5
|
+
positionOverlay(overlay: HTMLDivElement, element: Element, isSelected?: boolean): void;
|
|
6
|
+
clearSelection(): void;
|
|
7
|
+
createSelectionOverlays(elements: Element[], elementId: string): void;
|
|
8
|
+
}
|
|
9
|
+
export interface ToggleInlineEditData {
|
|
10
|
+
dataSourceLocation: string;
|
|
11
|
+
inlineEditingMode: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface InlineEditController {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
isEditing(): boolean;
|
|
16
|
+
getCurrentElement(): HTMLElement | null;
|
|
17
|
+
canEdit(element: Element): boolean;
|
|
18
|
+
startEditing(element: HTMLElement): void;
|
|
19
|
+
stopEditing(): void;
|
|
20
|
+
markElementsSelected(elements: Element[]): void;
|
|
21
|
+
clearSelectedMarks(elementId: string | null): void;
|
|
22
|
+
handleToggleMessage(data: ToggleInlineEditData): void;
|
|
23
|
+
cleanup(): void;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/capabilities/inline-edit/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,EAAE,CAAC;IAC/C,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAAC;IACtC,mBAAmB,IAAI,cAAc,EAAE,CAAC;IACxC,eAAe,CACb,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE,OAAO,GACnB,IAAI,CAAC;IACR,cAAc,IAAI,IAAI,CAAC;IACvB,uBAAuB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACvE;AAED,MAAM,WAAW,oBAAoB;IACnC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,IAAI,OAAO,CAAC;IACrB,iBAAiB,IAAI,WAAW,GAAG,IAAI,CAAC;IACxC,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;IACnC,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IACzC,WAAW,IAAI,IAAI,CAAC;IACpB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACnD,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtD,OAAO,IAAI,IAAI,CAAC;CACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/capabilities/inline-edit/types.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"visual-edit-agent.d.ts","sourceRoot":"","sources":["../../src/injections/visual-edit-agent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"visual-edit-agent.d.ts","sourceRoot":"","sources":["../../src/injections/visual-edit-agent.ts"],"names":[],"mappings":"AAKA,wBAAgB,oBAAoB,SAosBnC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { findElementsById, updateElementClasses, updateElementAttribute, collectAllowedAttributes, ALLOWED_ATTRIBUTES, getElementSelectorId } from "./utils.js";
|
|
2
2
|
import { createLayerController } from "./layer-dropdown/controller.js";
|
|
3
3
|
import { LAYER_DROPDOWN_ATTR } from "./layer-dropdown/consts.js";
|
|
4
|
+
import { createInlineEditController } from "../capabilities/inline-edit/index.js";
|
|
4
5
|
export function setupVisualEditAgent() {
|
|
5
6
|
// State variables (replacing React useState/useRef)
|
|
6
7
|
let isVisualEditMode = false;
|
|
@@ -10,6 +11,7 @@ export function setupVisualEditAgent() {
|
|
|
10
11
|
let selectedOverlays = [];
|
|
11
12
|
let currentHighlightedElements = [];
|
|
12
13
|
let selectedElementId = null;
|
|
14
|
+
const REPOSITION_DELAY_MS = 50;
|
|
13
15
|
// Create overlay element
|
|
14
16
|
const createOverlay = (isSelected = false) => {
|
|
15
17
|
const overlay = document.createElement("div");
|
|
@@ -57,6 +59,32 @@ export function setupVisualEditAgent() {
|
|
|
57
59
|
overlay.appendChild(label);
|
|
58
60
|
}
|
|
59
61
|
};
|
|
62
|
+
// --- Inline edit controller ---
|
|
63
|
+
const inlineEdit = createInlineEditController({
|
|
64
|
+
findElementsById,
|
|
65
|
+
getSelectedElementId: () => selectedElementId,
|
|
66
|
+
getSelectedOverlays: () => selectedOverlays,
|
|
67
|
+
positionOverlay,
|
|
68
|
+
clearSelection: () => {
|
|
69
|
+
inlineEdit.clearSelectedMarks(selectedElementId);
|
|
70
|
+
clearSelectedOverlays();
|
|
71
|
+
selectedElementId = null;
|
|
72
|
+
},
|
|
73
|
+
createSelectionOverlays: (elements, elementId) => {
|
|
74
|
+
elements.forEach((el) => {
|
|
75
|
+
const overlay = createOverlay(true);
|
|
76
|
+
document.body.appendChild(overlay);
|
|
77
|
+
selectedOverlays.push(overlay);
|
|
78
|
+
positionOverlay(overlay, el, true);
|
|
79
|
+
});
|
|
80
|
+
selectedElementId = elementId;
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
const clearSelection = () => {
|
|
84
|
+
inlineEdit.clearSelectedMarks(selectedElementId);
|
|
85
|
+
clearSelectedOverlays();
|
|
86
|
+
selectedElementId = null;
|
|
87
|
+
};
|
|
60
88
|
// Clear hover overlays
|
|
61
89
|
const clearHoverOverlays = () => {
|
|
62
90
|
hoverOverlays.forEach((overlay) => {
|
|
@@ -81,6 +109,11 @@ export function setupVisualEditAgent() {
|
|
|
81
109
|
const rect = element.getBoundingClientRect();
|
|
82
110
|
const svgElement = element;
|
|
83
111
|
const isTextElement = TEXT_TAGS.includes(element.tagName?.toLowerCase());
|
|
112
|
+
const arrEl = htmlElement.closest("[data-arr-variable-name]");
|
|
113
|
+
const staticArrayName = arrEl?.dataset?.arrVariableName || null;
|
|
114
|
+
const rawIdx = arrEl?.dataset?.arrIndex;
|
|
115
|
+
const staticArrayIndex = rawIdx != null ? parseInt(rawIdx, 10) : null;
|
|
116
|
+
const staticArrayField = htmlElement.dataset?.arrField || null;
|
|
84
117
|
window.parent.postMessage({
|
|
85
118
|
type: "element-selected",
|
|
86
119
|
tagName: element.tagName,
|
|
@@ -105,6 +138,9 @@ export function setupVisualEditAgent() {
|
|
|
105
138
|
},
|
|
106
139
|
attributes: collectAllowedAttributes(element, ALLOWED_ATTRIBUTES),
|
|
107
140
|
isTextElement,
|
|
141
|
+
staticArrayName,
|
|
142
|
+
staticArrayIndex,
|
|
143
|
+
staticArrayField,
|
|
108
144
|
}, "*");
|
|
109
145
|
};
|
|
110
146
|
// Select an element: create overlays, update state, notify parent
|
|
@@ -129,7 +165,7 @@ export function setupVisualEditAgent() {
|
|
|
129
165
|
};
|
|
130
166
|
// Handle mouse over event
|
|
131
167
|
const handleMouseOver = (e) => {
|
|
132
|
-
if (!isVisualEditMode || isPopoverDragging)
|
|
168
|
+
if (!isVisualEditMode || isPopoverDragging || inlineEdit.isEditing())
|
|
133
169
|
return;
|
|
134
170
|
const target = e.target;
|
|
135
171
|
// Prevent hover effects when a dropdown is open
|
|
@@ -184,6 +220,19 @@ export function setupVisualEditAgent() {
|
|
|
184
220
|
// Let layer dropdown clicks pass through without interference
|
|
185
221
|
if (target.closest(`[${LAYER_DROPDOWN_ATTR}]`))
|
|
186
222
|
return;
|
|
223
|
+
// Let clicks inside the editable element pass through to the browser
|
|
224
|
+
// so the user can reposition the cursor and select text naturally.
|
|
225
|
+
if (inlineEdit.enabled && target instanceof HTMLElement && target.contentEditable === "true") {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
// Clicking outside the editable element exits inline editing mode.
|
|
229
|
+
if (inlineEdit.isEditing()) {
|
|
230
|
+
e.preventDefault();
|
|
231
|
+
e.stopPropagation();
|
|
232
|
+
e.stopImmediatePropagation();
|
|
233
|
+
inlineEdit.stopEditing();
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
187
236
|
// Close dropdowns when clicking anywhere in iframe if a dropdown is open
|
|
188
237
|
if (isDropdownOpen) {
|
|
189
238
|
e.preventDefault();
|
|
@@ -205,13 +254,24 @@ export function setupVisualEditAgent() {
|
|
|
205
254
|
if (!element) {
|
|
206
255
|
return;
|
|
207
256
|
}
|
|
257
|
+
const htmlElement = element;
|
|
258
|
+
const visualSelectorId = getElementSelectorId(element);
|
|
259
|
+
const isAlreadySelected = selectedElementId === visualSelectorId &&
|
|
260
|
+
htmlElement.dataset.selected === "true";
|
|
261
|
+
if (isAlreadySelected && inlineEdit.enabled && inlineEdit.canEdit(htmlElement)) {
|
|
262
|
+
inlineEdit.startEditing(htmlElement);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
inlineEdit.stopEditing();
|
|
266
|
+
if (inlineEdit.enabled) {
|
|
267
|
+
inlineEdit.markElementsSelected(findElementsById(visualSelectorId));
|
|
268
|
+
}
|
|
208
269
|
const selectedOverlay = selectElement(element);
|
|
209
270
|
layerController.attachToOverlay(selectedOverlay, element);
|
|
210
271
|
};
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
selectedElementId = null;
|
|
272
|
+
const unselectElement = () => {
|
|
273
|
+
inlineEdit.stopEditing();
|
|
274
|
+
clearSelection();
|
|
215
275
|
};
|
|
216
276
|
const updateElementClassesAndReposition = (visualSelectorId, classes) => {
|
|
217
277
|
const elements = findElementsById(visualSelectorId);
|
|
@@ -240,7 +300,7 @@ export function setupVisualEditAgent() {
|
|
|
240
300
|
});
|
|
241
301
|
}
|
|
242
302
|
}
|
|
243
|
-
},
|
|
303
|
+
}, REPOSITION_DELAY_MS);
|
|
244
304
|
};
|
|
245
305
|
// Update element attribute by visual selector ID
|
|
246
306
|
const updateElementAttributeAndReposition = (visualSelectorId, attribute, value) => {
|
|
@@ -257,14 +317,16 @@ export function setupVisualEditAgent() {
|
|
|
257
317
|
}
|
|
258
318
|
});
|
|
259
319
|
}
|
|
260
|
-
},
|
|
320
|
+
}, REPOSITION_DELAY_MS);
|
|
261
321
|
};
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
const elements = findElementsById(visualSelectorId);
|
|
322
|
+
const updateElementContent = (visualSelectorId, content, arrIndex) => {
|
|
323
|
+
let elements = findElementsById(visualSelectorId);
|
|
265
324
|
if (elements.length === 0) {
|
|
266
325
|
return;
|
|
267
326
|
}
|
|
327
|
+
if (arrIndex != null) {
|
|
328
|
+
elements = elements.filter((el) => el.dataset.arrIndex === String(arrIndex));
|
|
329
|
+
}
|
|
268
330
|
elements.forEach((element) => {
|
|
269
331
|
element.innerText = content;
|
|
270
332
|
});
|
|
@@ -276,7 +338,7 @@ export function setupVisualEditAgent() {
|
|
|
276
338
|
}
|
|
277
339
|
});
|
|
278
340
|
}
|
|
279
|
-
},
|
|
341
|
+
}, REPOSITION_DELAY_MS);
|
|
280
342
|
};
|
|
281
343
|
// --- Layer dropdown controller ---
|
|
282
344
|
const layerController = createLayerController({
|
|
@@ -295,11 +357,11 @@ export function setupVisualEditAgent() {
|
|
|
295
357
|
const toggleVisualEditMode = (isEnabled) => {
|
|
296
358
|
isVisualEditMode = isEnabled;
|
|
297
359
|
if (!isEnabled) {
|
|
360
|
+
inlineEdit.stopEditing();
|
|
361
|
+
clearSelection();
|
|
298
362
|
layerController.cleanup();
|
|
299
363
|
clearHoverOverlays();
|
|
300
|
-
clearSelectedOverlays();
|
|
301
364
|
currentHighlightedElements = [];
|
|
302
|
-
selectedElementId = null;
|
|
303
365
|
document.body.style.cursor = "default";
|
|
304
366
|
document.removeEventListener("mouseover", handleMouseOver);
|
|
305
367
|
document.removeEventListener("mouseout", handleMouseOut);
|
|
@@ -350,6 +412,9 @@ export function setupVisualEditAgent() {
|
|
|
350
412
|
switch (message.type) {
|
|
351
413
|
case "toggle-visual-edit-mode":
|
|
352
414
|
toggleVisualEditMode(message.data.enabled);
|
|
415
|
+
if (message.data.specs?.newInlineEditEnabled !== undefined) {
|
|
416
|
+
inlineEdit.enabled = message.data.specs.newInlineEditEnabled;
|
|
417
|
+
}
|
|
353
418
|
break;
|
|
354
419
|
case "update-classes":
|
|
355
420
|
if (message.data && message.data.classes !== undefined) {
|
|
@@ -371,14 +436,14 @@ export function setupVisualEditAgent() {
|
|
|
371
436
|
}
|
|
372
437
|
break;
|
|
373
438
|
case "unselect-element":
|
|
374
|
-
|
|
439
|
+
unselectElement();
|
|
375
440
|
break;
|
|
376
441
|
case "refresh-page":
|
|
377
442
|
window.location.reload();
|
|
378
443
|
break;
|
|
379
444
|
case "update-content":
|
|
380
445
|
if (message.data && message.data.content !== undefined) {
|
|
381
|
-
updateElementContent(message.data.visualSelectorId, message.data.content);
|
|
446
|
+
updateElementContent(message.data.visualSelectorId, message.data.content, message.data.arrIndex);
|
|
382
447
|
}
|
|
383
448
|
else {
|
|
384
449
|
console.warn("[VisualEditAgent] Invalid update-content message:", message);
|
|
@@ -431,6 +496,11 @@ export function setupVisualEditAgent() {
|
|
|
431
496
|
}
|
|
432
497
|
}
|
|
433
498
|
break;
|
|
499
|
+
case "toggle-inline-edit-mode":
|
|
500
|
+
if (message.data) {
|
|
501
|
+
inlineEdit.handleToggleMessage(message.data);
|
|
502
|
+
}
|
|
503
|
+
break;
|
|
434
504
|
default:
|
|
435
505
|
break;
|
|
436
506
|
}
|
|
@@ -485,7 +555,7 @@ export function setupVisualEditAgent() {
|
|
|
485
555
|
return isLayoutChange && hasVisualId(mutation.target);
|
|
486
556
|
});
|
|
487
557
|
if (needsUpdate) {
|
|
488
|
-
setTimeout(handleResize,
|
|
558
|
+
setTimeout(handleResize, REPOSITION_DELAY_MS);
|
|
489
559
|
}
|
|
490
560
|
});
|
|
491
561
|
// Set up event listeners
|