ckeditor5-phoenix 1.27.1 → 1.28.0

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 (29) hide show
  1. package/dist/hooks/editable.d.ts.map +1 -1
  2. package/dist/hooks/editor/editor.d.ts.map +1 -1
  3. package/dist/hooks/editor/utils/assign-editor-roots-to-config.d.ts +14 -0
  4. package/dist/hooks/editor/utils/assign-editor-roots-to-config.d.ts.map +1 -0
  5. package/dist/hooks/editor/utils/index.d.ts +1 -2
  6. package/dist/hooks/editor/utils/index.d.ts.map +1 -1
  7. package/dist/hooks/editor/utils/query-all-editor-editables.d.ts +1 -16
  8. package/dist/hooks/editor/utils/query-all-editor-editables.d.ts.map +1 -1
  9. package/dist/index.cjs +2 -2
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.mjs +244 -277
  12. package/dist/index.mjs.map +1 -1
  13. package/package.json +3 -3
  14. package/src/hooks/editable.test.ts +29 -0
  15. package/src/hooks/editable.ts +3 -1
  16. package/src/hooks/editor/editor.test.ts +94 -0
  17. package/src/hooks/editor/editor.ts +22 -42
  18. package/src/hooks/editor/plugins/sync-editor-with-phoenix.ts +1 -1
  19. package/src/hooks/editor/utils/assign-editor-roots-to-config.ts +58 -0
  20. package/src/hooks/editor/utils/index.ts +1 -2
  21. package/src/hooks/editor/utils/query-all-editor-editables.ts +12 -35
  22. package/test-utils/editor/create-editable-html-element.ts +5 -0
  23. package/test-utils/editor/create-editor-html-element.ts +5 -0
  24. package/dist/hooks/editor/utils/assign-initial-data-to-editor-config.d.ts +0 -10
  25. package/dist/hooks/editor/utils/assign-initial-data-to-editor-config.d.ts.map +0 -1
  26. package/dist/hooks/editor/utils/assign-source-elements-to-editor-config.d.ts +0 -12
  27. package/dist/hooks/editor/utils/assign-source-elements-to-editor-config.d.ts.map +0 -1
  28. package/src/hooks/editor/utils/assign-initial-data-to-editor-config.ts +0 -47
  29. package/src/hooks/editor/utils/assign-source-elements-to-editor-config.ts +0 -60
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ckeditor5-phoenix",
3
- "version": "1.27.1",
3
+ "version": "1.28.0",
4
4
  "description": "CKEditor 5 integration for Phoenix Framework",
5
5
  "author": "Mateusz Bagiński <cziken58@gmail.com>",
6
6
  "license": "MIT",
@@ -24,8 +24,8 @@
24
24
  "test-utils"
25
25
  ],
26
26
  "dependencies": {
27
- "ckeditor5": "^48.1.0",
28
- "ckeditor5-premium-features": "^48.1.0",
27
+ "ckeditor5": "^48.2.0",
28
+ "ckeditor5-premium-features": "^48.2.0",
29
29
  "phoenix_live_view": "^1.0.17"
30
30
  },
31
31
  "devDependencies": {
@@ -105,6 +105,35 @@ describe('editable hook', () => {
105
105
 
106
106
  expect(editor.getData({ rootName: 'foo' })).toBe('<p>Foo</p>');
107
107
  });
108
+
109
+ it('should set proper root element name on initial added root', async () => {
110
+ const editable = createEditableHtmlElement({
111
+ name: 'foo',
112
+ initialValue: '<p>Foo</p>',
113
+ modelElement: '$inlineRoot',
114
+ });
115
+
116
+ document.body.appendChild(editable);
117
+
118
+ const editor = await appendMultirootEditor();
119
+ EditableHook.mounted.call({ el: editable });
120
+
121
+ expect(editor.model.document.getRoot('foo')?.name).to.be.equal('$inlineRoot');
122
+ });
123
+
124
+ it('should set proper root element name on lazy added root', async () => {
125
+ const editor = await appendMultirootEditor();
126
+ const editable = createEditableHtmlElement({
127
+ name: 'foo',
128
+ initialValue: '<p>Foo</p>',
129
+ modelElement: '$inlineRoot',
130
+ });
131
+
132
+ document.body.appendChild(editable);
133
+ EditableHook.mounted.call({ el: editable });
134
+
135
+ expect(editor.model.document.getRoot('foo')?.name).to.be.equal('$inlineRoot');
136
+ });
108
137
  });
