@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.
Files changed (207) hide show
  1. package/dist/components/ui/context-menu.d.ts +25 -0
  2. package/dist/components/ui/context-menu.js +51 -0
  3. package/dist/components/ui/context-menu.js.map +1 -0
  4. package/dist/config/config.js +4 -3
  5. package/dist/config/config.js.map +1 -1
  6. package/dist/config/types.d.ts +4 -2
  7. package/dist/editor/ComponentInfo.js +1 -1
  8. package/dist/editor/ComponentInfo.js.map +1 -1
  9. package/dist/editor/ConfirmationDialog.d.ts +1 -1
  10. package/dist/editor/ContextMenu.d.ts +1 -1
  11. package/dist/editor/ContextMenu.js +24 -9
  12. package/dist/editor/ContextMenu.js.map +1 -1
  13. package/dist/editor/EditorWarnings.js +1 -1
  14. package/dist/editor/EditorWarnings.js.map +1 -1
  15. package/dist/editor/FieldList.js +1 -1
  16. package/dist/editor/FieldList.js.map +1 -1
  17. package/dist/editor/FieldListFieldWithFallbacks.js +3 -3
  18. package/dist/editor/FieldListFieldWithFallbacks.js.map +1 -1
  19. package/dist/editor/ImageEditor.js +2 -2
  20. package/dist/editor/ImageEditor.js.map +1 -1
  21. package/dist/editor/ItemInfo.js +2 -2
  22. package/dist/editor/ItemInfo.js.map +1 -1
  23. package/dist/editor/MainLayout.js +3 -3
  24. package/dist/editor/MainLayout.js.map +1 -1
  25. package/dist/editor/Titlebar.js +1 -1
  26. package/dist/editor/Titlebar.js.map +1 -1
  27. package/dist/editor/ai/AiTerminal.js +19 -12
  28. package/dist/editor/ai/AiTerminal.js.map +1 -1
  29. package/dist/editor/client/EditorClient.js +90 -35
  30. package/dist/editor/client/EditorClient.js.map +1 -1
  31. package/dist/editor/client/editContext.d.ts +10 -4
  32. package/dist/editor/client/editContext.js.map +1 -1
  33. package/dist/editor/client/operations.d.ts +5 -1
  34. package/dist/editor/client/operations.js +112 -17
  35. package/dist/editor/client/operations.js.map +1 -1
  36. package/dist/editor/client/pageModelBuilder.js +8 -5
  37. package/dist/editor/client/pageModelBuilder.js.map +1 -1
  38. package/dist/editor/commands/componentCommands.js +15 -13
  39. package/dist/editor/commands/componentCommands.js.map +1 -1
  40. package/dist/editor/component-designer/ComponentDesigner.js +1 -1
  41. package/dist/editor/component-designer/ComponentDesigner.js.map +1 -1
  42. package/dist/editor/componentTreeHelper.js +3 -3
  43. package/dist/editor/componentTreeHelper.js.map +1 -1
  44. package/dist/editor/control-center/ControlCenterMenu.js +3 -3
  45. package/dist/editor/control-center/ControlCenterMenu.js.map +1 -1
  46. package/dist/editor/field-types/TreeListEditor.js +4 -4
  47. package/dist/editor/field-types/TreeListEditor.js.map +1 -1
  48. package/dist/editor/menubar/LanguageSelector.js +3 -3
  49. package/dist/editor/menubar/LanguageSelector.js.map +1 -1
  50. package/dist/editor/menubar/PageSelector.js +1 -1
  51. package/dist/editor/menubar/PageSelector.js.map +1 -1
  52. package/dist/editor/menubar/PageViewerControls.js +12 -7
  53. package/dist/editor/menubar/PageViewerControls.js.map +1 -1
  54. package/dist/editor/menubar/Separator.js +1 -1
  55. package/dist/editor/menubar/VersionSelector.js +1 -1
  56. package/dist/editor/menubar/VersionSelector.js.map +1 -1
  57. package/dist/editor/page-editor-chrome/FrameMenu.d.ts +2 -2
  58. package/dist/editor/page-editor-chrome/FrameMenu.js +66 -22
  59. package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
  60. package/dist/editor/page-editor-chrome/FrameMenus.d.ts +2 -2
  61. package/dist/editor/page-editor-chrome/FrameMenus.js +2 -2
  62. package/dist/editor/page-editor-chrome/FrameMenus.js.map +1 -1
  63. package/dist/editor/page-editor-chrome/InlineEditor.d.ts +2 -2
  64. package/dist/editor/page-editor-chrome/InlineEditor.js +175 -17
  65. package/dist/editor/page-editor-chrome/InlineEditor.js.map +1 -1
  66. package/dist/editor/page-editor-chrome/PageEditorChrome.d.ts +2 -2
  67. package/dist/editor/page-editor-chrome/PageEditorChrome.js +2 -2
  68. package/dist/editor/page-editor-chrome/PageEditorChrome.js.map +1 -1
  69. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +5 -5
  70. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
  71. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +114 -45
  72. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
  73. package/dist/editor/page-viewer/EditorForm.d.ts +2 -1
  74. package/dist/editor/page-viewer/EditorForm.js +9 -8
  75. package/dist/editor/page-viewer/EditorForm.js.map +1 -1
  76. package/dist/editor/page-viewer/MiniMap.d.ts +2 -2
  77. package/dist/editor/page-viewer/MiniMap.js +2 -2
  78. package/dist/editor/page-viewer/MiniMap.js.map +1 -1
  79. package/dist/editor/page-viewer/PageViewer.d.ts +2 -2
  80. package/dist/editor/page-viewer/PageViewer.js +3 -3
  81. package/dist/editor/page-viewer/PageViewer.js.map +1 -1
  82. package/dist/editor/page-viewer/PageViewerFrame.d.ts +2 -3
  83. package/dist/editor/page-viewer/PageViewerFrame.js +127 -223
  84. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  85. package/dist/editor/page-viewer/pageModelBuilder.d.ts +3 -0
  86. package/dist/editor/page-viewer/pageModelBuilder.js +299 -0
  87. package/dist/editor/page-viewer/pageModelBuilder.js.map +1 -0
  88. package/dist/editor/pageModel.d.ts +5 -0
  89. package/dist/editor/reviews/Comments.d.ts +2 -0
  90. package/dist/editor/reviews/Comments.js +26 -9
  91. package/dist/editor/reviews/Comments.js.map +1 -1
  92. package/dist/editor/reviews/DiffView.d.ts +17 -0
  93. package/dist/editor/reviews/DiffView.js +57 -0
  94. package/dist/editor/reviews/DiffView.js.map +1 -0
  95. package/dist/editor/reviews/SuggestedEdit.d.ts +4 -0
  96. package/dist/editor/reviews/SuggestedEdit.js +180 -0
  97. package/dist/editor/reviews/SuggestedEdit.js.map +1 -0
  98. package/dist/editor/services/suggestedEditsService.d.ts +17 -0
  99. package/dist/editor/services/suggestedEditsService.js +26 -0
  100. package/dist/editor/services/suggestedEditsService.js.map +1 -0
  101. package/dist/editor/sidebar/ComponentPalette.js +30 -30
  102. package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
  103. package/dist/editor/sidebar/ComponentTree.js +7 -6
  104. package/dist/editor/sidebar/ComponentTree.js.map +1 -1
  105. package/dist/editor/sidebar/MainContentTree.js +1 -1
  106. package/dist/editor/sidebar/MainContentTree.js.map +1 -1
  107. package/dist/editor/sidebar/SidebarView.js +3 -3
  108. package/dist/editor/sidebar/SidebarView.js.map +1 -1
  109. package/dist/editor/ui/CopyToClipboardButton.js +2 -1
  110. package/dist/editor/ui/CopyToClipboardButton.js.map +1 -1
  111. package/dist/editor/ui/Icons.d.ts +0 -1
  112. package/dist/editor/ui/Icons.js +0 -3
  113. package/dist/editor/ui/Icons.js.map +1 -1
  114. package/dist/editor/ui/PerfectTree.js +3 -3
  115. package/dist/editor/ui/PerfectTree.js.map +1 -1
  116. package/dist/editor/ui/Section.js +1 -1
  117. package/dist/editor/ui/Section.js.map +1 -1
  118. package/dist/editor/ui/SimpleIconButton.js +3 -1
  119. package/dist/editor/ui/SimpleIconButton.js.map +1 -1
  120. package/dist/editor/ui/SimpleMenu.d.ts +1 -8
  121. package/dist/editor/ui/SimpleMenu.js +1 -1
  122. package/dist/editor/ui/SimpleMenu.js.map +1 -1
  123. package/dist/editor/utils.d.ts +2 -2
  124. package/dist/editor/utils.js +57 -9
  125. package/dist/editor/utils.js.map +1 -1
  126. package/dist/editor/views/CompareView.js +4 -13
  127. package/dist/editor/views/CompareView.js.map +1 -1
  128. package/dist/editor/views/EditView.js +2 -2
  129. package/dist/editor/views/EditView.js.map +1 -1
  130. package/dist/editor/views/SingleEditView.d.ts +2 -2
  131. package/dist/editor/views/SingleEditView.js +2 -2
  132. package/dist/editor/views/SingleEditView.js.map +1 -1
  133. package/dist/lib/safelist.js +1 -1
  134. package/dist/lib/safelist.js.map +1 -1
  135. package/dist/page-wizard/steps/BuildPageStep.js +2 -2
  136. package/dist/page-wizard/steps/BuildPageStep.js.map +1 -1
  137. package/dist/page-wizard/steps/CreatePageAndLayoutStep.js +2 -2
  138. package/dist/page-wizard/steps/CreatePageAndLayoutStep.js.map +1 -1
  139. package/dist/splash-screen/SplashScreen.js +0 -1
  140. package/dist/splash-screen/SplashScreen.js.map +1 -1
  141. package/dist/styles.css +275 -58
  142. package/dist/types.d.ts +20 -2
  143. package/package.json +6 -2
  144. package/src/components/ui/context-menu.tsx +250 -0
  145. package/src/config/config.tsx +4 -4
  146. package/src/config/types.ts +4 -2
  147. package/src/editor/ComponentInfo.tsx +3 -5
  148. package/src/editor/ConfirmationDialog.tsx +1 -1
  149. package/src/editor/ContextMenu.tsx +68 -19
  150. package/src/editor/EditorWarnings.tsx +2 -2
  151. package/src/editor/FieldList.tsx +6 -6
  152. package/src/editor/FieldListFieldWithFallbacks.tsx +9 -9
  153. package/src/editor/ImageEditor.tsx +2 -2
  154. package/src/editor/ItemInfo.tsx +4 -4
  155. package/src/editor/MainLayout.tsx +3 -4
  156. package/src/editor/Titlebar.tsx +4 -4
  157. package/src/editor/ai/AiTerminal.tsx +31 -24
  158. package/src/editor/client/EditorClient.tsx +106 -57
  159. package/src/editor/client/editContext.ts +13 -4
  160. package/src/editor/client/operations.ts +162 -23
  161. package/src/editor/client/pageModelBuilder.ts +26 -18
  162. package/src/editor/commands/componentCommands.tsx +58 -39
  163. package/src/editor/component-designer/ComponentDesigner.tsx +1 -1
  164. package/src/editor/componentTreeHelper.tsx +3 -2
  165. package/src/editor/control-center/ControlCenterMenu.tsx +4 -4
  166. package/src/editor/field-types/TreeListEditor.tsx +11 -11
  167. package/src/editor/menubar/LanguageSelector.tsx +6 -6
  168. package/src/editor/menubar/PageSelector.tsx +11 -11
  169. package/src/editor/menubar/PageViewerControls.tsx +49 -23
  170. package/src/editor/menubar/Separator.tsx +2 -2
  171. package/src/editor/menubar/VersionSelector.tsx +1 -1
  172. package/src/editor/page-editor-chrome/FrameMenu.tsx +94 -29
  173. package/src/editor/page-editor-chrome/FrameMenus.tsx +6 -6
  174. package/src/editor/page-editor-chrome/InlineEditor.tsx +237 -26
  175. package/src/editor/page-editor-chrome/PageEditorChrome.tsx +11 -14
  176. package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +12 -15
  177. package/src/editor/page-editor-chrome/PlaceholderDropZones.tsx +159 -68
  178. package/src/editor/page-viewer/EditorForm.tsx +15 -9
  179. package/src/editor/page-viewer/MiniMap.tsx +4 -4
  180. package/src/editor/page-viewer/PageViewer.tsx +6 -6
  181. package/src/editor/page-viewer/PageViewerFrame.tsx +146 -309
  182. package/src/editor/page-viewer/pageModelBuilder.ts +412 -0
  183. package/src/editor/pageModel.ts +5 -0
  184. package/src/editor/reviews/Comments.tsx +56 -15
  185. package/src/editor/reviews/DiffView.tsx +109 -0
  186. package/src/editor/reviews/SuggestedEdit.tsx +316 -0
  187. package/src/editor/services/suggestedEditsService.ts +39 -0
  188. package/src/editor/sidebar/ComponentPalette.tsx +108 -106
  189. package/src/editor/sidebar/ComponentTree.tsx +10 -5
  190. package/src/editor/sidebar/MainContentTree.tsx +1 -1
  191. package/src/editor/sidebar/SidebarView.tsx +9 -9
  192. package/src/editor/ui/CopyToClipboardButton.tsx +2 -1
  193. package/src/editor/ui/Icons.tsx +0 -18
  194. package/src/editor/ui/PerfectTree.tsx +5 -5
  195. package/src/editor/ui/Section.tsx +4 -4
  196. package/src/editor/ui/SimpleIconButton.tsx +5 -3
  197. package/src/editor/ui/SimpleMenu.tsx +5 -13
  198. package/src/editor/utils.ts +74 -17
  199. package/src/editor/views/CompareView.tsx +13 -24
  200. package/src/editor/views/EditView.tsx +2 -2
  201. package/src/editor/views/SingleEditView.tsx +3 -3
  202. package/src/lib/safelist.tsx +4 -0
  203. package/src/page-wizard/steps/BuildPageStep.tsx +18 -25
  204. package/src/page-wizard/steps/CreatePageAndLayoutStep.tsx +16 -18
  205. package/src/splash-screen/SplashScreen.tsx +0 -1
  206. package/src/types.ts +20 -3
  207. 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 { useEditContext, useEditContextRef } from "../client/editContext";
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
- mode,
43
+ compareView,
47
44
  pageViewContext,
48
45
  }: {
49
- mode: "edit" | "compare" | "view";
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
- renderUrl.searchParams.set(
405
- "sc_mode",
406
- editContext.previewMode ? "preview" : "edit",
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.previewMode ? "preview" : "edit",
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.previewMode,
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
- if (mode === "edit" && !editContext.previewMode) injectEditorCSS(doc);
265
+ injectEditorCSS(doc, editContext.mode !== "preview");
535
266
 
536
- buildPageModel(doc);
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 rect = findComponentRect(
548
- iframeRef.current!,
282
+ const component = getComponentById(
549
283
  editContext.scrollIntoView,
550
- true,
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: fieldId,
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?.setCurrentOverlay(undefined);
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?.select([componentId]);
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 (hasLock) {
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(iframeDocument);
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 (mode === "edit") pageViewContextRef.current?.setScroll(e);
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
- mode={mode || "edit"}
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
- mode={mode}
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
- export function injectEditorCSS(iframeDocument: Document) {
730
+ function injectEditorCSS(iframeDocument: Document, editMode: boolean) {
984
731
  if (!iframeDocument) return;
985
732
  const style = iframeDocument.createElement("style");
986
- style.textContent = `[contentEditable]:empty:before {
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.