@upstart.gg/vite-plugins 0.1.40 → 0.1.42
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/upstart-editor-api.d.ts +59 -1
- package/dist/upstart-editor-api.d.ts.map +1 -1
- package/dist/upstart-editor-api.js +273 -4
- package/dist/upstart-editor-api.js.map +1 -1
- package/dist/vite-plugin-upstart-attrs.d.ts +2 -1
- package/dist/vite-plugin-upstart-attrs.d.ts.map +1 -1
- package/dist/vite-plugin-upstart-attrs.js +91 -4
- package/dist/vite-plugin-upstart-attrs.js.map +1 -1
- package/dist/vite-plugin-upstart-editor/runtime/array-controls.js +342 -0
- package/dist/vite-plugin-upstart-editor/runtime/array-controls.js.map +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/click-handler.d.ts.map +1 -1
- package/dist/vite-plugin-upstart-editor/runtime/click-handler.js +29 -2
- package/dist/vite-plugin-upstart-editor/runtime/click-handler.js.map +1 -1
- package/dist/vite-plugin-upstart-editor/runtime/form-guard.js +80 -0
- package/dist/vite-plugin-upstart-editor/runtime/form-guard.js.map +1 -0
- package/dist/vite-plugin-upstart-editor/runtime/hover-overlay.d.ts.map +1 -1
- package/dist/vite-plugin-upstart-editor/runtime/hover-overlay.js +2 -1
- package/dist/vite-plugin-upstart-editor/runtime/hover-overlay.js.map +1 -1
- package/dist/vite-plugin-upstart-editor/runtime/index.d.ts.map +1 -1
- package/dist/vite-plugin-upstart-editor/runtime/index.js +26 -4
- package/dist/vite-plugin-upstart-editor/runtime/index.js.map +1 -1
- package/dist/vite-plugin-upstart-editor/runtime/text-editor.d.ts.map +1 -1
- package/dist/vite-plugin-upstart-editor/runtime/text-editor.js +40 -36
- package/dist/vite-plugin-upstart-editor/runtime/text-editor.js.map +1 -1
- package/dist/vite-plugin-upstart-editor/runtime/types.d.ts +20 -4
- package/dist/vite-plugin-upstart-editor/runtime/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/tests/vite-plugin-upstart-attrs.test.ts +412 -0
- package/src/upstart-editor-api.ts +314 -5
- package/src/vite-plugin-upstart-attrs.ts +154 -4
- package/src/vite-plugin-upstart-editor/runtime/array-controls.ts +478 -0
- package/src/vite-plugin-upstart-editor/runtime/click-handler.ts +43 -0
- package/src/vite-plugin-upstart-editor/runtime/form-guard.ts +121 -0
- package/src/vite-plugin-upstart-editor/runtime/hover-overlay.ts +6 -1
- package/src/vite-plugin-upstart-editor/runtime/index.ts +20 -4
- package/src/vite-plugin-upstart-editor/runtime/text-editor.ts +49 -58
- package/src/vite-plugin-upstart-editor/runtime/types.ts +31 -4
|
@@ -2,6 +2,8 @@ import { initClickHandler } from "./click-handler.js";
|
|
|
2
2
|
import { initHoverOverlay, hideOverlays } from "./hover-overlay.js";
|
|
3
3
|
import { initErrorHandler } from "./error-handler.js";
|
|
4
4
|
import { initTextEditor, activateAllEditors, destroyAllActiveEditors } from "./text-editor.js";
|
|
5
|
+
import { initArrayControls, refreshArrayControls, hideArrayControls } from "./array-controls.js";
|
|
6
|
+
import { initFormGuard } from "./form-guard.js";
|
|
5
7
|
import { sendToParent } from "./utils.js";
|
|
6
8
|
import { getCurrentMode, setCurrentMode } from "./state.js";
|
|
7
9
|
import type { EditorMode, UpstartParentMessage } from "./types.js";
|
|
@@ -71,19 +73,24 @@ export function initUpstartEditor(): void {
|
|
|
71
73
|
|
|
72
74
|
window.addEventListener("message", handleParentMessage);
|
|
73
75
|
|
|
76
|
+
// Current path (pathname + search), reported to the parent so it can reload
|
|
77
|
+
// the iframe on the page being viewed instead of always the home page.
|
|
78
|
+
const currentPath = () => location.pathname + location.search;
|
|
79
|
+
|
|
74
80
|
// Notify parent on SPA navigation so it can resend the current editMode
|
|
81
|
+
// and track the current page for the next reload.
|
|
75
82
|
window.addEventListener("popstate", () => {
|
|
76
|
-
sendToParent({ type: "editor-navigated" });
|
|
83
|
+
sendToParent({ type: "editor-navigated", path: currentPath() });
|
|
77
84
|
});
|
|
78
85
|
const originalPushState = history.pushState.bind(history);
|
|
79
86
|
history.pushState = (...args) => {
|
|
80
87
|
originalPushState(...args);
|
|
81
|
-
sendToParent({ type: "editor-navigated" });
|
|
88
|
+
sendToParent({ type: "editor-navigated", path: currentPath() });
|
|
82
89
|
};
|
|
83
90
|
const originalReplaceState = history.replaceState.bind(history);
|
|
84
91
|
history.replaceState = (...args) => {
|
|
85
92
|
originalReplaceState(...args);
|
|
86
|
-
sendToParent({ type: "editor-navigated" });
|
|
93
|
+
sendToParent({ type: "editor-navigated", path: currentPath() });
|
|
87
94
|
};
|
|
88
95
|
|
|
89
96
|
// i18next integration: if the app exposes it on window.__i18next (set before hydration),
|
|
@@ -97,9 +104,11 @@ export function initUpstartEditor(): void {
|
|
|
97
104
|
initTextEditor(getRawI18nTemplate ? { getRawI18nTemplate } : {});
|
|
98
105
|
initClickHandler();
|
|
99
106
|
initHoverOverlay();
|
|
107
|
+
initArrayControls();
|
|
108
|
+
initFormGuard();
|
|
100
109
|
initErrorHandler();
|
|
101
110
|
|
|
102
|
-
sendToParent({ type: "editor-ready" });
|
|
111
|
+
sendToParent({ type: "editor-ready", path: currentPath() });
|
|
103
112
|
} catch (error) {
|
|
104
113
|
console.error("[Upstart Editor] Initialization failed:", error);
|
|
105
114
|
sendToParent({
|
|
@@ -152,6 +161,11 @@ function handleParentMessage(event: MessageEvent): void {
|
|
|
152
161
|
} else if (styleEl) {
|
|
153
162
|
styleEl.textContent = "";
|
|
154
163
|
}
|
|
164
|
+
} else if (message.type === "preview-image") {
|
|
165
|
+
const el = document.querySelector<HTMLImageElement>(`[data-upstart-image-id="${message.imageId}"]`);
|
|
166
|
+
if (el) {
|
|
167
|
+
el.src = message.src;
|
|
168
|
+
}
|
|
155
169
|
} else if (message.type === "request-scroll-position") {
|
|
156
170
|
sendToParent({ type: "scroll-position", x: window.scrollX, y: window.scrollY });
|
|
157
171
|
} else if (message.type === "restore-scroll-position") {
|
|
@@ -163,6 +177,7 @@ function enableEditMode(): void {
|
|
|
163
177
|
console.log("[Upstart Editor] Edit mode enabled");
|
|
164
178
|
document.documentElement.setAttribute("data-upstart-edit-mode", "");
|
|
165
179
|
activateAllEditors();
|
|
180
|
+
refreshArrayControls();
|
|
166
181
|
}
|
|
167
182
|
|
|
168
183
|
function disableEditMode(): void {
|
|
@@ -170,6 +185,7 @@ function disableEditMode(): void {
|
|
|
170
185
|
document.documentElement.removeAttribute("data-upstart-edit-mode");
|
|
171
186
|
destroyAllActiveEditors();
|
|
172
187
|
hideOverlays();
|
|
188
|
+
hideArrayControls();
|
|
173
189
|
}
|
|
174
190
|
|
|
175
191
|
export { initTextEditor } from "./text-editor.js";
|
|
@@ -128,7 +128,11 @@ function buildI18nContent(rawTemplate: string, renderedText: string): object {
|
|
|
128
128
|
return { type: "doc", content: [{ type: "paragraph", content: inlineNodes }] };
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
// Keyed by the host DOM element, NOT by data-upstart-hash: a component rendered
|
|
132
|
+
// multiple times (e.g. a TimelineItem reused 4×) emits the same source-derived
|
|
133
|
+
// hash on every instance, so keying by hash would let only the first instance
|
|
134
|
+
// become editable. The element is the only per-instance unique identity.
|
|
135
|
+
const activeEditors = new Map<HTMLElement, EditorInstance>();
|
|
132
136
|
let i18nSyncInProgress = false;
|
|
133
137
|
const styleCache = new WeakMap<
|
|
134
138
|
HTMLElement,
|
|
@@ -185,6 +189,14 @@ function injectEditorStyles(): void {
|
|
|
185
189
|
"[data-upstart-editor-active] .ProseMirror:focus {",
|
|
186
190
|
" outline: none !important;",
|
|
187
191
|
"}",
|
|
192
|
+
// Single-line editors (plain/direct, e.g. array-item pills) render their text
|
|
193
|
+
// inside a ProseMirror <p>, which would otherwise pick up the browser's default
|
|
194
|
+
// paragraph margin and change the element's height when edit mode activates.
|
|
195
|
+
"[data-upstart-editor-active][data-upstart-editable-text-mode='plain'] .ProseMirror p,",
|
|
196
|
+
"[data-upstart-editor-active][data-upstart-editable-text-mode='direct'] .ProseMirror p {",
|
|
197
|
+
" margin: 0 !important;",
|
|
198
|
+
" padding: 0 !important;",
|
|
199
|
+
"}",
|
|
188
200
|
].join("\n");
|
|
189
201
|
document.head.appendChild(style);
|
|
190
202
|
}
|
|
@@ -210,14 +222,14 @@ export function activateAllEditors(): void {
|
|
|
210
222
|
*/
|
|
211
223
|
export function destroyAllActiveEditors(): void {
|
|
212
224
|
stopDomObserver();
|
|
213
|
-
for (const
|
|
214
|
-
destroyEditor(
|
|
225
|
+
for (const element of activeEditors.keys()) {
|
|
226
|
+
destroyEditor(element);
|
|
215
227
|
}
|
|
216
228
|
}
|
|
217
229
|
|
|
218
230
|
function setupEditableElement(element: HTMLElement, options: Required<UpstartEditorOptions>): void {
|
|
219
231
|
const hash = getEditableHash(element);
|
|
220
|
-
if (!hash || activeEditors.has(
|
|
232
|
+
if (!hash || activeEditors.has(element)) {
|
|
221
233
|
return;
|
|
222
234
|
}
|
|
223
235
|
|
|
@@ -232,19 +244,19 @@ function activateEditor(element: HTMLElement, hash: string, options: Required<Up
|
|
|
232
244
|
|
|
233
245
|
switch (mode) {
|
|
234
246
|
case "direct":
|
|
235
|
-
editor = createDirectEditor(element,
|
|
247
|
+
editor = createDirectEditor(element, options);
|
|
236
248
|
break;
|
|
237
249
|
case "rich-panel":
|
|
238
|
-
editor = createRichPanelEditor(element,
|
|
250
|
+
editor = createRichPanelEditor(element, options);
|
|
239
251
|
break;
|
|
240
252
|
case "block-rich":
|
|
241
|
-
editor = createRichTextEditor(element,
|
|
253
|
+
editor = createRichTextEditor(element, options);
|
|
242
254
|
break;
|
|
243
255
|
case "inline-rich":
|
|
244
|
-
editor = createInlineRichTextEditor(element,
|
|
256
|
+
editor = createInlineRichTextEditor(element, options);
|
|
245
257
|
break;
|
|
246
258
|
case "plain":
|
|
247
|
-
editor = createPlainTextEditor(element,
|
|
259
|
+
editor = createPlainTextEditor(element, options);
|
|
248
260
|
break;
|
|
249
261
|
}
|
|
250
262
|
|
|
@@ -252,14 +264,10 @@ function activateEditor(element: HTMLElement, hash: string, options: Required<Up
|
|
|
252
264
|
element.dataset.upstartEditorActive = "true";
|
|
253
265
|
|
|
254
266
|
applyActiveStyles(element);
|
|
255
|
-
activeEditors.set(
|
|
267
|
+
activeEditors.set(element, { editor, element, hash, mode });
|
|
256
268
|
}
|
|
257
269
|
|
|
258
|
-
function createPlainTextEditor(
|
|
259
|
-
element: HTMLElement,
|
|
260
|
-
hash: string,
|
|
261
|
-
options: Required<UpstartEditorOptions>,
|
|
262
|
-
): Editor {
|
|
270
|
+
function createPlainTextEditor(element: HTMLElement, options: Required<UpstartEditorOptions>): Editor {
|
|
263
271
|
const renderedText = element.textContent ?? "";
|
|
264
272
|
|
|
265
273
|
let content: string | object = renderedText;
|
|
@@ -320,23 +328,19 @@ function createPlainTextEditor(
|
|
|
320
328
|
onUpdate: () => {
|
|
321
329
|
if (i18nSyncInProgress) return;
|
|
322
330
|
hasChanged = true;
|
|
323
|
-
syncI18nSiblings(
|
|
331
|
+
syncI18nSiblings(element);
|
|
324
332
|
},
|
|
325
333
|
onBlur: ({ editor: e }) => {
|
|
326
334
|
if (!hasChanged) return;
|
|
327
335
|
hasChanged = false;
|
|
328
|
-
saveText(
|
|
336
|
+
saveText(element, e.getText());
|
|
329
337
|
},
|
|
330
338
|
});
|
|
331
339
|
|
|
332
340
|
return editor;
|
|
333
341
|
}
|
|
334
342
|
|
|
335
|
-
function createRichTextEditor(
|
|
336
|
-
element: HTMLElement,
|
|
337
|
-
hash: string,
|
|
338
|
-
options: Required<UpstartEditorOptions>,
|
|
339
|
-
): Editor {
|
|
343
|
+
function createRichTextEditor(element: HTMLElement, options: Required<UpstartEditorOptions>): Editor {
|
|
340
344
|
const content = element.innerHTML;
|
|
341
345
|
element.innerHTML = ""; // Clear the element first!
|
|
342
346
|
let hasChanged = false;
|
|
@@ -369,12 +373,12 @@ function createRichTextEditor(
|
|
|
369
373
|
onUpdate: () => {
|
|
370
374
|
if (i18nSyncInProgress) return;
|
|
371
375
|
hasChanged = true;
|
|
372
|
-
syncI18nSiblings(
|
|
376
|
+
syncI18nSiblings(element);
|
|
373
377
|
},
|
|
374
378
|
onBlur: ({ editor: e }) => {
|
|
375
379
|
if (!hasChanged) return;
|
|
376
380
|
hasChanged = false;
|
|
377
|
-
saveText(
|
|
381
|
+
saveText(element, e.getHTML());
|
|
378
382
|
},
|
|
379
383
|
});
|
|
380
384
|
|
|
@@ -385,11 +389,7 @@ function createRichTextEditor(
|
|
|
385
389
|
return editor;
|
|
386
390
|
}
|
|
387
391
|
|
|
388
|
-
function createInlineRichTextEditor(
|
|
389
|
-
element: HTMLElement,
|
|
390
|
-
hash: string,
|
|
391
|
-
options: Required<UpstartEditorOptions>,
|
|
392
|
-
): Editor {
|
|
392
|
+
function createInlineRichTextEditor(element: HTMLElement, options: Required<UpstartEditorOptions>): Editor {
|
|
393
393
|
const content = element.innerHTML;
|
|
394
394
|
element.innerHTML = ""; // Clear the element first!
|
|
395
395
|
let hasChanged = false;
|
|
@@ -433,12 +433,12 @@ function createInlineRichTextEditor(
|
|
|
433
433
|
onUpdate: () => {
|
|
434
434
|
if (i18nSyncInProgress) return;
|
|
435
435
|
hasChanged = true;
|
|
436
|
-
syncI18nSiblings(
|
|
436
|
+
syncI18nSiblings(element);
|
|
437
437
|
},
|
|
438
438
|
onBlur: ({ editor: e }) => {
|
|
439
439
|
if (!hasChanged) return;
|
|
440
440
|
hasChanged = false;
|
|
441
|
-
saveText(
|
|
441
|
+
saveText(element, e.getHTML());
|
|
442
442
|
},
|
|
443
443
|
});
|
|
444
444
|
|
|
@@ -449,11 +449,7 @@ function createInlineRichTextEditor(
|
|
|
449
449
|
return editor;
|
|
450
450
|
}
|
|
451
451
|
|
|
452
|
-
function createDirectEditor(
|
|
453
|
-
element: HTMLElement,
|
|
454
|
-
hash: string,
|
|
455
|
-
options: Required<UpstartEditorOptions>,
|
|
456
|
-
): Editor {
|
|
452
|
+
function createDirectEditor(element: HTMLElement, options: Required<UpstartEditorOptions>): Editor {
|
|
457
453
|
const content = element.innerHTML;
|
|
458
454
|
element.innerHTML = "";
|
|
459
455
|
let hasChanged = false;
|
|
@@ -489,7 +485,7 @@ function createDirectEditor(
|
|
|
489
485
|
if (!hasChanged) return;
|
|
490
486
|
hasChanged = false;
|
|
491
487
|
// Strip the outer <p> that TipTap adds when using default document schema
|
|
492
|
-
saveText(
|
|
488
|
+
saveText(element, e.getHTML().replace(/^<p>([\s\S]*)<\/p>$/, "$1"));
|
|
493
489
|
},
|
|
494
490
|
});
|
|
495
491
|
|
|
@@ -500,11 +496,7 @@ function createDirectEditor(
|
|
|
500
496
|
return editor;
|
|
501
497
|
}
|
|
502
498
|
|
|
503
|
-
function createRichPanelEditor(
|
|
504
|
-
element: HTMLElement,
|
|
505
|
-
hash: string,
|
|
506
|
-
options: Required<UpstartEditorOptions>,
|
|
507
|
-
): Editor {
|
|
499
|
+
function createRichPanelEditor(element: HTMLElement, options: Required<UpstartEditorOptions>): Editor {
|
|
508
500
|
const content = element.innerHTML;
|
|
509
501
|
element.innerHTML = "";
|
|
510
502
|
let hasChanged = false;
|
|
@@ -527,7 +519,7 @@ function createRichPanelEditor(
|
|
|
527
519
|
onBlur: ({ editor: e }) => {
|
|
528
520
|
if (!hasChanged) return;
|
|
529
521
|
hasChanged = false;
|
|
530
|
-
saveText(
|
|
522
|
+
saveText(element, e.getHTML());
|
|
531
523
|
},
|
|
532
524
|
});
|
|
533
525
|
|
|
@@ -567,11 +559,11 @@ function getEditorMode(element: HTMLElement, options: Required<UpstartEditorOpti
|
|
|
567
559
|
return "block-rich";
|
|
568
560
|
}
|
|
569
561
|
|
|
570
|
-
function syncI18nSiblings(
|
|
571
|
-
|
|
572
|
-
|
|
562
|
+
function syncI18nSiblings(sourceElement: HTMLElement): void {
|
|
563
|
+
const instance = activeEditors.get(sourceElement);
|
|
564
|
+
console.log("[Upstart Editor] Syncing i18n siblings for", instance?.hash);
|
|
573
565
|
if (!instance) {
|
|
574
|
-
console.warn("[Upstart Editor] No editor instance found for
|
|
566
|
+
console.warn("[Upstart Editor] No editor instance found for element:", sourceElement);
|
|
575
567
|
return;
|
|
576
568
|
}
|
|
577
569
|
|
|
@@ -593,12 +585,11 @@ function syncI18nSiblings(sourceHash: string): void {
|
|
|
593
585
|
for (const sibling of siblings) {
|
|
594
586
|
if (sibling === instance.element) continue;
|
|
595
587
|
|
|
596
|
-
const
|
|
597
|
-
const siblingInstance = siblingHash ? activeEditors.get(siblingHash) : null;
|
|
588
|
+
const siblingInstance = activeEditors.get(sibling);
|
|
598
589
|
|
|
599
590
|
if (siblingInstance) {
|
|
600
591
|
console.log(
|
|
601
|
-
`[Upstart Editor] Updating sibling editor (hash: ${
|
|
592
|
+
`[Upstart Editor] Updating sibling editor (hash: ${siblingInstance.hash}) with new content`,
|
|
602
593
|
siblingInstance,
|
|
603
594
|
);
|
|
604
595
|
sibling.innerText = plainContent;
|
|
@@ -612,9 +603,9 @@ function syncI18nSiblings(sourceHash: string): void {
|
|
|
612
603
|
}
|
|
613
604
|
}
|
|
614
605
|
|
|
615
|
-
function saveText(
|
|
606
|
+
function saveText(element: HTMLElement, newText: string): void {
|
|
616
607
|
try {
|
|
617
|
-
const instance = activeEditors.get(
|
|
608
|
+
const instance = activeEditors.get(element);
|
|
618
609
|
const dataset = instance?.element.dataset ?? {};
|
|
619
610
|
|
|
620
611
|
// direct/rich-panel always go via editTextDirect; plain goes via editTextDirect when a
|
|
@@ -638,7 +629,7 @@ function saveText(hash: string, newText: string): void {
|
|
|
638
629
|
});
|
|
639
630
|
}
|
|
640
631
|
|
|
641
|
-
console.log("[Upstart Editor] Text save message sent:", hash);
|
|
632
|
+
console.log("[Upstart Editor] Text save message sent:", instance?.hash);
|
|
642
633
|
} catch (error) {
|
|
643
634
|
console.error("[Upstart Editor] Failed to send save message:", error);
|
|
644
635
|
sendToParent({
|
|
@@ -648,8 +639,8 @@ function saveText(hash: string, newText: string): void {
|
|
|
648
639
|
}
|
|
649
640
|
}
|
|
650
641
|
|
|
651
|
-
function destroyEditor(
|
|
652
|
-
const instance = activeEditors.get(
|
|
642
|
+
function destroyEditor(element: HTMLElement): void {
|
|
643
|
+
const instance = activeEditors.get(element);
|
|
653
644
|
if (!instance) {
|
|
654
645
|
return;
|
|
655
646
|
}
|
|
@@ -674,7 +665,7 @@ function destroyEditor(hash: string): void {
|
|
|
674
665
|
}
|
|
675
666
|
|
|
676
667
|
restoreStyles(instance.element);
|
|
677
|
-
activeEditors.delete(
|
|
668
|
+
activeEditors.delete(element);
|
|
678
669
|
}
|
|
679
670
|
|
|
680
671
|
// ---------------------------------------------------------------------------
|
|
@@ -749,10 +740,10 @@ function scheduleReactivation(): void {
|
|
|
749
740
|
* (e.g. React replaced the subtree during a re-render).
|
|
750
741
|
*/
|
|
751
742
|
function cleanupOrphanedEditors(): void {
|
|
752
|
-
for (const [
|
|
743
|
+
for (const [element, instance] of activeEditors) {
|
|
753
744
|
if (!document.contains(instance.element)) {
|
|
754
745
|
instance.editor.destroy();
|
|
755
|
-
activeEditors.delete(
|
|
746
|
+
activeEditors.delete(element);
|
|
756
747
|
}
|
|
757
748
|
}
|
|
758
749
|
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { Editor } from "@tiptap/core";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
PayloadEditText,
|
|
4
|
+
PayloadEditTextDirect,
|
|
5
|
+
PayloadArrayItemAdd,
|
|
6
|
+
PayloadArrayItemDelete,
|
|
7
|
+
PayloadArraySet,
|
|
8
|
+
} from "~/upstart-editor-api";
|
|
3
9
|
|
|
4
10
|
/**
|
|
5
11
|
* Editor mode
|
|
@@ -38,13 +44,31 @@ export interface EditorInstance {
|
|
|
38
44
|
mode: TextEditorMode;
|
|
39
45
|
}
|
|
40
46
|
|
|
47
|
+
/**
|
|
48
|
+
* A swappable image surfaced to the inspector. `id` maps to a registry entry of
|
|
49
|
+
* type "image"; `src` is the currently rendered URL (for the thumbnail).
|
|
50
|
+
*/
|
|
51
|
+
export interface EditableImageRef {
|
|
52
|
+
id: string;
|
|
53
|
+
src: string;
|
|
54
|
+
alt?: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
41
57
|
/**
|
|
42
58
|
* Messages sent from iframe to parent editor.
|
|
43
59
|
*/
|
|
44
60
|
export type EditorMessage =
|
|
45
|
-
| {
|
|
46
|
-
|
|
47
|
-
|
|
61
|
+
| {
|
|
62
|
+
type: "text-edit";
|
|
63
|
+
payload:
|
|
64
|
+
| PayloadEditText
|
|
65
|
+
| PayloadEditTextDirect
|
|
66
|
+
| PayloadArrayItemAdd
|
|
67
|
+
| PayloadArrayItemDelete
|
|
68
|
+
| PayloadArraySet;
|
|
69
|
+
}
|
|
70
|
+
| { type: "editor-ready"; path?: string }
|
|
71
|
+
| { type: "editor-navigated"; path?: string }
|
|
48
72
|
| { type: "scroll-position"; x: number; y: number }
|
|
49
73
|
| { type: "editor-error"; error: string }
|
|
50
74
|
| {
|
|
@@ -59,6 +83,8 @@ export type EditorMessage =
|
|
|
59
83
|
themeColors?: Record<string, string>;
|
|
60
84
|
bounds: ElementBounds;
|
|
61
85
|
viewportWidth?: number;
|
|
86
|
+
/** Editable images found in the clicked element's nearest subtree. */
|
|
87
|
+
images?: EditableImageRef[];
|
|
62
88
|
};
|
|
63
89
|
|
|
64
90
|
/**
|
|
@@ -67,6 +93,7 @@ export type EditorMessage =
|
|
|
67
93
|
export type ParentMessage =
|
|
68
94
|
| { type: "set-mode"; mode: EditorMode }
|
|
69
95
|
| { type: "preview-classname"; classNameId: string; className: string; previewCSS?: string }
|
|
96
|
+
| { type: "preview-image"; imageId: string; src: string }
|
|
70
97
|
| { type: "request-scroll-position" }
|
|
71
98
|
| { type: "restore-scroll-position"; x: number; y: number };
|
|
72
99
|
|