@alpaca-editor/core 1.0.3812 → 1.0.3815
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/components/ui/context-menu.d.ts +25 -0
- package/dist/components/ui/context-menu.js +51 -0
- package/dist/components/ui/context-menu.js.map +1 -0
- package/dist/config/config.js +3 -2
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +4 -2
- package/dist/editor/ComponentInfo.js +1 -1
- package/dist/editor/ComponentInfo.js.map +1 -1
- package/dist/editor/ConfirmationDialog.d.ts +1 -1
- package/dist/editor/ContextMenu.d.ts +1 -1
- package/dist/editor/ContextMenu.js +24 -9
- package/dist/editor/ContextMenu.js.map +1 -1
- package/dist/editor/ImageEditor.js +2 -2
- package/dist/editor/ImageEditor.js.map +1 -1
- package/dist/editor/ItemInfo.js +2 -2
- package/dist/editor/ItemInfo.js.map +1 -1
- package/dist/editor/MainLayout.js +3 -3
- package/dist/editor/MainLayout.js.map +1 -1
- package/dist/editor/Titlebar.js +1 -1
- package/dist/editor/Titlebar.js.map +1 -1
- package/dist/editor/ai/AiTerminal.js +19 -12
- package/dist/editor/ai/AiTerminal.js.map +1 -1
- package/dist/editor/client/EditorClient.js +19 -4
- package/dist/editor/client/EditorClient.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +1 -1
- package/dist/editor/client/operations.js +15 -14
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/client/pageModelBuilder.js +8 -5
- package/dist/editor/client/pageModelBuilder.js.map +1 -1
- package/dist/editor/commands/componentCommands.js +15 -13
- package/dist/editor/commands/componentCommands.js.map +1 -1
- package/dist/editor/componentTreeHelper.js +3 -3
- package/dist/editor/componentTreeHelper.js.map +1 -1
- package/dist/editor/control-center/ControlCenterMenu.js +3 -3
- package/dist/editor/control-center/ControlCenterMenu.js.map +1 -1
- package/dist/editor/field-types/TreeListEditor.js +4 -4
- package/dist/editor/field-types/TreeListEditor.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +52 -14
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +5 -5
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +114 -45
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.d.ts +0 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +119 -215
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/page-viewer/pageModelBuilder.d.ts +3 -0
- package/dist/editor/page-viewer/pageModelBuilder.js +299 -0
- package/dist/editor/page-viewer/pageModelBuilder.js.map +1 -0
- package/dist/editor/pageModel.d.ts +5 -0
- package/dist/editor/sidebar/ComponentPalette.js +30 -30
- package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
- package/dist/editor/sidebar/ComponentTree.js +7 -6
- package/dist/editor/sidebar/ComponentTree.js.map +1 -1
- package/dist/editor/sidebar/MainContentTree.js +1 -1
- package/dist/editor/sidebar/MainContentTree.js.map +1 -1
- package/dist/editor/sidebar/SidebarView.js +3 -3
- package/dist/editor/sidebar/SidebarView.js.map +1 -1
- package/dist/editor/ui/CopyToClipboardButton.js +2 -1
- package/dist/editor/ui/CopyToClipboardButton.js.map +1 -1
- package/dist/editor/ui/Icons.d.ts +0 -1
- package/dist/editor/ui/Icons.js +0 -3
- package/dist/editor/ui/Icons.js.map +1 -1
- package/dist/editor/ui/Section.js +1 -1
- package/dist/editor/ui/Section.js.map +1 -1
- package/dist/editor/ui/SimpleMenu.d.ts +1 -8
- package/dist/editor/ui/SimpleMenu.js +1 -1
- package/dist/editor/ui/SimpleMenu.js.map +1 -1
- package/dist/editor/utils.d.ts +2 -2
- package/dist/editor/utils.js +57 -9
- package/dist/editor/utils.js.map +1 -1
- package/dist/lib/safelist.js +1 -1
- package/dist/lib/safelist.js.map +1 -1
- package/dist/splash-screen/SplashScreen.js +0 -1
- package/dist/splash-screen/SplashScreen.js.map +1 -1
- package/dist/styles.css +242 -59
- package/dist/types.d.ts +2 -2
- package/package.json +3 -2
- package/src/components/ui/context-menu.tsx +250 -0
- package/src/config/config.tsx +2 -2
- package/src/config/types.ts +4 -2
- package/src/editor/ComponentInfo.tsx +3 -5
- package/src/editor/ConfirmationDialog.tsx +1 -1
- package/src/editor/ContextMenu.tsx +68 -19
- package/src/editor/ImageEditor.tsx +2 -2
- package/src/editor/ItemInfo.tsx +4 -4
- package/src/editor/MainLayout.tsx +3 -4
- package/src/editor/Titlebar.tsx +1 -1
- package/src/editor/ai/AiTerminal.tsx +31 -24
- package/src/editor/client/EditorClient.tsx +23 -6
- package/src/editor/client/editContext.ts +1 -1
- package/src/editor/client/operations.ts +16 -14
- package/src/editor/client/pageModelBuilder.ts +26 -18
- package/src/editor/commands/componentCommands.tsx +58 -39
- package/src/editor/componentTreeHelper.tsx +3 -2
- package/src/editor/control-center/ControlCenterMenu.tsx +4 -4
- package/src/editor/field-types/TreeListEditor.tsx +11 -11
- package/src/editor/page-editor-chrome/FrameMenu.tsx +81 -17
- package/src/editor/page-editor-chrome/InlineEditor.tsx +5 -5
- package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +12 -15
- package/src/editor/page-editor-chrome/PlaceholderDropZones.tsx +159 -68
- package/src/editor/page-viewer/PageViewerFrame.tsx +131 -300
- package/src/editor/page-viewer/pageModelBuilder.ts +412 -0
- package/src/editor/pageModel.ts +5 -0
- package/src/editor/sidebar/ComponentPalette.tsx +108 -106
- package/src/editor/sidebar/ComponentTree.tsx +10 -5
- package/src/editor/sidebar/MainContentTree.tsx +1 -1
- package/src/editor/sidebar/SidebarView.tsx +9 -9
- package/src/editor/ui/CopyToClipboardButton.tsx +2 -1
- package/src/editor/ui/Icons.tsx +0 -18
- package/src/editor/ui/Section.tsx +4 -4
- package/src/editor/ui/SimpleMenu.tsx +5 -13
- package/src/editor/utils.ts +74 -17
- package/src/lib/safelist.tsx +2 -0
- package/src/splash-screen/SplashScreen.tsx +0 -1
- package/src/types.ts +2 -4
- package/styles.css +58 -17
|
@@ -24,18 +24,11 @@ import { loadFieldButtons } from "../services/editService";
|
|
|
24
24
|
import { usePathname } from "next/navigation";
|
|
25
25
|
import { EditorWarnings } from "../EditorWarnings";
|
|
26
26
|
|
|
27
|
-
import {
|
|
28
|
-
Component,
|
|
29
|
-
PageSkeleton,
|
|
30
|
-
ComponentSkeleton,
|
|
31
|
-
PlaceholderSkeleton,
|
|
32
|
-
RenderedItemSkeleton,
|
|
33
|
-
ItemDescriptor,
|
|
34
|
-
} from "../pageModel";
|
|
27
|
+
import { Component, ItemDescriptor } from "../pageModel";
|
|
35
28
|
import { NoLayout } from "../page-editor-chrome/NoLayout";
|
|
36
29
|
import { Spinner } from "../ui/Spinner";
|
|
37
30
|
import { DeviceToolbar } from "./DeviceToolbar";
|
|
38
|
-
|
|
31
|
+
import { buildPageModel } from "./pageModelBuilder";
|
|
39
32
|
declare global {
|
|
40
33
|
interface Window {
|
|
41
34
|
requestRefresh?: (newUri?: string) => boolean;
|
|
@@ -109,278 +102,6 @@ export function PageViewerFrame({
|
|
|
109
102
|
|
|
110
103
|
updateMiniMapVisibility();
|
|
111
104
|
|
|
112
|
-
function buildPageModel(iframeDocument: Document | undefined) {
|
|
113
|
-
if (
|
|
114
|
-
!iframeDocument ||
|
|
115
|
-
!editContextRef.current ||
|
|
116
|
-
!pageViewContextRef.current
|
|
117
|
-
)
|
|
118
|
-
return;
|
|
119
|
-
|
|
120
|
-
const pageItemDescriptor = pageViewContextRef.current?.pageItemDescriptor;
|
|
121
|
-
|
|
122
|
-
if (!pageItemDescriptor) return;
|
|
123
|
-
|
|
124
|
-
const pageItem: RenderedItemSkeleton = {
|
|
125
|
-
...pageItemDescriptor,
|
|
126
|
-
renderedFieldIds: [],
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
const start = performance.now();
|
|
130
|
-
|
|
131
|
-
const treeWalker = iframeDocument.createTreeWalker(
|
|
132
|
-
iframeDocument.documentElement, // Root node to start traversal
|
|
133
|
-
NodeFilter.SHOW_ELEMENT, // Only show element nodes
|
|
134
|
-
null, // Optional filter function, can be `null`
|
|
135
|
-
);
|
|
136
|
-
|
|
137
|
-
const root: ComponentSkeleton = {
|
|
138
|
-
placeholders: [],
|
|
139
|
-
id: "page",
|
|
140
|
-
type: "Page",
|
|
141
|
-
typeId: "",
|
|
142
|
-
name: "Page",
|
|
143
|
-
items: [pageItem],
|
|
144
|
-
datasourceItem: pageItem,
|
|
145
|
-
renderedDictionaryKeys: [],
|
|
146
|
-
editorFields: {},
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
let currentComponent: ComponentSkeleton | undefined = root;
|
|
150
|
-
let currentPlaceholder: undefined | PlaceholderSkeleton;
|
|
151
|
-
|
|
152
|
-
while (treeWalker.nextNode()) {
|
|
153
|
-
const node = treeWalker.currentNode;
|
|
154
|
-
|
|
155
|
-
if (node.nodeType !== Node.ELEMENT_NODE) continue;
|
|
156
|
-
|
|
157
|
-
const element = node as Element;
|
|
158
|
-
|
|
159
|
-
if (currentComponent && element.hasAttribute("data-fieldid")) {
|
|
160
|
-
const fieldId = element.getAttribute("data-fieldid")!;
|
|
161
|
-
|
|
162
|
-
const language =
|
|
163
|
-
element.getAttribute("data-language") ||
|
|
164
|
-
currentComponent.datasourceItem?.language ||
|
|
165
|
-
pageItem.language;
|
|
166
|
-
const version = element.hasAttribute("data-version")
|
|
167
|
-
? parseInt(element.getAttribute("data-version")!)
|
|
168
|
-
: currentComponent.datasourceItem?.version || pageItem.version;
|
|
169
|
-
const itemId =
|
|
170
|
-
element.getAttribute("data-itemid") ||
|
|
171
|
-
currentComponent.datasourceItem?.id;
|
|
172
|
-
|
|
173
|
-
if (!itemId) continue;
|
|
174
|
-
|
|
175
|
-
let renderedItem = currentComponent.items.find(
|
|
176
|
-
(x) =>
|
|
177
|
-
x.id === itemId && x.language === language && x.version === version,
|
|
178
|
-
);
|
|
179
|
-
|
|
180
|
-
if (!renderedItem) {
|
|
181
|
-
renderedItem = {
|
|
182
|
-
id: itemId,
|
|
183
|
-
language,
|
|
184
|
-
version,
|
|
185
|
-
renderedFieldIds: [],
|
|
186
|
-
};
|
|
187
|
-
currentComponent.items.push(renderedItem);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (renderedItem.renderedFieldIds.indexOf(fieldId) === -1) {
|
|
191
|
-
renderedItem.renderedFieldIds.push(fieldId);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
if (element.tagName === "SCRIPT") {
|
|
196
|
-
const placeholderStartId = element.getAttribute(
|
|
197
|
-
"data-placeholder-start",
|
|
198
|
-
);
|
|
199
|
-
const placeholderEndId = element.getAttribute("data-placeholder-end");
|
|
200
|
-
const componentStartId = element.getAttribute("data-component-start");
|
|
201
|
-
const componentEndId = element.getAttribute("data-component-end");
|
|
202
|
-
const dictionaryKeyStart = element.getAttribute(
|
|
203
|
-
"data-dictionary-key-start",
|
|
204
|
-
);
|
|
205
|
-
const editorGroup = element.getAttribute("data-editor-group");
|
|
206
|
-
|
|
207
|
-
if (currentComponent && editorGroup) {
|
|
208
|
-
let group = currentComponent.editorFields[editorGroup];
|
|
209
|
-
if (!group) {
|
|
210
|
-
group = {
|
|
211
|
-
addFields: [],
|
|
212
|
-
removeFields: [],
|
|
213
|
-
};
|
|
214
|
-
currentComponent.editorFields[editorGroup] = group;
|
|
215
|
-
}
|
|
216
|
-
const addFields = element.getAttribute("data-add-fields")?.split(",");
|
|
217
|
-
const removeFields = element
|
|
218
|
-
.getAttribute("data-remove-fields")
|
|
219
|
-
?.split(",");
|
|
220
|
-
|
|
221
|
-
group.addFields = [...group.addFields, ...(addFields || [])];
|
|
222
|
-
group.removeFields = [...group.removeFields, ...(removeFields || [])];
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (dictionaryKeyStart) {
|
|
226
|
-
if (!currentComponent) {
|
|
227
|
-
console.error(
|
|
228
|
-
"Dictionary key without component:",
|
|
229
|
-
dictionaryKeyStart,
|
|
230
|
-
);
|
|
231
|
-
} else {
|
|
232
|
-
currentComponent.renderedDictionaryKeys.push(dictionaryKeyStart);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
if (placeholderStartId) {
|
|
236
|
-
if (!currentComponent) {
|
|
237
|
-
console.error(
|
|
238
|
-
"Placeholder start without component:",
|
|
239
|
-
placeholderStartId,
|
|
240
|
-
"Current placeholder",
|
|
241
|
-
currentPlaceholder,
|
|
242
|
-
);
|
|
243
|
-
} else {
|
|
244
|
-
currentPlaceholder = currentComponent.placeholders.find(
|
|
245
|
-
(x) => x.key === placeholderStartId,
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
if (!currentPlaceholder) {
|
|
249
|
-
currentPlaceholder = {
|
|
250
|
-
key: placeholderStartId,
|
|
251
|
-
name:
|
|
252
|
-
placeholderStartId.indexOf(currentComponent.id + "_") === 0
|
|
253
|
-
? placeholderStartId.substring(
|
|
254
|
-
currentComponent.id.length + 1,
|
|
255
|
-
)
|
|
256
|
-
: placeholderStartId,
|
|
257
|
-
description: "",
|
|
258
|
-
components: [],
|
|
259
|
-
parentComponent: currentComponent,
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
currentComponent.placeholders.push(currentPlaceholder);
|
|
263
|
-
}
|
|
264
|
-
currentComponent = undefined;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (placeholderEndId) {
|
|
269
|
-
currentComponent = currentPlaceholder?.parentComponent;
|
|
270
|
-
if (currentPlaceholder?.key !== placeholderEndId) {
|
|
271
|
-
console.error(
|
|
272
|
-
"Placeholder end does not match start",
|
|
273
|
-
currentPlaceholder,
|
|
274
|
-
placeholderEndId,
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
currentPlaceholder = undefined;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
if (componentStartId) {
|
|
281
|
-
if (!currentPlaceholder) {
|
|
282
|
-
if (!currentComponent) {
|
|
283
|
-
console.error(
|
|
284
|
-
"Component start without parent component:",
|
|
285
|
-
componentStartId,
|
|
286
|
-
);
|
|
287
|
-
continue;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
currentPlaceholder = {
|
|
291
|
-
key: "implicit_" + componentStartId,
|
|
292
|
-
name: "no-placeholder",
|
|
293
|
-
description: "",
|
|
294
|
-
components: [],
|
|
295
|
-
parentComponent: currentComponent,
|
|
296
|
-
};
|
|
297
|
-
if (!currentComponent) {
|
|
298
|
-
console.error(
|
|
299
|
-
"Component start without placeholder or parent component",
|
|
300
|
-
);
|
|
301
|
-
} else {
|
|
302
|
-
currentComponent.placeholders.push(currentPlaceholder);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
if (currentPlaceholder) {
|
|
306
|
-
const language =
|
|
307
|
-
element.getAttribute("data-language") || pageItem.language;
|
|
308
|
-
const version = element.hasAttribute("data-version")
|
|
309
|
-
? parseInt(element.getAttribute("data-version")!)
|
|
310
|
-
: pageItem.version;
|
|
311
|
-
|
|
312
|
-
const itemId = element.getAttribute("data-itemid");
|
|
313
|
-
|
|
314
|
-
const datasourceItem = itemId
|
|
315
|
-
? {
|
|
316
|
-
id: itemId,
|
|
317
|
-
language,
|
|
318
|
-
version,
|
|
319
|
-
renderedFieldIds: [],
|
|
320
|
-
}
|
|
321
|
-
: undefined;
|
|
322
|
-
|
|
323
|
-
const layoutId = element.getAttribute("data-layoutid");
|
|
324
|
-
|
|
325
|
-
currentComponent = currentPlaceholder.components.find(
|
|
326
|
-
(x) => x.id === componentStartId,
|
|
327
|
-
);
|
|
328
|
-
|
|
329
|
-
if (!currentComponent) {
|
|
330
|
-
currentComponent = {
|
|
331
|
-
id: componentStartId,
|
|
332
|
-
name: "",
|
|
333
|
-
type: element.getAttribute("data-type") || "",
|
|
334
|
-
typeId: element.getAttribute("data-typeid") || "",
|
|
335
|
-
items: datasourceItem ? [datasourceItem] : [],
|
|
336
|
-
placeholders: [],
|
|
337
|
-
parentPlaceholder: currentPlaceholder,
|
|
338
|
-
renderedDictionaryKeys: [],
|
|
339
|
-
datasourceItem,
|
|
340
|
-
layoutId: layoutId || undefined,
|
|
341
|
-
editorFields: {},
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
currentPlaceholder.components.push(currentComponent);
|
|
345
|
-
}
|
|
346
|
-
currentPlaceholder = undefined;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
if (componentEndId) {
|
|
351
|
-
if (!currentComponent || currentComponent.id !== componentEndId) {
|
|
352
|
-
console.error(
|
|
353
|
-
"Component end does not match start",
|
|
354
|
-
currentComponent,
|
|
355
|
-
componentEndId,
|
|
356
|
-
);
|
|
357
|
-
|
|
358
|
-
// Placeholder closed implicitly
|
|
359
|
-
if (currentPlaceholder?.parentComponent.id === componentEndId) {
|
|
360
|
-
currentComponent = currentPlaceholder.parentComponent;
|
|
361
|
-
currentPlaceholder = undefined;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
currentPlaceholder = currentComponent?.parentPlaceholder;
|
|
365
|
-
|
|
366
|
-
if (currentPlaceholder?.key.startsWith("implicit_")) {
|
|
367
|
-
currentComponent = currentPlaceholder.parentComponent;
|
|
368
|
-
} else currentComponent = undefined;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
const page: PageSkeleton = {
|
|
374
|
-
rootComponent: root,
|
|
375
|
-
item: pageItem,
|
|
376
|
-
editRevision: editContextRef.current?.revision ?? "",
|
|
377
|
-
};
|
|
378
|
-
const time = performance.now() - start;
|
|
379
|
-
|
|
380
|
-
console.log("PAGE MODEL SKELETON", page, time);
|
|
381
|
-
pageViewContextRef.current?.setPageSkeleton(page);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
105
|
const buildPageModelThrottled = useThrottledCallback(buildPageModel, 1000);
|
|
385
106
|
|
|
386
107
|
const [iframeSrc, setIframeSrc] = useState<string>();
|
|
@@ -401,10 +122,12 @@ export function PageViewerFrame({
|
|
|
401
122
|
"sc_version",
|
|
402
123
|
pageItemDescriptor.version.toString(),
|
|
403
124
|
);
|
|
404
|
-
|
|
405
|
-
"
|
|
406
|
-
|
|
407
|
-
|
|
125
|
+
if (editContext.previewMode) {
|
|
126
|
+
renderUrl.searchParams.set("alpaca_preview", "1");
|
|
127
|
+
} else {
|
|
128
|
+
renderUrl.searchParams.set("alpaca_editor", "1");
|
|
129
|
+
}
|
|
130
|
+
renderUrl.searchParams.set("sc_mode", "edit");
|
|
408
131
|
renderUrl.searchParams.set("alpaca_editor", "1");
|
|
409
132
|
renderUrl.searchParams.set("sc_database", "master");
|
|
410
133
|
//renderUrl.searchParams.set(
|
|
@@ -528,12 +251,22 @@ export function PageViewerFrame({
|
|
|
528
251
|
const parser = new DOMParser();
|
|
529
252
|
const newDoc = parser.parseFromString(text, "text/html");
|
|
530
253
|
morphdom(doc.documentElement, newDoc.documentElement);
|
|
254
|
+
if ((iframeRef.current!.contentWindow as any).XA) {
|
|
255
|
+
console.log("init XA");
|
|
256
|
+
(iframeRef.current!.contentWindow as any).XA.init();
|
|
257
|
+
}
|
|
531
258
|
setShowSpinner(false);
|
|
532
259
|
}
|
|
533
260
|
|
|
534
|
-
if (mode === "edit" && !editContext.previewMode)
|
|
261
|
+
if (mode === "edit" && !editContext.previewMode)
|
|
262
|
+
injectEditorCSS(doc, true);
|
|
263
|
+
else injectEditorCSS(doc, false);
|
|
264
|
+
|
|
265
|
+
setTimeout(() => {
|
|
266
|
+
injectSXAScripts(iframeRef.current!);
|
|
267
|
+
}, 1000);
|
|
535
268
|
|
|
536
|
-
buildPageModel(doc);
|
|
269
|
+
buildPageModel(doc, editContextRef, pageViewContextRef);
|
|
537
270
|
}
|
|
538
271
|
};
|
|
539
272
|
|
|
@@ -544,12 +277,15 @@ export function PageViewerFrame({
|
|
|
544
277
|
)
|
|
545
278
|
return;
|
|
546
279
|
|
|
547
|
-
const
|
|
548
|
-
iframeRef.current!,
|
|
280
|
+
const component = getComponentById(
|
|
549
281
|
editContext.scrollIntoView,
|
|
550
|
-
|
|
282
|
+
pageViewContextRef.current!.page!,
|
|
551
283
|
);
|
|
552
284
|
|
|
285
|
+
if (!component) return;
|
|
286
|
+
|
|
287
|
+
const rect = findComponentRect(iframeRef.current!, component, true);
|
|
288
|
+
|
|
553
289
|
if (!rect) return;
|
|
554
290
|
|
|
555
291
|
// Check if element is already in viewport
|
|
@@ -633,7 +369,7 @@ export function PageViewerFrame({
|
|
|
633
369
|
);
|
|
634
370
|
|
|
635
371
|
editContextRef.current?.setSelectedRange({
|
|
636
|
-
itemId:
|
|
372
|
+
itemId: fieldElement.getAttribute("data-itemid") || "",
|
|
637
373
|
fieldId: fieldId,
|
|
638
374
|
startOffset: globalStartOffset,
|
|
639
375
|
endOffset: globalEndOffset,
|
|
@@ -652,7 +388,8 @@ export function PageViewerFrame({
|
|
|
652
388
|
if (editContextRef.current?.isRefreshing) return;
|
|
653
389
|
|
|
654
390
|
const componentId = findParentComponentId(target);
|
|
655
|
-
editContextRef.current?.
|
|
391
|
+
if (editContextRef.current?.currentOverlay)
|
|
392
|
+
editContextRef.current?.setCurrentOverlay(undefined);
|
|
656
393
|
|
|
657
394
|
if (componentId) {
|
|
658
395
|
if (event.ctrlKey) {
|
|
@@ -660,7 +397,9 @@ export function PageViewerFrame({
|
|
|
660
397
|
if (currentSelection.indexOf(componentId) === -1)
|
|
661
398
|
editContextRef.current?.select([...currentSelection, componentId]);
|
|
662
399
|
} else {
|
|
663
|
-
editContextRef.current?.
|
|
400
|
+
if (editContextRef.current?.selection.indexOf(componentId) === -1) {
|
|
401
|
+
editContextRef.current?.select([componentId]);
|
|
402
|
+
}
|
|
664
403
|
}
|
|
665
404
|
|
|
666
405
|
// if (mode !== "edit") {
|
|
@@ -680,7 +419,10 @@ export function PageViewerFrame({
|
|
|
680
419
|
);
|
|
681
420
|
blockBlurEventRef.current = Date.now() + 500;
|
|
682
421
|
|
|
683
|
-
if (
|
|
422
|
+
if (
|
|
423
|
+
hasLock &&
|
|
424
|
+
editContextRef.current?.inlineEditingFieldElement !== fieldElement
|
|
425
|
+
) {
|
|
684
426
|
editContextRef.current?.setInlineEditingFieldElement(fieldElement);
|
|
685
427
|
}
|
|
686
428
|
}
|
|
@@ -727,7 +469,6 @@ export function PageViewerFrame({
|
|
|
727
469
|
|
|
728
470
|
if (componentId) {
|
|
729
471
|
if (!editContextRef.current?.selection.includes(componentId)) {
|
|
730
|
-
console.log("Selecting component CONTEXT MENU", componentId);
|
|
731
472
|
editContextRef.current!.select([componentId]);
|
|
732
473
|
}
|
|
733
474
|
}
|
|
@@ -837,7 +578,11 @@ export function PageViewerFrame({
|
|
|
837
578
|
),
|
|
838
579
|
)
|
|
839
580
|
) {
|
|
840
|
-
buildPageModelThrottled(
|
|
581
|
+
buildPageModelThrottled(
|
|
582
|
+
iframeDocument,
|
|
583
|
+
editContextRef,
|
|
584
|
+
pageViewContextRef,
|
|
585
|
+
);
|
|
841
586
|
}
|
|
842
587
|
});
|
|
843
588
|
|
|
@@ -849,7 +594,7 @@ export function PageViewerFrame({
|
|
|
849
594
|
//attributes: true, // observe attribute changes (like style or class)
|
|
850
595
|
});
|
|
851
596
|
|
|
852
|
-
buildPageModel(iframeDocument);
|
|
597
|
+
buildPageModel(iframeDocument, editContextRef, pageViewContextRef);
|
|
853
598
|
}
|
|
854
599
|
};
|
|
855
600
|
|
|
@@ -980,24 +725,110 @@ export function PageViewerFrame({
|
|
|
980
725
|
);
|
|
981
726
|
}
|
|
982
727
|
|
|
983
|
-
|
|
728
|
+
function injectEditorCSS(iframeDocument: Document, editMode: boolean) {
|
|
984
729
|
if (!iframeDocument) return;
|
|
985
730
|
const style = iframeDocument.createElement("style");
|
|
986
|
-
style.textContent =
|
|
731
|
+
style.textContent = editMode
|
|
732
|
+
? `[contentEditable]:empty:before {
|
|
987
733
|
content: attr(placeholder);
|
|
988
734
|
opacity: 0.6;
|
|
989
735
|
}
|
|
990
736
|
|
|
737
|
+
.scChromeData, code {
|
|
738
|
+
display: none;
|
|
739
|
+
}
|
|
740
|
+
|
|
991
741
|
[contenteditable] {
|
|
992
742
|
outline: 0px solid transparent;
|
|
993
743
|
}
|
|
994
|
-
|
|
744
|
+
`
|
|
745
|
+
: `
|
|
746
|
+
.scChromeData, code {
|
|
747
|
+
display: none;
|
|
748
|
+
}
|
|
749
|
+
`;
|
|
995
750
|
|
|
996
751
|
if (iframeDocument && iframeDocument.head) {
|
|
997
752
|
iframeDocument.head.appendChild(style);
|
|
998
753
|
}
|
|
999
754
|
}
|
|
1000
755
|
|
|
756
|
+
function injectSXAScripts(iframe: HTMLIFrameElement): void {
|
|
757
|
+
if (!iframe) return;
|
|
758
|
+
const iframeDocument = iframe.contentDocument;
|
|
759
|
+
const iframeWindow = iframe.contentWindow as any;
|
|
760
|
+
if (!iframeDocument || !iframeWindow) return;
|
|
761
|
+
|
|
762
|
+
iframeWindow.Sitecore = {
|
|
763
|
+
PageModes: {
|
|
764
|
+
HoverFrame: {
|
|
765
|
+
extend: () => {
|
|
766
|
+
// console.log("extend hoverframe");
|
|
767
|
+
},
|
|
768
|
+
},
|
|
769
|
+
ChromeManager: {
|
|
770
|
+
chromes: () => {
|
|
771
|
+
// console.log("chromes");
|
|
772
|
+
return [];
|
|
773
|
+
},
|
|
774
|
+
resetChromes: () => {
|
|
775
|
+
// console.log("resetChromes");
|
|
776
|
+
iframeWindow.XA.init();
|
|
777
|
+
},
|
|
778
|
+
chromesReseted: {
|
|
779
|
+
observe: () => {
|
|
780
|
+
// console.log("chromesReseted.observe");
|
|
781
|
+
},
|
|
782
|
+
},
|
|
783
|
+
// Dummy selectionChanged with an _callbacks array
|
|
784
|
+
selectionChanged: {
|
|
785
|
+
_callbacks: [] as any[],
|
|
786
|
+
// Optionally, you can add a method to trigger all callbacks if needed.
|
|
787
|
+
trigger: function (...args: any[]): void {
|
|
788
|
+
this._callbacks.forEach((callback: Function) => callback(...args));
|
|
789
|
+
},
|
|
790
|
+
},
|
|
791
|
+
},
|
|
792
|
+
|
|
793
|
+
ChromeControls: function () {},
|
|
794
|
+
ChromeTypes: {
|
|
795
|
+
PlaceholderSorting: function () {},
|
|
796
|
+
Rendering: function () {},
|
|
797
|
+
},
|
|
798
|
+
},
|
|
799
|
+
};
|
|
800
|
+
|
|
801
|
+
// Option 1: Use main window's jQuery if available.
|
|
802
|
+
if (iframeWindow.jQuery) {
|
|
803
|
+
// Be cautious: if the iframe's document is different, it's better to load jQuery within the iframe.
|
|
804
|
+
iframeWindow.$sc = iframeWindow.jQuery;
|
|
805
|
+
} else {
|
|
806
|
+
// Option 2: Dynamically load jQuery in the iframe.
|
|
807
|
+
const jqueryScript = iframeDocument.createElement("script");
|
|
808
|
+
jqueryScript.type = "text/javascript";
|
|
809
|
+
jqueryScript.src = "https://code.jquery.com/jquery-3.6.0.min.js"; // Use the version you prefer.
|
|
810
|
+
jqueryScript.onload = () => {
|
|
811
|
+
// Once loaded, assign it to $sc using noConflict to avoid global collisions.
|
|
812
|
+
iframeWindow.$sc = iframeWindow.jQuery.noConflict();
|
|
813
|
+
// console.log("jQuery loaded in iframe and assigned to $sc");
|
|
814
|
+
};
|
|
815
|
+
(iframeDocument.head || iframeDocument.body).appendChild(jqueryScript);
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
// Add a dummy implementation for renderExpandCommand on the ChromeControls prototype.
|
|
819
|
+
iframeWindow.Sitecore.PageModes.ChromeControls.prototype.renderExpandCommand =
|
|
820
|
+
function () {
|
|
821
|
+
console.log("renderExpandCommand called");
|
|
822
|
+
// Return a dummy value if needed. For example, you might return a dummy HTML string.
|
|
823
|
+
return "<div>Dummy Expand Command</div>";
|
|
824
|
+
};
|
|
825
|
+
|
|
826
|
+
iframeWindow.Sitecore.PageModes.ChromeTypes.PlaceholderSorting.prototype.insertSortingHandle =
|
|
827
|
+
function () {
|
|
828
|
+
console.log("insertSortingHandle called");
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
|
|
1001
832
|
/**
|
|
1002
833
|
* Calculates the global offset of a given target node and its local offset,
|
|
1003
834
|
* relative to the container's complete text content.
|