109
138
 
110
139
  describe('value synchronization', () => {
@@ -22,6 +22,7 @@ class EditableHookImpl extends ClassHook {
22
22
  editableId: this.el.getAttribute('id')!,
23
23
  editorId: this.el.getAttribute('data-cke-editor-id') || null,
24
24
  rootName: this.el.getAttribute('data-cke-editable-root-name')!,
25
+ modelElement: this.el.getAttribute('data-cke-editable-root-model-element-name') || null,
25
26
  initialValue: this.el.getAttribute('data-cke-editable-initial-value') || '',
26
27
  };
27
28
 
@@ -39,7 +40,7 @@ class EditableHookImpl extends ClassHook {
39
40
  * Mounts the editable component.
40
41
  */
41
42
  override mounted() {
42
- const { editableId, editorId, rootName, initialValue } = this.attrs;
43
+ const { editableId, editorId, rootName, initialValue, modelElement } = this.attrs;
43
44
 
44
45
  const unmountEffect = EditorsRegistry.the.mountEffect(editorId, (editor: MultiRootEditor | DecoupledEditor) => {
45
46
  const contentElement = this.el.querySelector('[data-cke-editable-content]') as HTMLElement;
@@ -57,6 +58,7 @@ class EditableHookImpl extends ClassHook {
57
58
  editor.addRoot(rootName, {
58
59
  isUndoable: false,
59
60
  initialData: initialValue,
61
+ modelElement: modelElement || '$root',
60
62
  });
61
63
 
62
64
  const editable = ui.view.createEditable(rootName, contentElement);
@@ -111,6 +111,19 @@ describe('editor hook', () => {
111
111
 
112
112
  expect(isEditorShown()).toBe(true);
113
113
  });
114
+
115
+ it('should be possible to specify root element name', async () => {
116
+ const hookElement = createEditorHtmlElement({
117
+ modelElement: '$inlineRoot',
118
+ });
119
+
120
+ document.body.appendChild(hookElement);
121
+ EditorHook.mounted.call({ el: hookElement });
122
+
123
+ const editor = await waitForTestEditor();
124
+
125
+ expect(editor.model.document.getRoot()?.name).to.be.equal('$inlineRoot');
126
+ });
114
127
  });
115
128
 
116
129
  describe('decoupled', () => {
@@ -249,6 +262,57 @@ describe('editor hook', () => {
249
262
  expect(editor).toBeInstanceOf(DecoupledEditor);
250
263
  expect(editor.getData()).toBe('<p>XD</p>');
251
264
  });
265
+
266
+ it('should be possible to specify root element name using global config (if editable model element not specified)', async () => {
267
+ const hookElement = createEditorHtmlElement({
268
+ preset: createEditorPreset('decoupled'),
269
+ modelElement: '$inlineRoot',
270
+ });
271
+
272
+ document.body.appendChild(hookElement);
273
+ document.body.appendChild(createEditableHtmlElement());
274
+
275
+ EditorHook.mounted.call({ el: hookElement });
276
+
277
+ const editor = await waitForTestEditor();
278
+
279
+ expect(editor.model.document.getRoot()?.name).toEqual('$inlineRoot');
280
+ });
281
+
282
+ it('should be possible to specify root element name using editable config alone', async () => {
283
+ const hookElement = createEditorHtmlElement({
284
+ preset: createEditorPreset('decoupled'),
285
+ });
286
+
287
+ document.body.appendChild(hookElement);
288
+ document.body.appendChild(createEditableHtmlElement({
289
+ modelElement: '$inlineRoot',
290
+ }));
291
+
292
+ EditorHook.mounted.call({ el: hookElement });
293
+
294
+ const editor = await waitForTestEditor();
295
+
296
+ expect(editor.model.document.getRoot()?.name).toEqual('$inlineRoot');
297
+ });
298
+
299
+ it('should use editable root element name config if both specified', async () => {
300
+ const hookElement = createEditorHtmlElement({
301
+ preset: createEditorPreset('decoupled'),
302
+ modelElement: '$miamia',
303
+ });
304
+
305
+ document.body.appendChild(hookElement);
306
+ document.body.appendChild(createEditableHtmlElement({
307
+ modelElement: '$inlineRoot',
308
+ }));
309
+
310
+ EditorHook.mounted.call({ el: hookElement });
311
+
312
+ const editor = await waitForTestEditor();
313
+
314
+ expect(editor.model.document.getRoot()?.name).toEqual('$inlineRoot');
315
+ });
252
316
  });
253
317
 
254
318
  describe('inline', () => {
@@ -313,6 +377,36 @@ describe('editor hook', () => {
313
377
  '<p>Third root</p>',
314
378
  );
315
379
  });
380
+
381
+ it('should create a multiroot editor with inline editables', async () => {
382
+ const hookElement = createEditorHtmlElement({
383
+ preset: createEditorPreset('multiroot'),
384
+ });
385
+
386
+ document.body.appendChild(hookElement);
387
+ document.body.appendChild(
388
+ createEditableHtmlElement({
389
+ name: 'second',
390
+ initialValue: '<p>Second root</p>',
391
+ modelElement: '$inlineRoot',
392
+ }),
393
+ );
394
+
395
+ document.body.appendChild(
396
+ createEditableHtmlElement({
397
+ name: 'third',
398
+ initialValue: '<p>Third root</p>',
399
+ modelElement: '$inlineRoot',
400
+ }),
401
+ );
402
+
403
+ EditorHook.mounted.call({ el: hookElement });
404
+
405
+ const editor = await waitForTestEditor();
406
+
407
+ expect(editor.model.document.getRoot('second')?.name).toEqual('$inlineRoot');
408
+ expect(editor.model.document.getRoot('third')?.name).toEqual('$inlineRoot');
409
+ });
316
410
  });
317
411
  });
318
412
 
@@ -1,4 +1,5 @@
1
1
  import type { EditorId } from './typings';
2
+ import type { EditableItem } from './utils';
2
3
 
3
4
  import { isEmptyObject, parseIntIfNotNull, waitFor } from '../../shared';
4
5
  import { ClassHook, makeHook } from '../../shared/hook';
@@ -11,8 +12,7 @@ import {
11
12
  createSyncEditorWithPhoenixPlugin,
12
13
  } from './plugins';
13
14
  import {
14
- assignInitialDataToEditorConfig,
15
- assignSourceElementsToEditorConfig,
15
+ assignEditorRootsToConfig,
16
16
  cleanupOrphanEditorElements,
17
17
  createEditorInContext,
18
18
  isSingleRootEditor,
@@ -20,8 +20,7 @@ import {
20
20
  loadEditorConstructor,
21
21
  loadEditorPlugins,
22
22
  normalizeCustomTranslations,
23
- queryEditablesElements,
24
- queryEditablesSnapshotContent,
23
+ queryAllEditorEditables,
25
24
  readPresetOrThrow,
26
25
  resolveEditorConfigElementReferences,
27
26
  resolveEditorConfigTranslations,
@@ -234,34 +233,16 @@ class EditorHookImpl extends ClassHook {
234
233
  ]
235
234
  .filter(translations => !isEmptyObject(translations));
236
235
 
237
- // Let's query all elements, and create basic configuration.
238
- let initialData: string | Record<string, string> = queryEditablesSnapshotContent(editorId);
236
+ // Query all editable elements along with their initial values in one pass.
237
+ let editables = queryAllEditorEditables(editorId);
238
+ const requiredRoots = Object.keys(editables);
239
239
 
240
240
  if (isSingleRootEditor(type)) {
241
- initialData = initialData['main'] || '';
241
+ requiredRoots.push('main');
242
242
  }
243
243
 
244
- // Depending of the editor type, and parent lookup for nearest context or initialize it without it.
245
- let sourceElements: HTMLElement | Record<string, HTMLElement> = queryEditablesElements(editorId);
246
-
247
- // Handle special case when user specified `initialData` of several root elements, but editable components
248
- // are not yet present in the DOM. In other words - editor is initialized before attaching root elements.
249
- if (!(sourceElements instanceof HTMLElement) && !('main' in sourceElements)) {
250
- const requiredRoots = (
251
- type === 'decoupled'
252
- ? ['main']
253
- : Object.keys(initialData as Record<string, string>)
254
- );
255
-
256
- if (!checkIfAllRootsArePresent(sourceElements, requiredRoots)) {
257
- sourceElements = await waitForAllRootsToBePresent(editorId, requiredRoots);
258
- initialData = queryEditablesSnapshotContent(editorId);
259
- }
260
- }
261
-
262
- // If single root editor, unwrap the element from the object.
263
- if (isSingleRootEditor(type) && 'main' in sourceElements) {
264
- sourceElements = sourceElements['main'];
244
+ if (!checkIfAllRootsArePresent(editables, requiredRoots)) {
245
+ editables = await waitForAllRootsToBePresent(editorId, requiredRoots);
265
246
  }
266
247
 
267
248
  // Do some postprocessing on received configuration.
@@ -277,8 +258,7 @@ class EditorHookImpl extends ClassHook {
277
258
 
278
259
  resolvedConfig = resolveEditorConfigElementReferences(resolvedConfig);
279
260
  resolvedConfig = resolveEditorConfigTranslations([...mixedTranslations].reverse(), language.ui, resolvedConfig);
280
- resolvedConfig = assignSourceElementsToEditorConfig(Constructor, sourceElements, resolvedConfig);
281
- resolvedConfig = assignInitialDataToEditorConfig(initialData, resolvedConfig);
261
+ resolvedConfig = assignEditorRootsToConfig(Constructor, editables, resolvedConfig);
282
262
 
283
263
  const editor = await (async () => {
284
264
  if (!context) {
@@ -337,42 +317,42 @@ class EditorHookImpl extends ClassHook {
337
317
  }
338
318
 
339
319
  /**
340
- * Checks if all required root elements are present in the elements object.
320
+ * Checks if all required root elements are present in the editables map.
341
321
  *
342
- * @param elements The elements object mapping root IDs to HTMLElements.
343
- * @param requiredRoots The list of required root IDs.
322
+ * @param editables The editables map keyed by root name.
323
+ * @param requiredRoots The list of required root names.
344
324
  * @returns True if all required roots are present, false otherwise.
345
325
  */
346
- function checkIfAllRootsArePresent(elements: Record<string, HTMLElement>, requiredRoots: string[]): boolean {
347
- return requiredRoots.every(rootId => elements[rootId]);
326
+ function checkIfAllRootsArePresent(editables: Record<string, EditableItem>, requiredRoots: string[]): boolean {
327
+ return requiredRoots.every(rootId => editables[rootId]);
348
328
  }
349
329
 
350
330
  /**
351
331
  * Waits for all required root elements to be present in the DOM.
352
332
  *
353
333
  * @param editorId The editor's ID.
354
- * @param requiredRoots The list of required root IDs.
355
- * @returns A promise that resolves to the record of root elements.
334
+ * @param requiredRoots The list of required root names.
335
+ * @returns A promise that resolves to the map of editable items.
356
336
  */
357
337
  async function waitForAllRootsToBePresent(
358
338
  editorId: EditorId,
359
339
  requiredRoots: string[],
360
- ): Promise<Record<string, HTMLElement>> {
340
+ ): Promise<Record<string, EditableItem>> {
361
341
  return waitFor(
362
342
  () => {
363
- const elements = queryEditablesElements(editorId) as unknown as Record<string, HTMLElement>;
343
+ const editables = queryAllEditorEditables(editorId);
364
344
 
365
- if (!checkIfAllRootsArePresent(elements, requiredRoots)) {
345
+ if (!checkIfAllRootsArePresent(editables, requiredRoots)) {
366
346
  throw new Error(
367
347
  'It looks like not all required root elements are present yet.\n'
368
348
  + '* If you want to wait for them, ensure they are registered before editor initialization.\n'
369
349
  + '* If you want lazy initialize roots, consider removing root values from the `initialData` config '
370
350
  + 'and assign initial data in editable components.\n'
371
- + `Missing roots: ${requiredRoots.filter(rootId => !elements[rootId]).join(', ')}.`,
351
+ + `Missing roots: ${requiredRoots.filter(rootId => !editables[rootId]).join(', ')}.`,
372
352
  );
373
353
  }
374
354
 
375
- return elements;
355
+ return editables;
376
356
  },
377
357
  { timeOutAfter: 2000, retryAfter: 100 },
378
358
  );
@@ -168,7 +168,7 @@ function getEditorRootsValues(editor: Editor) {
168
168
  return roots.reduce<Record<string, string>>((acc, rootName) => {
169
169
  acc[rootName] = editor.getData({ rootName });
170
170
  return acc;
171
- }, Object.create({}));
171
+ }, Object.create(null));
172
172
  }
173
173
 
174
174
  /**
@@ -0,0 +1,58 @@
1
+ import type { EditorConfig } from 'ckeditor5';
2
+
3
+ import type { EditorRelaxedConstructor } from '../types/editor-relaxed-constructor.type';
4
+ import type { EditableItem } from './query-all-editor-editables';
5
+
6
+ /**
7
+ * Assigns DOM elements and initial data to the editor configuration in a way that is compatible
8
+ * with the specific editor type.
9
+ *
10
+ * @param Editor Constructor of the editor used to determine the location of element config entry.
11
+ * @param editables Map of editable items (element + initial value) keyed by root name.
12
+ * @param config Config of the editor.
13
+ * @returns The updated configuration object.
14
+ */
15
+ export function assignEditorRootsToConfig<C extends EditorConfig>(
16
+ Editor: EditorRelaxedConstructor,
17
+ editables: Record<string, EditableItem>,
18
+ config: C,
19
+ ): C {
20
+ const isClassicEditor = !Editor.editorName || Editor.editorName === 'ClassicEditor';
21
+ const allRootsKeys = new Set([
22
+ ...Object.keys(editables),
23
+ ...Object.keys(config.roots ?? {}),
24
+ ]);
25
+
26
+ const rootsConfig = Array.from(allRootsKeys).reduce((acc, rootKey) => ({
27
+ ...acc,
28
+ [rootKey]: {
29
+ /* v8 ignore next 1 */
30
+ ...config.roots?.[rootKey],
31
+ ...rootKey === 'main' ? config.root : {},
32
+
33
+ /* v8 ignore start */
34
+ ...rootKey in editables
35
+ ? {
36
+ initialData: editables[rootKey]!.initialValue,
37
+ modelElement: editables[rootKey]!.modelElement || '$root',
38
+ ...!isClassicEditor && {
39
+ element: editables[rootKey]!.content,
40
+ },
41
+ }
42
+ : {},
43
+ /* v8 ignore end */
44
+ },
45
+ }), { ...config.roots || {} });
46
+
47
+ const mappedConfig: C = {
48
+ ...config,
49
+ roots: rootsConfig,
50
+ ...isClassicEditor && {
51
+ attachTo: editables['main']?.content,
52
+ },
53
+ };
54
+
55
+ delete mappedConfig.root;
56
+
57
+ return mappedConfig;
58
+ }
@@ -1,5 +1,4 @@
1
- export * from './assign-initial-data-to-editor-config';
2
- export * from './assign-source-elements-to-editor-config';
1
+ export * from './assign-editor-roots-to-config';
3
2
  export * from './cleanup-orphan-editor-elements';
4
3
  export * from './create-editor-in-context';
5
4
  export * from './is-multiroot-editor-instance';
@@ -1,34 +1,5 @@
1
1
  import type { EditorId } from '../typings';
2
2
 
3
- import { filterObjectValues, mapObjectValues } from '../../../shared';
4
-
5
- /**
6
- * Gets the initial root elements for the editor based on its type.
7
- *
8
- * @param editorId The editor's ID.
9
- * @returns The root element(s) for the editor.
10
- */
11
- export function queryEditablesElements(editorId: EditorId) {
12
- const editables = queryAllEditorEditables(editorId);
13
-
14
- return mapObjectValues(editables, ({ content }) => content);
15
- }
16
-
17
- /**
18
- * Gets the initial data for the roots of the editor. If the editor is a single editing-like editor,
19
- * it retrieves the initial value from the element's attribute. Otherwise, it returns an object mapping
20
- * editable names to their initial values.
21
- *
22
- * @param editorId The editor's ID.
23
- * @returns The initial values for the editor's roots.
24
- */
25
- export function queryEditablesSnapshotContent(editorId: EditorId) {
26
- const editables = queryAllEditorEditables(editorId);
27
- const values = mapObjectValues(editables, ({ initialValue }) => initialValue);
28
-
29
- return filterObjectValues(values, value => typeof value === 'string') as Record<string, string>;
30
- }
31
-
32
3
  /**
33
4
  * Queries all editable elements within a specific editor instance.
34
5
  *
@@ -49,6 +20,7 @@ export function queryAllEditorEditables(editorId: EditorId): Record<string, Edit
49
20
  .from(iterator)
50
21
  .reduce<Record<string, EditableItem>>((acc, element) => {
51
22
  const name = element.getAttribute('data-cke-editable-root-name');
23
+ const modelElement = element.getAttribute('data-cke-editable-root-model-element-name') || null;
52
24
  const initialValue = element.getAttribute('data-cke-editable-initial-value') || '';
53
25
  const content = element.querySelector('[data-cke-editable-content]') as HTMLElement;
54
26
 
@@ -61,9 +33,10 @@ export function queryAllEditorEditables(editorId: EditorId): Record<string, Edit
61
33
  [name]: {
62
34
  content,
63
35
  initialValue,
36
+ modelElement,
64
37
  },
65
38
  };
66
- }, Object.create({}))
39
+ }, Object.create(null))
67
40
  );
68
41
 
69
42
  const rootEditorElement = document.querySelector<HTMLElement>(`[phx-hook="CKEditor5"][id="${editorId}"]`);
@@ -72,26 +45,29 @@ export function queryAllEditorEditables(editorId: EditorId): Record<string, Edit
72
45
  return acc;
73
46
  }
74
47
 
48
+ const rootEditorModelElement = rootEditorElement.getAttribute('data-cke-root-model-element-name');
75
49
  const initialRootEditableValue = rootEditorElement.getAttribute('data-cke-initial-value') || '';
76
- const contentElement = rootEditorElement.querySelector<HTMLElement>(`#${editorId}_editor `);
77
- const currentMain = acc['main'];
78
50
 
79
- if (currentMain) {
51
+ if (acc['main']) {
80
52
  return {
81
53
  ...acc,
82
54
  main: {
83
- ...currentMain,
84
- initialValue: currentMain.initialValue || initialRootEditableValue,
55
+ ...acc['main'],
56
+ modelElement: acc['main'].modelElement || rootEditorModelElement,
57
+ initialValue: acc['main'].initialValue || initialRootEditableValue,
85
58
  },
86
59
  };
87
60
  }
88
61
 
62
+ const contentElement = rootEditorElement.querySelector<HTMLElement>(`#${editorId}_editor `);
63
+
89
64
  if (contentElement) {
90
65
  return {
91
66
  ...acc,
92
67
  main: {
93
68
  content: contentElement,
94
69
  initialValue: initialRootEditableValue,
70
+ modelElement: rootEditorElement.getAttribute('data-cke-root-model-element-name') || '$root',
95
71
  },
96
72
  };
97
73
  }
@@ -105,4 +81,5 @@ export function queryAllEditorEditables(editorId: EditorId): Record<string, Edit
105
81
  export type EditableItem = {
106
82
  content: HTMLElement;
107
83
  initialValue: string;
84
+ modelElement: string | null;
108
85
  };
@@ -12,12 +12,14 @@ export function createEditableHtmlElement(
12
12
  editorId,
13
13
  initialValue,
14
14
  withInput = false,
15
+ modelElement,
15
16
  }: {
16
17
  id?: string;
17
18
  editorId?: EditorId;
18
19
  name?: string;
19
20
  initialValue?: string;
20
21
  withInput?: boolean;
22
+ modelElement?: string;
21
23
  } = {},
22
24
  ) {
23
25
  return html.div(
@@ -30,6 +32,9 @@ export function createEditableHtmlElement(
30
32
  ...initialValue && {
31
33
  'data-cke-editable-initial-value': initialValue,
32
34
  },
35
+ ...modelElement && {
36
+ 'data-cke-editable-root-model-element-name': modelElement,
37
+ },
33
38
  },
34
39
  html.div({
35
40
  'class': 'editable-content',
@@ -20,6 +20,7 @@ export function createEditorHtmlElement(
20
20
  readyEvent = false,
21
21
  watchdog = false,
22
22
  saveDebounceMs = undefined,
23
+ modelElement,
23
24
  language,
24
25
  hookAttrs,
25
26
  }: EditorCreatorAttrs = {},
@@ -63,6 +64,9 @@ export function createEditorHtmlElement(
63
64
  ...contextId && {
64
65
  'data-cke-context-id': contextId,
65
66
  },
67
+ ...modelElement && {
68
+ 'data-cke-root-model-element-name': modelElement,
69
+ },
66
70
  ...hookAttrs,
67
71
  },
68
72
  !['multiroot', 'decoupled'].includes(preset.type) && html.div({ id: `${id}_editor` }),
@@ -91,5 +95,6 @@ type EditorCreatorAttrs = {
91
95
  watchdog?: boolean;
92
96
  saveDebounceMs?: number;
93
97
  hookAttrs?: Record<string, string>;
98
+ modelElement?: string;
94
99
  language?: { ui?: string; content?: string; };
95
100
  };
@@ -1,10 +0,0 @@
1
- import { EditorConfig } from 'ckeditor5';
2
- /**
3
- * Assigns initial data to specified editor config.
4
- *
5
- * @param dataOrMap Initial data to be assigned to config.
6
- * @param config Config of the editor.
7
- * @returns The updated configuration object.
8
- */
9
- export declare function assignInitialDataToEditorConfig<C extends EditorConfig>(dataOrMap: string | Record<string, string>, config: C): C;
10
- //# sourceMappingURL=assign-initial-data-to-editor-config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"assign-initial-data-to-editor-config.d.ts","sourceRoot":"","sources":["../../../../src/hooks/editor/utils/assign-initial-data-to-editor-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,CAAC,SAAS,YAAY,EACpE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC1C,MAAM,EAAE,CAAC,GACR,CAAC,CA8BH"}
@@ -1,12 +0,0 @@
1
- import { EditorConfig } from 'ckeditor5';
2
- import { EditorRelaxedConstructor } from '../types/editor-relaxed-constructor.type';
3
- /**
4
- * Assigns a DOM element to the editor configuration in a way that is compatible with the specific editor type.
5
- *
6
- * @param Editor Constructor of the editor used to determine the location of element config entry.
7
- * @param elementOrMap Element to be assigned to config.
8
- * @param config Config of the editor.
9
- * @returns The updated configuration object.
10
- */
11
- export declare function assignSourceElementsToEditorConfig<C extends EditorConfig>(Editor: EditorRelaxedConstructor, elementOrMap: HTMLElement | Record<string, HTMLElement>, config: C): C;
12
- //# sourceMappingURL=assign-source-elements-to-editor-config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"assign-source-elements-to-editor-config.d.ts","sourceRoot":"","sources":["../../../../src/hooks/editor/utils/assign-source-elements-to-editor-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AAEzF;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,CAAC,CAAC,SAAS,YAAY,EACvE,MAAM,EAAE,wBAAwB,EAChC,YAAY,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACvD,MAAM,EAAE,CAAC,GACR,CAAC,CAuCH"}
@@ -1,47 +0,0 @@
1
- import type { EditorConfig } from 'ckeditor5';
2
-
3
- /**
4
- * Assigns initial data to specified editor config.
5
- *
6
- * @param dataOrMap Initial data to be assigned to config.
7
- * @param config Config of the editor.
8
- * @returns The updated configuration object.
9
- */
10
- export function assignInitialDataToEditorConfig<C extends EditorConfig>(
11
- dataOrMap: string | Record<string, string>,
12
- config: C,
13
- ): C {
14
- const dataMap = toDataMap(dataOrMap);
15
- const allRootsKeys = new Set([
16
- ...Object.keys(dataMap),
17
- ...Object.keys(config.roots ?? {}),
18
- ]);
19
-
20
- const rootsConfig = Array.from(allRootsKeys).reduce((acc, rootKey) => ({
21
- ...acc,
22
- [rootKey]: {
23
- ...config.roots?.[rootKey],
24
- ...rootKey === 'main' ? config.root : {},
25
-
26
- /* v8 ignore next 5 */
27
- ...rootKey in dataMap
28
- ? {
29
- initialData: dataMap[rootKey],
30
- }
31
- : {},
32
- },
33
- }), Object.create(config.roots || {}));
34
-
35
- const mappedConfig: C = {
36
- ...config,
37
- roots: rootsConfig,
38
- };
39
-
40
- delete mappedConfig.root;
41
-
42
- return mappedConfig;
43
- }
44
-
45
- function toDataMap(element: string | Record<string, string>): Record<string, string> {
46
- return typeof element === 'string' ? { main: element } : { ...element };
47
- }