@alpaca-editor/core 1.0.3813 → 1.0.3817
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 +4 -3
- 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/EditorWarnings.js +1 -1
- package/dist/editor/EditorWarnings.js.map +1 -1
- package/dist/editor/FieldList.js +1 -1
- package/dist/editor/FieldList.js.map +1 -1
- package/dist/editor/FieldListFieldWithFallbacks.js +3 -3
- package/dist/editor/FieldListFieldWithFallbacks.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 +90 -35
- package/dist/editor/client/EditorClient.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +10 -4
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/operations.d.ts +5 -1
- package/dist/editor/client/operations.js +112 -17
- 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/component-designer/ComponentDesigner.js +1 -1
- package/dist/editor/component-designer/ComponentDesigner.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/menubar/LanguageSelector.js +3 -3
- package/dist/editor/menubar/LanguageSelector.js.map +1 -1
- package/dist/editor/menubar/PageSelector.js +1 -1
- package/dist/editor/menubar/PageSelector.js.map +1 -1
- package/dist/editor/menubar/PageViewerControls.js +12 -7
- package/dist/editor/menubar/PageViewerControls.js.map +1 -1
- package/dist/editor/menubar/Separator.js +1 -1
- package/dist/editor/menubar/VersionSelector.js +1 -1
- package/dist/editor/menubar/VersionSelector.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.d.ts +2 -2
- package/dist/editor/page-editor-chrome/FrameMenu.js +66 -22
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenus.d.ts +2 -2
- package/dist/editor/page-editor-chrome/FrameMenus.js +2 -2
- package/dist/editor/page-editor-chrome/FrameMenus.js.map +1 -1
- package/dist/editor/page-editor-chrome/InlineEditor.d.ts +2 -2
- package/dist/editor/page-editor-chrome/InlineEditor.js +175 -17
- package/dist/editor/page-editor-chrome/InlineEditor.js.map +1 -1
- package/dist/editor/page-editor-chrome/PageEditorChrome.d.ts +2 -2
- package/dist/editor/page-editor-chrome/PageEditorChrome.js +2 -2
- package/dist/editor/page-editor-chrome/PageEditorChrome.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/EditorForm.d.ts +2 -1
- package/dist/editor/page-viewer/EditorForm.js +9 -8
- package/dist/editor/page-viewer/EditorForm.js.map +1 -1
- package/dist/editor/page-viewer/MiniMap.d.ts +2 -2
- package/dist/editor/page-viewer/MiniMap.js +2 -2
- package/dist/editor/page-viewer/MiniMap.js.map +1 -1
- package/dist/editor/page-viewer/PageViewer.d.ts +2 -2
- package/dist/editor/page-viewer/PageViewer.js +3 -3
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.d.ts +2 -3
- package/dist/editor/page-viewer/PageViewerFrame.js +127 -223
- 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/reviews/Comments.d.ts +2 -0
- package/dist/editor/reviews/Comments.js +26 -9
- package/dist/editor/reviews/Comments.js.map +1 -1
- package/dist/editor/reviews/DiffView.d.ts +17 -0
- package/dist/editor/reviews/DiffView.js +57 -0
- package/dist/editor/reviews/DiffView.js.map +1 -0
- package/dist/editor/reviews/SuggestedEdit.d.ts +4 -0
- package/dist/editor/reviews/SuggestedEdit.js +180 -0
- package/dist/editor/reviews/SuggestedEdit.js.map +1 -0
- package/dist/editor/services/suggestedEditsService.d.ts +17 -0
- package/dist/editor/services/suggestedEditsService.js +26 -0
- package/dist/editor/services/suggestedEditsService.js.map +1 -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/PerfectTree.js +3 -3
- package/dist/editor/ui/PerfectTree.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/SimpleIconButton.js +3 -1
- package/dist/editor/ui/SimpleIconButton.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/editor/views/CompareView.js +4 -13
- package/dist/editor/views/CompareView.js.map +1 -1
- package/dist/editor/views/EditView.js +2 -2
- package/dist/editor/views/EditView.js.map +1 -1
- package/dist/editor/views/SingleEditView.d.ts +2 -2
- package/dist/editor/views/SingleEditView.js +2 -2
- package/dist/editor/views/SingleEditView.js.map +1 -1
- package/dist/lib/safelist.js +1 -1
- package/dist/lib/safelist.js.map +1 -1
- package/dist/page-wizard/steps/BuildPageStep.js +2 -2
- package/dist/page-wizard/steps/BuildPageStep.js.map +1 -1
- package/dist/page-wizard/steps/CreatePageAndLayoutStep.js +2 -2
- package/dist/page-wizard/steps/CreatePageAndLayoutStep.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 +275 -58
- package/dist/types.d.ts +20 -2
- package/package.json +6 -2
- package/src/components/ui/context-menu.tsx +250 -0
- package/src/config/config.tsx +4 -4
- 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/EditorWarnings.tsx +2 -2
- package/src/editor/FieldList.tsx +6 -6
- package/src/editor/FieldListFieldWithFallbacks.tsx +9 -9
- 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 +4 -4
- package/src/editor/ai/AiTerminal.tsx +31 -24
- package/src/editor/client/EditorClient.tsx +106 -57
- package/src/editor/client/editContext.ts +13 -4
- package/src/editor/client/operations.ts +162 -23
- package/src/editor/client/pageModelBuilder.ts +26 -18
- package/src/editor/commands/componentCommands.tsx +58 -39
- package/src/editor/component-designer/ComponentDesigner.tsx +1 -1
- 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/menubar/LanguageSelector.tsx +6 -6
- package/src/editor/menubar/PageSelector.tsx +11 -11
- package/src/editor/menubar/PageViewerControls.tsx +49 -23
- package/src/editor/menubar/Separator.tsx +2 -2
- package/src/editor/menubar/VersionSelector.tsx +1 -1
- package/src/editor/page-editor-chrome/FrameMenu.tsx +94 -29
- package/src/editor/page-editor-chrome/FrameMenus.tsx +6 -6
- package/src/editor/page-editor-chrome/InlineEditor.tsx +237 -26
- package/src/editor/page-editor-chrome/PageEditorChrome.tsx +11 -14
- 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/EditorForm.tsx +15 -9
- package/src/editor/page-viewer/MiniMap.tsx +4 -4
- package/src/editor/page-viewer/PageViewer.tsx +6 -6
- package/src/editor/page-viewer/PageViewerFrame.tsx +146 -309
- package/src/editor/page-viewer/pageModelBuilder.ts +412 -0
- package/src/editor/pageModel.ts +5 -0
- package/src/editor/reviews/Comments.tsx +56 -15
- package/src/editor/reviews/DiffView.tsx +109 -0
- package/src/editor/reviews/SuggestedEdit.tsx +316 -0
- package/src/editor/services/suggestedEditsService.ts +39 -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/PerfectTree.tsx +5 -5
- package/src/editor/ui/Section.tsx +4 -4
- package/src/editor/ui/SimpleIconButton.tsx +5 -3
- package/src/editor/ui/SimpleMenu.tsx +5 -13
- package/src/editor/utils.ts +74 -17
- package/src/editor/views/CompareView.tsx +13 -24
- package/src/editor/views/EditView.tsx +2 -2
- package/src/editor/views/SingleEditView.tsx +3 -3
- package/src/lib/safelist.tsx +4 -0
- package/src/page-wizard/steps/BuildPageStep.tsx +18 -25
- package/src/page-wizard/steps/CreatePageAndLayoutStep.tsx +16 -18
- package/src/splash-screen/SplashScreen.tsx +0 -1
- package/src/types.ts +20 -3
- package/styles.css +58 -17
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from "react";
|
|
2
2
|
import { MiniMap } from "./MiniMap";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
useEditContext,
|
|
5
|
+
useEditContextRef,
|
|
6
|
+
EditorMode,
|
|
7
|
+
} from "../client/editContext";
|
|
4
8
|
import { useDebouncedCallback, useThrottledCallback } from "use-debounce";
|
|
5
9
|
import { PageEditorChrome } from "../page-editor-chrome/PageEditorChrome";
|
|
6
10
|
import { PageViewContext } from "./pageViewContext";
|
|
@@ -24,18 +28,11 @@ import { loadFieldButtons } from "../services/editService";
|
|
|
24
28
|
import { usePathname } from "next/navigation";
|
|
25
29
|
import { EditorWarnings } from "../EditorWarnings";
|
|
26
30
|
|
|
27
|
-
import {
|
|
28
|
-
Component,
|
|
29
|
-
PageSkeleton,
|
|
30
|
-
ComponentSkeleton,
|
|
31
|
-
PlaceholderSkeleton,
|
|
32
|
-
RenderedItemSkeleton,
|
|
33
|
-
ItemDescriptor,
|
|
34
|
-
} from "../pageModel";
|
|
31
|
+
import { Component, ItemDescriptor } from "../pageModel";
|
|
35
32
|
import { NoLayout } from "../page-editor-chrome/NoLayout";
|
|
36
33
|
import { Spinner } from "../ui/Spinner";
|
|
37
34
|
import { DeviceToolbar } from "./DeviceToolbar";
|
|
38
|
-
|
|
35
|
+
import { buildPageModel } from "./pageModelBuilder";
|
|
39
36
|
declare global {
|
|
40
37
|
interface Window {
|
|
41
38
|
requestRefresh?: (newUri?: string) => boolean;
|
|
@@ -43,10 +40,10 @@ declare global {
|
|
|
43
40
|
}
|
|
44
41
|
|
|
45
42
|
export function PageViewerFrame({
|
|
46
|
-
|
|
43
|
+
compareView,
|
|
47
44
|
pageViewContext,
|
|
48
45
|
}: {
|
|
49
|
-
|
|
46
|
+
compareView: boolean;
|
|
50
47
|
pageViewContext?: PageViewContext;
|
|
51
48
|
}) {
|
|
52
49
|
const editContext = useEditContext();
|
|
@@ -109,278 +106,6 @@ export function PageViewerFrame({
|
|
|
109
106
|
|
|
110
107
|
updateMiniMapVisibility();
|
|
111
108
|
|
|
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
109
|
const buildPageModelThrottled = useThrottledCallback(buildPageModel, 1000);
|
|
385
110
|
|
|
386
111
|
const [iframeSrc, setIframeSrc] = useState<string>();
|
|
@@ -401,10 +126,12 @@ export function PageViewerFrame({
|
|
|
401
126
|
"sc_version",
|
|
402
127
|
pageItemDescriptor.version.toString(),
|
|
403
128
|
);
|
|
404
|
-
|
|
405
|
-
"
|
|
406
|
-
|
|
407
|
-
|
|
129
|
+
if (editContext.mode === "preview") {
|
|
130
|
+
renderUrl.searchParams.set("alpaca_preview", "1");
|
|
131
|
+
} else {
|
|
132
|
+
renderUrl.searchParams.set("alpaca_editor", "1");
|
|
133
|
+
}
|
|
134
|
+
renderUrl.searchParams.set("sc_mode", "edit");
|
|
408
135
|
renderUrl.searchParams.set("alpaca_editor", "1");
|
|
409
136
|
renderUrl.searchParams.set("sc_database", "master");
|
|
410
137
|
//renderUrl.searchParams.set(
|
|
@@ -432,7 +159,7 @@ export function PageViewerFrame({
|
|
|
432
159
|
);
|
|
433
160
|
renderUrl.searchParams.set(
|
|
434
161
|
"mode",
|
|
435
|
-
editContext.
|
|
162
|
+
editContext.mode === "preview" ? "preview" : "edit",
|
|
436
163
|
);
|
|
437
164
|
}
|
|
438
165
|
|
|
@@ -463,7 +190,7 @@ export function PageViewerFrame({
|
|
|
463
190
|
editContext.revision,
|
|
464
191
|
pageItemDescriptor,
|
|
465
192
|
pageViewContext.isHeadless,
|
|
466
|
-
editContext.
|
|
193
|
+
editContext.mode,
|
|
467
194
|
]);
|
|
468
195
|
|
|
469
196
|
useEffect(() => {
|
|
@@ -528,12 +255,20 @@ export function PageViewerFrame({
|
|
|
528
255
|
const parser = new DOMParser();
|
|
529
256
|
const newDoc = parser.parseFromString(text, "text/html");
|
|
530
257
|
morphdom(doc.documentElement, newDoc.documentElement);
|
|
258
|
+
if ((iframeRef.current!.contentWindow as any).XA) {
|
|
259
|
+
console.log("init XA");
|
|
260
|
+
(iframeRef.current!.contentWindow as any).XA.init();
|
|
261
|
+
}
|
|
531
262
|
setShowSpinner(false);
|
|
532
263
|
}
|
|
533
264
|
|
|
534
|
-
|
|
265
|
+
injectEditorCSS(doc, editContext.mode !== "preview");
|
|
535
266
|
|
|
536
|
-
|
|
267
|
+
setTimeout(() => {
|
|
268
|
+
injectSXAScripts(iframeRef.current!);
|
|
269
|
+
}, 1000);
|
|
270
|
+
|
|
271
|
+
buildPageModel(doc, editContextRef, pageViewContextRef);
|
|
537
272
|
}
|
|
538
273
|
};
|
|
539
274
|
|
|
@@ -544,12 +279,15 @@ export function PageViewerFrame({
|
|
|
544
279
|
)
|
|
545
280
|
return;
|
|
546
281
|
|
|
547
|
-
const
|
|
548
|
-
iframeRef.current!,
|
|
282
|
+
const component = getComponentById(
|
|
549
283
|
editContext.scrollIntoView,
|
|
550
|
-
|
|
284
|
+
pageViewContextRef.current!.page!,
|
|
551
285
|
);
|
|
552
286
|
|
|
287
|
+
if (!component) return;
|
|
288
|
+
|
|
289
|
+
const rect = findComponentRect(iframeRef.current!, component, true);
|
|
290
|
+
|
|
553
291
|
if (!rect) return;
|
|
554
292
|
|
|
555
293
|
// Check if element is already in viewport
|
|
@@ -633,7 +371,7 @@ export function PageViewerFrame({
|
|
|
633
371
|
);
|
|
634
372
|
|
|
635
373
|
editContextRef.current?.setSelectedRange({
|
|
636
|
-
itemId:
|
|
374
|
+
itemId: fieldElement.getAttribute("data-itemid") || "",
|
|
637
375
|
fieldId: fieldId,
|
|
638
376
|
startOffset: globalStartOffset,
|
|
639
377
|
endOffset: globalEndOffset,
|
|
@@ -652,7 +390,8 @@ export function PageViewerFrame({
|
|
|
652
390
|
if (editContextRef.current?.isRefreshing) return;
|
|
653
391
|
|
|
654
392
|
const componentId = findParentComponentId(target);
|
|
655
|
-
editContextRef.current?.
|
|
393
|
+
if (editContextRef.current?.currentOverlay)
|
|
394
|
+
editContextRef.current?.setCurrentOverlay(undefined);
|
|
656
395
|
|
|
657
396
|
if (componentId) {
|
|
658
397
|
if (event.ctrlKey) {
|
|
@@ -660,7 +399,9 @@ export function PageViewerFrame({
|
|
|
660
399
|
if (currentSelection.indexOf(componentId) === -1)
|
|
661
400
|
editContextRef.current?.select([...currentSelection, componentId]);
|
|
662
401
|
} else {
|
|
663
|
-
editContextRef.current?.
|
|
402
|
+
if (editContextRef.current?.selection.indexOf(componentId) === -1) {
|
|
403
|
+
editContextRef.current?.select([componentId]);
|
|
404
|
+
}
|
|
664
405
|
}
|
|
665
406
|
|
|
666
407
|
// if (mode !== "edit") {
|
|
@@ -669,7 +410,7 @@ export function PageViewerFrame({
|
|
|
669
410
|
} else editContextRef.current?.select([]);
|
|
670
411
|
|
|
671
412
|
if (
|
|
672
|
-
mode === "edit" &&
|
|
413
|
+
(editContext.mode === "edit" || editContext.mode === "suggestions") &&
|
|
673
414
|
pageViewContextRef.current?.page?.item.canWriteItem
|
|
674
415
|
) {
|
|
675
416
|
const fieldElement = findParentWithAttribute(target, "data-fieldid");
|
|
@@ -680,7 +421,10 @@ export function PageViewerFrame({
|
|
|
680
421
|
);
|
|
681
422
|
blockBlurEventRef.current = Date.now() + 500;
|
|
682
423
|
|
|
683
|
-
if (
|
|
424
|
+
if (
|
|
425
|
+
hasLock &&
|
|
426
|
+
editContextRef.current?.inlineEditingFieldElement !== fieldElement
|
|
427
|
+
) {
|
|
684
428
|
editContextRef.current?.setInlineEditingFieldElement(fieldElement);
|
|
685
429
|
}
|
|
686
430
|
}
|
|
@@ -727,7 +471,6 @@ export function PageViewerFrame({
|
|
|
727
471
|
|
|
728
472
|
if (componentId) {
|
|
729
473
|
if (!editContextRef.current?.selection.includes(componentId)) {
|
|
730
|
-
console.log("Selecting component CONTEXT MENU", componentId);
|
|
731
474
|
editContextRef.current!.select([componentId]);
|
|
732
475
|
}
|
|
733
476
|
}
|
|
@@ -837,7 +580,11 @@ export function PageViewerFrame({
|
|
|
837
580
|
),
|
|
838
581
|
)
|
|
839
582
|
) {
|
|
840
|
-
buildPageModelThrottled(
|
|
583
|
+
buildPageModelThrottled(
|
|
584
|
+
iframeDocument,
|
|
585
|
+
editContextRef,
|
|
586
|
+
pageViewContextRef,
|
|
587
|
+
);
|
|
841
588
|
}
|
|
842
589
|
});
|
|
843
590
|
|
|
@@ -849,7 +596,7 @@ export function PageViewerFrame({
|
|
|
849
596
|
//attributes: true, // observe attribute changes (like style or class)
|
|
850
597
|
});
|
|
851
598
|
|
|
852
|
-
buildPageModel(iframeDocument);
|
|
599
|
+
buildPageModel(iframeDocument, editContextRef, pageViewContextRef);
|
|
853
600
|
}
|
|
854
601
|
};
|
|
855
602
|
|
|
@@ -887,7 +634,7 @@ export function PageViewerFrame({
|
|
|
887
634
|
|
|
888
635
|
const updateScrollPosition = (e: number) => {
|
|
889
636
|
setScroll(e);
|
|
890
|
-
if (
|
|
637
|
+
if (!compareView) pageViewContextRef.current?.setScroll(e);
|
|
891
638
|
};
|
|
892
639
|
|
|
893
640
|
useEffect(() => {
|
|
@@ -946,7 +693,7 @@ export function PageViewerFrame({
|
|
|
946
693
|
{iframeRef.current && (
|
|
947
694
|
<PageEditorChrome
|
|
948
695
|
iframe={iframeRef.current}
|
|
949
|
-
|
|
696
|
+
compareView={compareView}
|
|
950
697
|
pageViewContext={pageViewContext}
|
|
951
698
|
/>
|
|
952
699
|
)}
|
|
@@ -956,7 +703,7 @@ export function PageViewerFrame({
|
|
|
956
703
|
</div>
|
|
957
704
|
{!editContext.pageView.fullscreen && showMiniMap && (
|
|
958
705
|
<MiniMap
|
|
959
|
-
|
|
706
|
+
compareView={compareView}
|
|
960
707
|
scroll={scroll}
|
|
961
708
|
mainViewIframeRef={iframeRef}
|
|
962
709
|
pageViewContext={pageViewContext}
|
|
@@ -980,24 +727,114 @@ export function PageViewerFrame({
|
|
|
980
727
|
);
|
|
981
728
|
}
|
|
982
729
|
|
|
983
|
-
|
|
730
|
+
function injectEditorCSS(iframeDocument: Document, editMode: boolean) {
|
|
984
731
|
if (!iframeDocument) return;
|
|
985
732
|
const style = iframeDocument.createElement("style");
|
|
986
|
-
|
|
733
|
+
|
|
734
|
+
style.textContent = editMode
|
|
735
|
+
? `[contentEditable]:empty:before {
|
|
987
736
|
content: attr(placeholder);
|
|
988
737
|
opacity: 0.6;
|
|
989
738
|
}
|
|
990
739
|
|
|
740
|
+
.scChromeData, code {
|
|
741
|
+
display: none;
|
|
742
|
+
}
|
|
743
|
+
|
|
991
744
|
[contenteditable] {
|
|
992
745
|
outline: 0px solid transparent;
|
|
993
746
|
}
|
|
994
|
-
|
|
747
|
+
`
|
|
748
|
+
: `
|
|
749
|
+
[contenteditable] {
|
|
750
|
+
outline: 0px solid transparent;
|
|
751
|
+
}
|
|
752
|
+
.scChromeData, code {
|
|
753
|
+
display: none;
|
|
754
|
+
}
|
|
755
|
+
`;
|
|
995
756
|
|
|
996
757
|
if (iframeDocument && iframeDocument.head) {
|
|
997
758
|
iframeDocument.head.appendChild(style);
|
|
998
759
|
}
|
|
999
760
|
}
|
|
1000
761
|
|
|
762
|
+
function injectSXAScripts(iframe: HTMLIFrameElement): void {
|
|
763
|
+
if (!iframe) return;
|
|
764
|
+
const iframeDocument = iframe.contentDocument;
|
|
765
|
+
const iframeWindow = iframe.contentWindow as any;
|
|
766
|
+
if (!iframeDocument || !iframeWindow) return;
|
|
767
|
+
|
|
768
|
+
iframeWindow.Sitecore = {
|
|
769
|
+
PageModes: {
|
|
770
|
+
HoverFrame: {
|
|
771
|
+
extend: () => {
|
|
772
|
+
// console.log("extend hoverframe");
|
|
773
|
+
},
|
|
774
|
+
},
|
|
775
|
+
ChromeManager: {
|
|
776
|
+
chromes: () => {
|
|
777
|
+
// console.log("chromes");
|
|
778
|
+
return [];
|
|
779
|
+
},
|
|
780
|
+
resetChromes: () => {
|
|
781
|
+
// console.log("resetChromes");
|
|
782
|
+
iframeWindow.XA.init();
|
|
783
|
+
},
|
|
784
|
+
chromesReseted: {
|
|
785
|
+
observe: () => {
|
|
786
|
+
// console.log("chromesReseted.observe");
|
|
787
|
+
},
|
|
788
|
+
},
|
|
789
|
+
// Dummy selectionChanged with an _callbacks array
|
|
790
|
+
selectionChanged: {
|
|
791
|
+
_callbacks: [] as any[],
|
|
792
|
+
// Optionally, you can add a method to trigger all callbacks if needed.
|
|
793
|
+
trigger: function (...args: any[]): void {
|
|
794
|
+
this._callbacks.forEach((callback: Function) => callback(...args));
|
|
795
|
+
},
|
|
796
|
+
},
|
|
797
|
+
},
|
|
798
|
+
|
|
799
|
+
ChromeControls: function () {},
|
|
800
|
+
ChromeTypes: {
|
|
801
|
+
PlaceholderSorting: function () {},
|
|
802
|
+
Rendering: function () {},
|
|
803
|
+
},
|
|
804
|
+
},
|
|
805
|
+
};
|
|
806
|
+
|
|
807
|
+
// Option 1: Use main window's jQuery if available.
|
|
808
|
+
if (iframeWindow.jQuery) {
|
|
809
|
+
// Be cautious: if the iframe's document is different, it's better to load jQuery within the iframe.
|
|
810
|
+
iframeWindow.$sc = iframeWindow.jQuery;
|
|
811
|
+
} else {
|
|
812
|
+
// Option 2: Dynamically load jQuery in the iframe.
|
|
813
|
+
const jqueryScript = iframeDocument.createElement("script");
|
|
814
|
+
jqueryScript.type = "text/javascript";
|
|
815
|
+
jqueryScript.src = "https://code.jquery.com/jquery-3.6.0.min.js"; // Use the version you prefer.
|
|
816
|
+
jqueryScript.onload = () => {
|
|
817
|
+
// Once loaded, assign it to $sc using noConflict to avoid global collisions.
|
|
818
|
+
iframeWindow.$sc = iframeWindow.jQuery.noConflict();
|
|
819
|
+
// console.log("jQuery loaded in iframe and assigned to $sc");
|
|
820
|
+
};
|
|
821
|
+
(iframeDocument.head || iframeDocument.body).appendChild(jqueryScript);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
// Add a dummy implementation for renderExpandCommand on the ChromeControls prototype.
|
|
825
|
+
iframeWindow.Sitecore.PageModes.ChromeControls.prototype.renderExpandCommand =
|
|
826
|
+
function () {
|
|
827
|
+
console.log("renderExpandCommand called");
|
|
828
|
+
// Return a dummy value if needed. For example, you might return a dummy HTML string.
|
|
829
|
+
return "<div>Dummy Expand Command</div>";
|
|
830
|
+
};
|
|
831
|
+
|
|
832
|
+
iframeWindow.Sitecore.PageModes.ChromeTypes.PlaceholderSorting.prototype.insertSortingHandle =
|
|
833
|
+
function () {
|
|
834
|
+
console.log("insertSortingHandle called");
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
|
|
1001
838
|
/**
|
|
1002
839
|
* Calculates the global offset of a given target node and its local offset,
|
|
1003
840
|
* relative to the container's complete text content.
|