@alpaca-editor/core 1.0.3941 → 1.0.3943

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 (308) hide show
  1. package/.prettierrc +3 -0
  2. package/build.css +3 -0
  3. package/components.json +21 -0
  4. package/dist/editor/ContentTree.d.ts +2 -1
  5. package/dist/editor/ContentTree.js +23 -21
  6. package/dist/editor/ContentTree.js.map +1 -1
  7. package/dist/editor/FieldActionsOverlay.js +0 -2
  8. package/dist/editor/FieldActionsOverlay.js.map +1 -1
  9. package/dist/editor/ScrollingContentTree.js +1 -1
  10. package/dist/editor/ScrollingContentTree.js.map +1 -1
  11. package/dist/editor/Titlebar.js +1 -1
  12. package/dist/editor/Titlebar.js.map +1 -1
  13. package/dist/editor/ai/GhostWriter.js +24 -3
  14. package/dist/editor/ai/GhostWriter.js.map +1 -1
  15. package/dist/editor/client/EditorClient.js +7 -7
  16. package/dist/editor/client/EditorClient.js.map +1 -1
  17. package/dist/editor/field-types/InternalLinkFieldEditor.js +60 -10
  18. package/dist/editor/field-types/InternalLinkFieldEditor.js.map +1 -1
  19. package/dist/editor/media-selector/MediaFolderBrowser.js +48 -1
  20. package/dist/editor/media-selector/MediaFolderBrowser.js.map +1 -1
  21. package/dist/editor/menubar/PageSelector.js +116 -65
  22. package/dist/editor/menubar/PageSelector.js.map +1 -1
  23. package/dist/editor/page-viewer/EditorForm.js +5 -2
  24. package/dist/editor/page-viewer/EditorForm.js.map +1 -1
  25. package/dist/editor/ui/ItemSearch.js +14 -8
  26. package/dist/editor/ui/ItemSearch.js.map +1 -1
  27. package/dist/editor/ui/PerfectTree.d.ts +4 -2
  28. package/dist/editor/ui/PerfectTree.js +78 -4
  29. package/dist/editor/ui/PerfectTree.js.map +1 -1
  30. package/dist/editor/ui/Splitter.js +1 -1
  31. package/dist/revision.d.ts +2 -2
  32. package/dist/revision.js +2 -2
  33. package/dist/styles.css +8 -2
  34. package/eslint.config.mjs +4 -0
  35. package/images/bg-shape-black.webp +0 -0
  36. package/images/wizard-bg.png +0 -0
  37. package/images/wizard-tour.png +0 -0
  38. package/images/wizard.png +0 -0
  39. package/package.json +2 -8
  40. package/src/client-components/api.ts +6 -0
  41. package/src/client-components/index.ts +19 -0
  42. package/src/components/ActionButton.tsx +50 -0
  43. package/src/components/Error.tsx +57 -0
  44. package/src/components/ui/CardConnector.tsx +56 -0
  45. package/src/components/ui/button.tsx +62 -0
  46. package/src/components/ui/card.tsx +372 -0
  47. package/src/components/ui/context-menu.tsx +250 -0
  48. package/src/config/config.tsx +917 -0
  49. package/src/config/types.ts +286 -0
  50. package/src/editor/ComponentInfo.tsx +90 -0
  51. package/src/editor/ConfirmationDialog.tsx +103 -0
  52. package/src/editor/ContentTree.tsx +733 -0
  53. package/src/editor/ContextMenu.tsx +230 -0
  54. package/src/editor/Editor.tsx +90 -0
  55. package/src/editor/EditorWarning.tsx +34 -0
  56. package/src/editor/EditorWarnings.tsx +33 -0
  57. package/src/editor/FieldActionsOverlay.tsx +296 -0
  58. package/src/editor/FieldEditorPopup.tsx +65 -0
  59. package/src/editor/FieldHistory.tsx +75 -0
  60. package/src/editor/FieldList.tsx +190 -0
  61. package/src/editor/FieldListField.tsx +391 -0
  62. package/src/editor/FieldListFieldWithFallbacks.tsx +217 -0
  63. package/src/editor/FloatingToolbar.tsx +163 -0
  64. package/src/editor/ImageEditor.tsx +128 -0
  65. package/src/editor/ItemInfo.tsx +90 -0
  66. package/src/editor/LinkEditorDialog.tsx +196 -0
  67. package/src/editor/MainLayout.tsx +95 -0
  68. package/src/editor/MobileLayout.tsx +68 -0
  69. package/src/editor/NewEditorClient.tsx +11 -0
  70. package/src/editor/PictureCropper.tsx +568 -0
  71. package/src/editor/PictureEditor.tsx +301 -0
  72. package/src/editor/PictureEditorDialog.tsx +381 -0
  73. package/src/editor/PublishDialog.ignore +74 -0
  74. package/src/editor/ScrollingContentTree.tsx +68 -0
  75. package/src/editor/Terminal.tsx +227 -0
  76. package/src/editor/Titlebar.tsx +104 -0
  77. package/src/editor/ai/AiPopup.tsx +59 -0
  78. package/src/editor/ai/AiResponseMessage.tsx +106 -0
  79. package/src/editor/ai/AiTerminal.tsx +503 -0
  80. package/src/editor/ai/AiToolCall.tsx +61 -0
  81. package/src/editor/ai/EditorAiTerminal.tsx +20 -0
  82. package/src/editor/ai/GhostWriter.tsx +480 -0
  83. package/src/editor/ai/aiPageModel.ts +108 -0
  84. package/src/editor/ai/editorAiContext.ts +18 -0
  85. package/src/editor/client/AboutDialog.tsx +44 -0
  86. package/src/editor/client/EditorClient.tsx +2241 -0
  87. package/src/editor/client/GenericDialog.tsx +50 -0
  88. package/src/editor/client/editContext.ts +416 -0
  89. package/src/editor/client/helpers.ts +44 -0
  90. package/src/editor/client/itemsRepository.ts +574 -0
  91. package/src/editor/client/operations.ts +768 -0
  92. package/src/editor/client/pageModelBuilder.ts +219 -0
  93. package/src/editor/commands/commands.ts +22 -0
  94. package/src/editor/commands/componentCommands.tsx +431 -0
  95. package/src/editor/commands/createVersionCommand.ts +33 -0
  96. package/src/editor/commands/deleteVersionCommand.ts +71 -0
  97. package/src/editor/commands/itemCommands.tsx +351 -0
  98. package/src/editor/commands/localizeItem/LocalizeItemDialog.tsx +201 -0
  99. package/src/editor/commands/localizeItem/LocalizeItemUtils.ts +27 -0
  100. package/src/editor/commands/undo.ts +39 -0
  101. package/src/editor/component-designer/ComponentDesigner.tsx +70 -0
  102. package/src/editor/component-designer/ComponentDesignerAiTerminal.tsx +11 -0
  103. package/src/editor/component-designer/ComponentDesignerMenu.tsx +91 -0
  104. package/src/editor/component-designer/ComponentEditor.tsx +97 -0
  105. package/src/editor/component-designer/ComponentRenderingCodeEditor.tsx +31 -0
  106. package/src/editor/component-designer/ComponentRenderingEditor.tsx +104 -0
  107. package/src/editor/component-designer/ComponentsDropdown.tsx +39 -0
  108. package/src/editor/component-designer/PlaceholdersEditor.tsx +179 -0
  109. package/src/editor/component-designer/RenderingsDropdown.tsx +36 -0
  110. package/src/editor/component-designer/TemplateEditor.tsx +236 -0
  111. package/src/editor/component-designer/aiContext.ts +23 -0
  112. package/src/editor/componentTreeHelper.tsx +116 -0
  113. package/src/editor/context-menu/CopyMoveMenu.tsx +103 -0
  114. package/src/editor/context-menu/InsertMenu.tsx +347 -0
  115. package/src/editor/control-center/About.tsx +342 -0
  116. package/src/editor/control-center/ControlCenterMenu.tsx +76 -0
  117. package/src/editor/control-center/IndexOverview.tsx +50 -0
  118. package/src/editor/control-center/IndexSettings.tsx +266 -0
  119. package/src/editor/control-center/Info.tsx +104 -0
  120. package/src/editor/control-center/QuotaInfo.tsx +301 -0
  121. package/src/editor/control-center/Status.tsx +113 -0
  122. package/src/editor/control-center/WebSocketMessages.tsx +155 -0
  123. package/src/editor/editor-warnings/ItemLocked.tsx +63 -0
  124. package/src/editor/editor-warnings/NoLanguageWriteAccess.tsx +22 -0
  125. package/src/editor/editor-warnings/NoWorkflowWriteAccess.tsx +23 -0
  126. package/src/editor/editor-warnings/NoWriteAccess.tsx +16 -0
  127. package/src/editor/editor-warnings/ValidationErrors.tsx +54 -0
  128. package/src/editor/field-types/AttachmentEditor.tsx +9 -0
  129. package/src/editor/field-types/CheckboxEditor.tsx +47 -0
  130. package/src/editor/field-types/DropLinkEditor.tsx +80 -0
  131. package/src/editor/field-types/DropListEditor.tsx +84 -0
  132. package/src/editor/field-types/ImageFieldEditor.tsx +65 -0
  133. package/src/editor/field-types/InternalLinkFieldEditor.tsx +188 -0
  134. package/src/editor/field-types/LinkFieldEditor.tsx +85 -0
  135. package/src/editor/field-types/MultiLineText.tsx +82 -0
  136. package/src/editor/field-types/PictureFieldEditor.tsx +121 -0
  137. package/src/editor/field-types/RawEditor.tsx +53 -0
  138. package/src/editor/field-types/ReactQuill.tsx +580 -0
  139. package/src/editor/field-types/RichTextEditor.tsx +22 -0
  140. package/src/editor/field-types/RichTextEditorComponent.tsx +127 -0
  141. package/src/editor/field-types/SingleLineText.tsx +174 -0
  142. package/src/editor/field-types/TreeListEditor.tsx +261 -0
  143. package/src/editor/fieldTypes.ts +140 -0
  144. package/src/editor/media-selector/AiImageSearch.tsx +185 -0
  145. package/src/editor/media-selector/AiImageSearchPrompt.tsx +94 -0
  146. package/src/editor/media-selector/MediaFolderBrowser.tsx +321 -0
  147. package/src/editor/media-selector/MediaSelector.tsx +42 -0
  148. package/src/editor/media-selector/Preview.tsx +14 -0
  149. package/src/editor/media-selector/Thumbnails.tsx +48 -0
  150. package/src/editor/media-selector/TreeSelector.tsx +292 -0
  151. package/src/editor/media-selector/UploadZone.tsx +137 -0
  152. package/src/editor/media-selector/index.ts +8 -0
  153. package/src/editor/menubar/ActionsMenu.tsx +94 -0
  154. package/src/editor/menubar/ActiveUsers.tsx +17 -0
  155. package/src/editor/menubar/ApproveAndPublish.tsx +18 -0
  156. package/src/editor/menubar/BrowseHistory.tsx +28 -0
  157. package/src/editor/menubar/ItemLanguageVersion.tsx +76 -0
  158. package/src/editor/menubar/LanguageSelector.tsx +226 -0
  159. package/src/editor/menubar/Menu.tsx +83 -0
  160. package/src/editor/menubar/NavButtons.tsx +74 -0
  161. package/src/editor/menubar/PageSelector.tsx +278 -0
  162. package/src/editor/menubar/PageViewerControls.tsx +120 -0
  163. package/src/editor/menubar/PreviewSecondaryControls.tsx +18 -0
  164. package/src/editor/menubar/SecondaryControls.tsx +45 -0
  165. package/src/editor/menubar/Separator.tsx +12 -0
  166. package/src/editor/menubar/SiteInfo.tsx +53 -0
  167. package/src/editor/menubar/User.tsx +27 -0
  168. package/src/editor/menubar/VersionSelector.tsx +142 -0
  169. package/src/editor/page-editor-chrome/CommentHighlighting.tsx +307 -0
  170. package/src/editor/page-editor-chrome/CommentHighlightings.tsx +35 -0
  171. package/src/editor/page-editor-chrome/FieldActionIndicator.tsx +59 -0
  172. package/src/editor/page-editor-chrome/FieldActionIndicators.tsx +23 -0
  173. package/src/editor/page-editor-chrome/FieldEditedIndicator.tsx +64 -0
  174. package/src/editor/page-editor-chrome/FieldEditedIndicators.tsx +35 -0
  175. package/src/editor/page-editor-chrome/FrameMenu.tsx +338 -0
  176. package/src/editor/page-editor-chrome/FrameMenus.tsx +48 -0
  177. package/src/editor/page-editor-chrome/InlineEditor.tsx +765 -0
  178. package/src/editor/page-editor-chrome/LockedFieldIndicator.tsx +61 -0
  179. package/src/editor/page-editor-chrome/NoLayout.tsx +36 -0
  180. package/src/editor/page-editor-chrome/PageEditorChrome.tsx +122 -0
  181. package/src/editor/page-editor-chrome/PictureEditorOverlay.tsx +161 -0
  182. package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +169 -0
  183. package/src/editor/page-editor-chrome/PlaceholderDropZones.tsx +315 -0
  184. package/src/editor/page-editor-chrome/SuggestionHighlighting.tsx +300 -0
  185. package/src/editor/page-editor-chrome/SuggestionHighlightings.tsx +40 -0
  186. package/src/editor/page-editor-chrome/useInlineAICompletion.tsx +828 -0
  187. package/src/editor/page-viewer/DeviceToolbar.tsx +70 -0
  188. package/src/editor/page-viewer/EditorForm.tsx +262 -0
  189. package/src/editor/page-viewer/MiniMap.tsx +362 -0
  190. package/src/editor/page-viewer/PageViewer.tsx +169 -0
  191. package/src/editor/page-viewer/PageViewerFrame.tsx +1022 -0
  192. package/src/editor/page-viewer/pageModelSkeletonBuilder.ts +412 -0
  193. package/src/editor/page-viewer/pageViewContext.ts +186 -0
  194. package/src/editor/pageModel.ts +220 -0
  195. package/src/editor/picture-shared.tsx +53 -0
  196. package/src/editor/reviews/Comment.tsx +308 -0
  197. package/src/editor/reviews/Comments.tsx +125 -0
  198. package/src/editor/reviews/DiffView.tsx +109 -0
  199. package/src/editor/reviews/PreviewInfo.tsx +35 -0
  200. package/src/editor/reviews/Reviews.tsx +280 -0
  201. package/src/editor/reviews/SuggestedEdit.tsx +316 -0
  202. package/src/editor/reviews/reviewCommands.tsx +47 -0
  203. package/src/editor/reviews/useReviews.tsx +70 -0
  204. package/src/editor/services/aiService.ts +173 -0
  205. package/src/editor/services/componentDesignerService.ts +151 -0
  206. package/src/editor/services/contentService.ts +180 -0
  207. package/src/editor/services/editService.ts +488 -0
  208. package/src/editor/services/indexService.ts +24 -0
  209. package/src/editor/services/reviewsService.ts +53 -0
  210. package/src/editor/services/serviceHelper.ts +95 -0
  211. package/src/editor/services/suggestedEditsService.ts +39 -0
  212. package/src/editor/services/systemService.ts +5 -0
  213. package/src/editor/services/translationService.ts +21 -0
  214. package/src/editor/services-server/api.ts +150 -0
  215. package/src/editor/services-server/graphQL.ts +106 -0
  216. package/src/editor/sidebar/ComponentPalette.tsx +161 -0
  217. package/src/editor/sidebar/ComponentTree.tsx +549 -0
  218. package/src/editor/sidebar/Debug.tsx +111 -0
  219. package/src/editor/sidebar/DictionaryEditor.tsx +261 -0
  220. package/src/editor/sidebar/EditHistory.tsx +134 -0
  221. package/src/editor/sidebar/GraphQL.tsx +164 -0
  222. package/src/editor/sidebar/Insert.tsx +35 -0
  223. package/src/editor/sidebar/MainContentTree.tsx +102 -0
  224. package/src/editor/sidebar/Performance.tsx +53 -0
  225. package/src/editor/sidebar/Sessions.tsx +35 -0
  226. package/src/editor/sidebar/Sidebar.tsx +20 -0
  227. package/src/editor/sidebar/SidebarView.tsx +152 -0
  228. package/src/editor/sidebar/Translations.tsx +295 -0
  229. package/src/editor/sidebar/Validation.tsx +102 -0
  230. package/src/editor/sidebar/ViewSelector.tsx +60 -0
  231. package/src/editor/sidebar/Workbox.tsx +209 -0
  232. package/src/editor/ui/CenteredMessage.tsx +7 -0
  233. package/src/editor/ui/CopyMoveTargetSelectorDialog.tsx +81 -0
  234. package/src/editor/ui/CopyToClipboardButton.tsx +24 -0
  235. package/src/editor/ui/DialogButtons.tsx +11 -0
  236. package/src/editor/ui/Icons.tsx +709 -0
  237. package/src/editor/ui/ItemList.tsx +76 -0
  238. package/src/editor/ui/ItemNameDialogNew.tsx +118 -0
  239. package/src/editor/ui/ItemSearch.tsx +159 -0
  240. package/src/editor/ui/PerfectTree.tsx +676 -0
  241. package/src/editor/ui/Section.tsx +35 -0
  242. package/src/editor/ui/SimpleIconButton.tsx +54 -0
  243. package/src/editor/ui/SimpleMenu.tsx +40 -0
  244. package/src/editor/ui/SimpleTable.tsx +60 -0
  245. package/src/editor/ui/SimpleTabs.tsx +60 -0
  246. package/src/editor/ui/SimpleToolbar.tsx +7 -0
  247. package/src/editor/ui/Spinner.tsx +9 -0
  248. package/src/editor/ui/Splitter.tsx +420 -0
  249. package/src/editor/ui/StackedPanels.tsx +134 -0
  250. package/src/editor/ui/Toolbar.tsx +7 -0
  251. package/src/editor/utils/id-helper.ts +3 -0
  252. package/src/editor/utils/insertOptions.ts +69 -0
  253. package/src/editor/utils/itemutils.ts +29 -0
  254. package/src/editor/utils/useMemoDebug.ts +28 -0
  255. package/src/editor/utils.ts +486 -0
  256. package/src/editor/views/CompareView.tsx +245 -0
  257. package/src/editor/views/EditView.tsx +27 -0
  258. package/src/editor/views/ItemEditor.tsx +58 -0
  259. package/src/editor/views/MediaFolderEditView.tsx +66 -0
  260. package/src/editor/views/SingleEditView.tsx +57 -0
  261. package/src/fonts/Geist-Black.woff2 +0 -0
  262. package/src/fonts/Geist-Bold.woff2 +0 -0
  263. package/src/fonts/Geist-ExtraBold.woff2 +0 -0
  264. package/src/fonts/Geist-ExtraLight.woff2 +0 -0
  265. package/src/fonts/Geist-Light.woff2 +0 -0
  266. package/src/fonts/Geist-Medium.woff2 +0 -0
  267. package/src/fonts/Geist-Regular.woff2 +0 -0
  268. package/src/fonts/Geist-SemiBold.woff2 +0 -0
  269. package/src/fonts/Geist-Thin.woff2 +0 -0
  270. package/src/fonts/Geist[wght].woff2 +0 -0
  271. package/src/fonts/index.ts +10 -0
  272. package/src/index.ts +23 -0
  273. package/src/lib/safelist.tsx +16 -0
  274. package/src/lib/utils.ts +6 -0
  275. package/src/page-wizard/PageWizard.tsx +139 -0
  276. package/src/page-wizard/WizardBox.tsx +4 -0
  277. package/src/page-wizard/WizardBoxConnector.tsx +56 -0
  278. package/src/page-wizard/WizardSteps.tsx +458 -0
  279. package/src/page-wizard/service.ts +35 -0
  280. package/src/page-wizard/startPageWizardCommand.ts +26 -0
  281. package/src/page-wizard/steps/BuildPageStep.tsx +259 -0
  282. package/src/page-wizard/steps/CollectStep.tsx +296 -0
  283. package/src/page-wizard/steps/ComponentTypesSelector.tsx +454 -0
  284. package/src/page-wizard/steps/Components.tsx +193 -0
  285. package/src/page-wizard/steps/ContentStep.tsx +890 -0
  286. package/src/page-wizard/steps/EditButton.tsx +34 -0
  287. package/src/page-wizard/steps/FieldEditor.tsx +102 -0
  288. package/src/page-wizard/steps/Generate.tsx +60 -0
  289. package/src/page-wizard/steps/ImagesStep.tsx +382 -0
  290. package/src/page-wizard/steps/LayoutStep.tsx +227 -0
  291. package/src/page-wizard/steps/MetaDataStep.tsx +173 -0
  292. package/src/page-wizard/steps/SelectStep.tsx +281 -0
  293. package/src/page-wizard/steps/schema.ts +180 -0
  294. package/src/page-wizard/steps/usePageCreator.ts +325 -0
  295. package/src/page-wizard/usePageWizard.ts +79 -0
  296. package/src/revision.ts +2 -0
  297. package/src/splash-screen/NewPage.tsx +294 -0
  298. package/src/splash-screen/OpenPage.tsx +113 -0
  299. package/src/splash-screen/RecentPages.tsx +123 -0
  300. package/src/splash-screen/SectionHeadline.tsx +21 -0
  301. package/src/splash-screen/SplashScreen.tsx +195 -0
  302. package/src/tour/Tour.tsx +566 -0
  303. package/src/tour/default-tour.tsx +301 -0
  304. package/src/tour/preview-tour.tsx +128 -0
  305. package/src/types.ts +335 -0
  306. package/styles.css +765 -0
  307. package/tsconfig.build.json +31 -0
  308. package/tsconfig.json +14 -0
@@ -0,0 +1,486 @@
1
+ import React, { useState } from "react";
2
+ import { useEffect, useRef } from "react";
3
+
4
+ import { EditContextType } from "./client/editContext";
5
+
6
+ import { FieldDescriptor } from "../types";
7
+ import { Field, FullItem, ItemDescriptor, Component } from "./pageModel";
8
+
9
+ export type Rect = {
10
+ x: number;
11
+ y: number;
12
+ width: number;
13
+ height: number;
14
+ };
15
+
16
+ // Hook
17
+ export function useEventListenerExt(
18
+ eventName: string,
19
+ handler: any,
20
+ element: HTMLElement | Window,
21
+ capture = false,
22
+ ) {
23
+ // Create a ref that stores handler
24
+ const savedHandler = useRef<any>(undefined);
25
+
26
+ // Update ref.current value if handler changes.
27
+ // This allows our effect below to always get latest handler ...
28
+ // ... without us needing to pass it in effect deps array ...
29
+ // ... and potentially cause effect to re-run every render.
30
+ useEffect(() => {
31
+ savedHandler.current = handler;
32
+ }, [handler]);
33
+
34
+ useEffect(
35
+ () => {
36
+ // Make sure element supports addEventListener
37
+ // On
38
+ const isSupported = element && element.addEventListener;
39
+ if (!isSupported) return;
40
+
41
+ // Create event listener that calls handler function stored in ref
42
+ const eventListener = (event: Event) => savedHandler.current(event);
43
+
44
+ // Add event listener
45
+ element.addEventListener(eventName, eventListener, { capture: capture });
46
+
47
+ // Remove event listener on cleanup
48
+ return () => {
49
+ element.removeEventListener(eventName, eventListener);
50
+ };
51
+ },
52
+ [eventName, element], // Re-run if eventName or element changes
53
+ );
54
+ }
55
+
56
+ export const useLocalStorage = <T>(
57
+ storageKey: string,
58
+ fallbackState: T,
59
+ ): [T, React.Dispatch<React.SetStateAction<T>>] => {
60
+ const [value, setValue] = useState<T>(
61
+ JSON.parse(
62
+ typeof window !== "undefined"
63
+ ? (localStorage.getItem(storageKey) ?? JSON.stringify(fallbackState))
64
+ : JSON.stringify(fallbackState),
65
+ ),
66
+ );
67
+
68
+ useEffect(() => {
69
+ if (typeof window !== "undefined")
70
+ localStorage.setItem(storageKey, JSON.stringify(value));
71
+ }, [value, storageKey]);
72
+
73
+ return [value, setValue];
74
+ };
75
+
76
+ export function isFieldActionExecuting(
77
+ field: Field,
78
+ editContext: EditContextType,
79
+ ) {
80
+ const fieldItem = field.descriptor.item;
81
+
82
+ if (!fieldItem) {
83
+ return false;
84
+ }
85
+
86
+ var action = editContext.activeFieldActions.find(
87
+ (x) =>
88
+ x.field.fieldId == field.id &&
89
+ x.field.item?.id == fieldItem.id &&
90
+ x.field.item?.language == fieldItem.language &&
91
+ x.field.item?.version == fieldItem.version,
92
+ );
93
+
94
+ return action?.state == "running";
95
+ }
96
+
97
+ export function getItemDescriptor(
98
+ item: FullItem | ItemDescriptor,
99
+ ): ItemDescriptor {
100
+ if (!item) throw new Error("Item is null");
101
+
102
+ if ("descriptor" in item) {
103
+ return item.descriptor;
104
+ }
105
+
106
+ return {
107
+ id: item!.id,
108
+ language: item!.language,
109
+ version: item!.version,
110
+ name: item!.name,
111
+ };
112
+ }
113
+
114
+ export function getAbsoluteIconUrl(url: string) {
115
+ //return configuration.services.editorService.baseUrl + url;
116
+ return url;
117
+ }
118
+
119
+ export function findParentWithAttribute(
120
+ element: HTMLElement,
121
+ attr: string,
122
+ ): HTMLElement | null {
123
+ while (element && element !== document.documentElement) {
124
+ if (element.hasAttribute(attr)) {
125
+ return element;
126
+ }
127
+ element = element.parentElement as HTMLElement;
128
+ }
129
+ return null;
130
+ }
131
+
132
+ export function parsePlaceholderKey(key: string) {
133
+ const placeholderKeyComponents = key.split("_");
134
+
135
+ const placeholderName =
136
+ placeholderKeyComponents.length === 1
137
+ ? placeholderKeyComponents[0]
138
+ : placeholderKeyComponents[1];
139
+ const parentId =
140
+ placeholderKeyComponents.length === 1
141
+ ? undefined
142
+ : placeholderKeyComponents[0];
143
+ return {
144
+ name: placeholderName,
145
+ componentId: parentId,
146
+ };
147
+ }
148
+
149
+ // export function getFieldRawValue(field: Field, editContext: EditContextType) {
150
+ // return (
151
+ // getModifiedField(field.descriptor, editContext)?.rawValue ??
152
+ // field.rawValue ??
153
+ // field.value
154
+ // );
155
+ // }
156
+
157
+ // export function getFieldValue(field: Field, editContext: EditContextType) {
158
+ // return getModifiedField(field.descriptor, editContext)?.value ?? field.value;
159
+ // }
160
+
161
+ // export function getModifiedField(
162
+ // field: FieldDescriptor,
163
+ // editContext: EditContextType
164
+ // ) {
165
+ // const modifiedField = editContext.modifiedFields.find(
166
+ // (x) =>
167
+ // x.field.fieldId === field.fieldId &&
168
+ // x.field.item.id === field.item.id &&
169
+ // x.field.item.language === field.item.language &&
170
+ // x.field.item.version === field.item.version
171
+ // );
172
+
173
+ // return modifiedField;
174
+ // }
175
+
176
+ // export function getModifiedFieldValue(
177
+ // field: FieldDescriptor,
178
+ // editContext: EditContextType
179
+ // ) {
180
+ // return getModifiedField(field, editContext)?.value;
181
+ // }
182
+
183
+ // export function setModifiedFieldValue(
184
+ // field: FieldDescriptor,
185
+ // value: string,
186
+ // editContext: EditContextType
187
+ // ) {
188
+ // const modifiedValue = editContext.modifiedFields.find(
189
+ // (x) =>
190
+ // x.field.fieldId === field.fieldId &&
191
+ // x.field.item.id === field.item.id &&
192
+ // x.field.item.language === field.item.language &&
193
+ // x.field.item.version === field.item.version
194
+ // );
195
+
196
+ // if (modifiedValue) {
197
+ // modifiedValue.value = value;
198
+ // } else {
199
+ // editContext.modifiedFields.push({
200
+ // field: field,
201
+ // value: value,
202
+ // });
203
+ // }
204
+
205
+ // editContext.setModifiedFields([...editContext.modifiedFields]);
206
+ // }
207
+
208
+ export function hasFieldLock(
209
+ field: FieldDescriptor,
210
+ editContext: EditContextType,
211
+ ) {
212
+ if (!editContext.lockedField) {
213
+ return false;
214
+ }
215
+ return (
216
+ editContext.lockedField.fieldId === field.fieldId &&
217
+ editContext.lockedField.item.id === field.item.id &&
218
+ editContext.lockedField.item.language === field.item.language &&
219
+ editContext.lockedField.item.version === field.item.version
220
+ );
221
+ }
222
+
223
+ export function getSessionWithFieldLock(
224
+ field: FieldDescriptor,
225
+ editContext: EditContextType,
226
+ ) {
227
+ return editContext.activeSessions.find(
228
+ (s) =>
229
+ s.fieldLock?.fieldId === field.fieldId &&
230
+ s.fieldLock?.fieldId === field.fieldId &&
231
+ s.fieldLock?.item.id === field.item.id &&
232
+ s.fieldLock?.item.language === field.item.language &&
233
+ s.fieldLock?.item.version === field.item.version,
234
+ );
235
+ }
236
+
237
+ export function getFieldDescriptorFromElement(
238
+ element: Element,
239
+ ): FieldDescriptor {
240
+ return {
241
+ item: {
242
+ id: element.getAttribute("data-itemid")!,
243
+ version: parseInt(element.getAttribute("data-version")!),
244
+ language: element.getAttribute("data-language")!,
245
+ },
246
+ fieldId: element.getAttribute("data-fieldid")!,
247
+ };
248
+ }
249
+
250
+ export function findNearestComponentId(startElement: Element) {
251
+ let element: Element | null = startElement;
252
+ while (element) {
253
+ if (element.hasAttribute("data-component-start")) {
254
+ return element.getAttribute("data-component-start") ?? undefined;
255
+ }
256
+ const prev: Element | null = element.previousElementSibling;
257
+ if (!prev) {
258
+ element = element.parentElement;
259
+ } else element = prev;
260
+ }
261
+ return;
262
+ }
263
+
264
+ export function findFieldElement(
265
+ iframe: HTMLIFrameElement,
266
+ fieldDescriptor: FieldDescriptor,
267
+ ) {
268
+ if (!iframe.contentWindow?.document.body) return undefined;
269
+
270
+ const fieldElement = iframe.contentWindow?.document.body.querySelector(
271
+ "[data-itemid='" +
272
+ fieldDescriptor.item.id +
273
+ "'][data-language='" +
274
+ fieldDescriptor.item.language +
275
+ "'][data-version='" +
276
+ fieldDescriptor.item.version +
277
+ "'][data-fieldid='" +
278
+ fieldDescriptor.fieldId +
279
+ "']",
280
+ );
281
+
282
+ return fieldElement;
283
+ }
284
+
285
+ export function findComponentRect(
286
+ iframe: HTMLIFrameElement,
287
+ component: Component,
288
+ takeScrollPositionIntoAccount = false,
289
+ ) {
290
+ if (!iframe.contentWindow?.document.body) return undefined;
291
+
292
+ let startElement: Element | undefined | null = component.firstDOMElement;
293
+
294
+ while (startElement && startElement.tagName === "SCRIPT") {
295
+ startElement = startElement.nextElementSibling;
296
+ }
297
+
298
+ if (!startElement) {
299
+ console.error("No start element found for component " + component.id);
300
+ return null;
301
+ }
302
+
303
+ const startRect = takeScrollPositionIntoAccount
304
+ ? getAbsolutePosition(startElement as HTMLElement, iframe)
305
+ : startElement.getBoundingClientRect();
306
+
307
+ let endElement: Element | undefined | null = component.lastDOMElement;
308
+
309
+ while (endElement && endElement.tagName === "SCRIPT") {
310
+ endElement = endElement.previousElementSibling;
311
+ }
312
+
313
+ if (!endElement) return null;
314
+
315
+ const endRect = takeScrollPositionIntoAccount
316
+ ? getAbsolutePosition(endElement as HTMLElement, iframe)
317
+ : endElement.getBoundingClientRect();
318
+
319
+ const elements =
320
+ startElement === endElement ? [startElement] : [startElement, endElement];
321
+
322
+ return {
323
+ rect: {
324
+ x: startRect.x,
325
+ y: startRect.y,
326
+ width: endRect.x + endRect.width - startRect.x,
327
+ height: endRect.y + endRect.height - startRect.y,
328
+ },
329
+ elements: elements,
330
+ };
331
+ }
332
+
333
+ // export function findComponentRect(
334
+ // iframe: HTMLIFrameElement,
335
+ // componentId: string,
336
+ // takeScrollPositionIntoAccount = false,
337
+ // ) {
338
+ // if (!iframe.contentWindow?.document.body) return undefined;
339
+
340
+ // const componentStart = iframe.contentWindow?.document.body.querySelector(
341
+ // "[data-component-start='" + componentId + "']",
342
+ // );
343
+
344
+ // const componentEnd = iframe?.contentWindow?.document.body.querySelector(
345
+ // "[data-component-end='" + componentId + "']",
346
+ // );
347
+
348
+ // if (!componentStart || !componentEnd) {
349
+ // return null;
350
+ // }
351
+
352
+ // let startElement = componentStart.nextElementSibling;
353
+
354
+ // while (startElement && startElement.tagName === "SCRIPT") {
355
+ // startElement = startElement.nextElementSibling;
356
+ // }
357
+
358
+ // if (!startElement) {
359
+ // console.error("No start element found for component " + componentId);
360
+ // return null;
361
+ // }
362
+
363
+ // const startRect = takeScrollPositionIntoAccount
364
+ // ? getAbsolutePosition(startElement as HTMLElement, iframe)
365
+ // : startElement.getBoundingClientRect();
366
+
367
+ // let endElement = componentEnd.previousElementSibling;
368
+
369
+ // while (endElement && endElement.tagName === "SCRIPT") {
370
+ // endElement = endElement.previousElementSibling;
371
+ // }
372
+
373
+ // if (!endElement) return null;
374
+
375
+ // const endRect = takeScrollPositionIntoAccount
376
+ // ? getAbsolutePosition(endElement as HTMLElement, iframe)
377
+ // : endElement.getBoundingClientRect();
378
+
379
+ // const elements =
380
+ // startElement === endElement ? [startElement] : [startElement, endElement];
381
+
382
+ // // console.log(
383
+ // // "start rect",
384
+ // // startRect,
385
+ // // startElement,
386
+ // // iframe.contentWindow?.scrollY,
387
+ // // takeScrollPositionIntoAccount
388
+ // // );
389
+
390
+ // return {
391
+ // rect: {
392
+ // x: startRect.x,
393
+ // y: startRect.y,
394
+ // width: endRect.x + endRect.width - startRect.x,
395
+ // height: endRect.y + endRect.height - startRect.y,
396
+ // },
397
+ // elements: elements,
398
+ // };
399
+ // }
400
+
401
+ export const getAbsolutePosition = (
402
+ element: HTMLElement,
403
+ iframe: HTMLIFrameElement,
404
+ ) => {
405
+ const rect = element.getBoundingClientRect();
406
+ const scrollLeft =
407
+ iframe.contentWindow?.scrollX ||
408
+ iframe.contentDocument?.documentElement.scrollLeft ||
409
+ 0;
410
+ const scrollTop =
411
+ iframe.contentWindow?.scrollY ||
412
+ iframe.contentDocument?.documentElement.scrollTop ||
413
+ 0;
414
+
415
+ return {
416
+ x: rect.left + scrollLeft,
417
+ y: rect.top + scrollTop,
418
+ width: rect.width,
419
+ height: rect.height,
420
+ };
421
+ };
422
+
423
+ export function findParentComponentId(element: HTMLElement) {
424
+ while (element && element !== document.documentElement) {
425
+ const startElement = findStartElement(element);
426
+
427
+ if (startElement) {
428
+ return startElement.getAttribute("data-component-start");
429
+ }
430
+ element = element.parentElement as HTMLElement;
431
+ }
432
+ return null;
433
+ }
434
+
435
+ function findStartElement(element: HTMLElement) {
436
+ let prev: Element | null = element;
437
+ while (prev) {
438
+ prev = prev.previousElementSibling;
439
+ if (prev?.getAttribute("data-component-start")) {
440
+ return prev;
441
+ }
442
+ }
443
+ return null;
444
+ }
445
+
446
+ export function normalizeGuid(id: string) {
447
+ id = id.toUpperCase();
448
+
449
+ if (id.length && id[0] === "{") return id;
450
+ return "{" + id + "}";
451
+ }
452
+
453
+ const dateOptions: Intl.DateTimeFormatOptions = {
454
+ year: "numeric",
455
+ month: "numeric",
456
+ day: "numeric",
457
+ hour: "numeric",
458
+ minute: "numeric",
459
+ second: "numeric",
460
+ hour12: false,
461
+ };
462
+
463
+ const dateFormat = Intl.DateTimeFormat(
464
+ typeof navigator !== "undefined" ? navigator.language : "en",
465
+ dateOptions,
466
+ );
467
+
468
+ export function formatDate(date: Date) {
469
+ return dateFormat.format(date);
470
+ }
471
+
472
+ export function findClosestFieldElement(node: Node | null): HTMLElement | null {
473
+ let current: Node | null = node;
474
+
475
+ while (current) {
476
+ if (current.nodeType === Node.ELEMENT_NODE) {
477
+ const element = current as Element;
478
+ if (element.hasAttribute("data-fieldid")) {
479
+ return element as HTMLElement;
480
+ }
481
+ }
482
+ current = current.parentNode;
483
+ }
484
+
485
+ return null;
486
+ }