@ckeditor/ckeditor5-editor-multi-root 48.0.1-alpha.1 → 48.1.0-alpha.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.
- package/dist/augmentation.d.ts +1 -80
- package/dist/index.d.ts +2 -1
- package/dist/index.js +41 -68
- package/dist/index.js.map +1 -1
- package/dist/multirooteditor.d.ts +3 -32
- package/package.json +5 -5
package/dist/augmentation.d.ts
CHANGED
|
@@ -2,88 +2,9 @@
|
|
|
2
2
|
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
4
|
*/
|
|
5
|
-
import
|
|
5
|
+
import '@ckeditor/ckeditor5-core';
|
|
6
6
|
declare module '@ckeditor/ckeditor5-core' {
|
|
7
7
|
interface RootConfig {
|
|
8
|
-
/**
|
|
9
|
-
* Initial root attributes for a root.
|
|
10
|
-
*
|
|
11
|
-
* **Note: This configuration option is supported only by the
|
|
12
|
-
* {@link module:editor-multi-root/multirooteditor~MultiRootEditor multi-root} editor type.**
|
|
13
|
-
*
|
|
14
|
-
* **Note: You must provide full set of attributes for each root. If an attribute is not set on a root, set the value to `null`.
|
|
15
|
-
* Only provided attribute keys will be returned by
|
|
16
|
-
* {@link module:editor-multi-root/multirooteditor~MultiRootEditor#getRootsAttributes}.**
|
|
17
|
-
*
|
|
18
|
-
* Roots attributes hold additional data related to the document roots, in addition to the regular document data (which usually is
|
|
19
|
-
* HTML). In roots attributes, for each root, you can store arbitrary key-value pairs with attributes connected with that root.
|
|
20
|
-
* Use it to store any custom data that is specific to your integration or custom features.
|
|
21
|
-
*
|
|
22
|
-
* Currently, any official plugins do not use root attributes. This is a mechanism that is prepared for custom features
|
|
23
|
-
* and non-standard integrations. If you do not provide any custom feature that would use root attributes, you do not need to
|
|
24
|
-
* handle (save and load) this property.
|
|
25
|
-
*
|
|
26
|
-
* ```ts
|
|
27
|
-
* MultiRootEditor.create(
|
|
28
|
-
* // Roots for the editor:
|
|
29
|
-
* {
|
|
30
|
-
* uid1: document.querySelector( '#uid1' ),
|
|
31
|
-
* uid2: document.querySelector( '#uid2' ),
|
|
32
|
-
* uid3: document.querySelector( '#uid3' ),
|
|
33
|
-
* uid4: document.querySelector( '#uid4' )
|
|
34
|
-
* },
|
|
35
|
-
* // Config:
|
|
36
|
-
* {
|
|
37
|
-
* roots: {
|
|
38
|
-
* uid1: {
|
|
39
|
-
* modelAttributes: { order: 20, isLocked: false } // Third, unlocked.
|
|
40
|
-
* },
|
|
41
|
-
* uid2: {
|
|
42
|
-
* modelAttributes: { order: 10, isLocked: true } // Second, locked.
|
|
43
|
-
* },
|
|
44
|
-
* uid3: {
|
|
45
|
-
* modelAttributes: { order: 30, isLocked: true } // Fourth, locked.
|
|
46
|
-
* },
|
|
47
|
-
* uid4: {
|
|
48
|
-
* modelAttributes: { order: 0, isLocked: false } // First, unlocked.
|
|
49
|
-
* }
|
|
50
|
-
* }
|
|
51
|
-
* }
|
|
52
|
-
* )
|
|
53
|
-
* .then( ... )
|
|
54
|
-
* .catch( ... );
|
|
55
|
-
* ```
|
|
56
|
-
*
|
|
57
|
-
* Note, that the above code snippet is only an example. You need to implement your own features that will use these attributes.
|
|
58
|
-
*
|
|
59
|
-
* Roots attributes can be changed the same way as attributes set on other model nodes:
|
|
60
|
-
*
|
|
61
|
-
* ```ts
|
|
62
|
-
* editor.model.change( writer => {
|
|
63
|
-
* const root = editor.model.getRoot( 'uid3' );
|
|
64
|
-
*
|
|
65
|
-
* writer.setAttribute( 'order', 40, root );
|
|
66
|
-
* } );
|
|
67
|
-
* ```
|
|
68
|
-
*
|
|
69
|
-
* You can react to root attributes changes by listening to
|
|
70
|
-
* {@link module:engine/model/document~ModelDocument#event:change:data document `change:data` event}:
|
|
71
|
-
*
|
|
72
|
-
* ```ts
|
|
73
|
-
* editor.model.document.on( 'change:data', () => {
|
|
74
|
-
* const changedRoots = editor.model.document.differ.getChangedRoots();
|
|
75
|
-
*
|
|
76
|
-
* for ( const change of changedRoots ) {
|
|
77
|
-
* if ( change.attributes ) {
|
|
78
|
-
* const root = editor.model.getRoot( change.name );
|
|
79
|
-
*
|
|
80
|
-
* // ...
|
|
81
|
-
* }
|
|
82
|
-
* }
|
|
83
|
-
* } );
|
|
84
|
-
* ```
|
|
85
|
-
*/
|
|
86
|
-
modelAttributes?: RootAttributes;
|
|
87
8
|
/**
|
|
88
9
|
* Flag for the root that exist in the document but is not initially loaded by the editor.
|
|
89
10
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -8,5 +8,6 @@
|
|
|
8
8
|
export { MultiRootEditor } from './multirooteditor.js';
|
|
9
9
|
export { MultiRootEditorUI } from './multirooteditorui.js';
|
|
10
10
|
export { MultiRootEditorUIView } from './multirooteditoruiview.js';
|
|
11
|
-
export type {
|
|
11
|
+
export type { AddRootEvent, DetachRootEvent, LoadRootEvent, AddRootOptions, LoadRootOptions, AddRootRootConfig, RootEditableOptions } from './multirooteditor.js';
|
|
12
|
+
export type { EditorRootAttributes as RootAttributes } from '@ckeditor/ckeditor5-core';
|
|
12
13
|
import './augmentation.js';
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
|
|
4
4
|
*/
|
|
5
|
-
import { Editor, normalizeMultiRootEditorConstructorParams, normalizeRootsConfig, secureSourceElement } from '@ckeditor/ckeditor5-core/dist/index.js';
|
|
5
|
+
import { Editor, normalizeMultiRootEditorConstructorParams, normalizeRootsConfig, secureSourceElement, registerAndInitializeRootConfigAttributes, verifyRootElements } from '@ckeditor/ckeditor5-core/dist/index.js';
|
|
6
6
|
import { CKEditorError, logWarning, decodeLicenseKey, isFeatureBlockedByLicenseKey, setDataInElement } from '@ckeditor/ckeditor5-utils/dist/index.js';
|
|
7
7
|
import { EditorUI, EditorUIView, ToolbarView, MenuBarView, InlineEditableUIView } from '@ckeditor/ckeditor5-ui/dist/index.js';
|
|
8
8
|
import { enableViewPlaceholder } from '@ckeditor/ckeditor5-engine/dist/index.js';
|
|
@@ -310,11 +310,6 @@ import { isElement as isElement$1 } from 'es-toolkit/compat';
|
|
|
310
310
|
/**
|
|
311
311
|
* The elements on which the editor has been initialized.
|
|
312
312
|
*/ sourceElements;
|
|
313
|
-
/**
|
|
314
|
-
* Holds attributes keys that were passed in
|
|
315
|
-
* {@link module:core/editor/editorconfig~EditorConfig#roots `config.roots.<rootName>.modelAttributes`}
|
|
316
|
-
* and should be returned by {@link #getRootsAttributes}.
|
|
317
|
-
*/ _registeredRootsAttributesKeys = new Set();
|
|
318
313
|
/**
|
|
319
314
|
* A set of lock IDs for enabling or disabling particular root.
|
|
320
315
|
*/ _readOnlyRootLocks = new Map();
|
|
@@ -366,17 +361,12 @@ import { isElement as isElement$1 } from 'es-toolkit/compat';
|
|
|
366
361
|
});
|
|
367
362
|
for (const [rootName, rootConfig] of rootsConfig){
|
|
368
363
|
// Create root and `UIView` element for each editable container.
|
|
369
|
-
const root = this.model.document.createRoot(
|
|
364
|
+
const root = this.model.document.createRoot(rootConfig.modelElement, rootName);
|
|
370
365
|
if (rootConfig.lazyLoad) {
|
|
371
366
|
root._isLoaded = false;
|
|
372
367
|
}
|
|
373
|
-
const attributes = rootConfig.modelAttributes;
|
|
374
|
-
if (attributes) {
|
|
375
|
-
for (const key of Object.keys(attributes)){
|
|
376
|
-
this.registerRootAttribute(key);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
368
|
}
|
|
369
|
+
registerAndInitializeRootConfigAttributes(this);
|
|
380
370
|
// Registering `$rootEditableOptions` attribute to make it available in the editor model.
|
|
381
371
|
// This allows to store editable options for each root in the model, and make them available on other RTC clients.
|
|
382
372
|
// We do not use `registerRootAttribute()` method here, as this attribute is used internally
|
|
@@ -390,11 +380,6 @@ import { isElement as isElement$1 } from 'es-toolkit/compat';
|
|
|
390
380
|
}, (writer)=>{
|
|
391
381
|
for (const [rootName, rootConfig] of rootsConfig){
|
|
392
382
|
const root = this.model.document.getRoot(rootName);
|
|
393
|
-
for (const [key, value] of Object.entries(rootConfig.modelAttributes || {})){
|
|
394
|
-
if (value !== null) {
|
|
395
|
-
writer.setAttribute(key, value, root);
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
383
|
// Set editable config for consistency with `addRoot()` method. This will allow features
|
|
399
384
|
// to use the same configuration for both initially loaded and dynamically added roots.
|
|
400
385
|
const rootEditableOptions = {
|
|
@@ -517,7 +502,7 @@ import { isElement as isElement$1 } from 'es-toolkit/compat';
|
|
|
517
502
|
* console.log( 'Editor was destroyed' );
|
|
518
503
|
* } );
|
|
519
504
|
* ```
|
|
520
|
-
*/ destroy() {
|
|
505
|
+
*/ async destroy() {
|
|
521
506
|
const shouldUpdateSourceElement = this.config.get('updateSourceElementOnDestroy');
|
|
522
507
|
// Cache the data and editable DOM elements, then destroy.
|
|
523
508
|
// It's safe to assume that the model->view conversion will not work after `super.destroy()`,
|
|
@@ -529,16 +514,32 @@ import { isElement as isElement$1 } from 'es-toolkit/compat';
|
|
|
529
514
|
}) : '';
|
|
530
515
|
}
|
|
531
516
|
this.ui.destroy();
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
517
|
+
await super.destroy();
|
|
518
|
+
for (const rootName of Object.keys(this.sourceElements)){
|
|
519
|
+
setDataInElement(this.sourceElements[rootName], data[rootName]);
|
|
520
|
+
}
|
|
521
|
+
// To satisfy the return type and to keep it backward compatible.
|
|
522
|
+
// eslint-disable-next-line no-useless-return
|
|
523
|
+
return;
|
|
537
524
|
}
|
|
538
525
|
addRoot(rootName, options = {}) {
|
|
539
526
|
const initialData = options.initialData || options.data || '';
|
|
540
527
|
const modelAttributes = options.modelAttributes || options.attributes || {};
|
|
541
|
-
const modelElement = options.elementName || '$root';
|
|
528
|
+
const modelElement = options.modelElement || options.elementName || '$root';
|
|
529
|
+
if (!this.model.schema.isLimit(modelElement)) {
|
|
530
|
+
/**
|
|
531
|
+
* The model root element must be a {@link module:engine/model/schema~ModelSchemaItemDefinition#isLimit limit element}.
|
|
532
|
+
* The element name specified in {@link ~MultiRootEditor#addRoot `addRoot()`} options must be registered in the schema
|
|
533
|
+
* with `isLimit` set to `true`.
|
|
534
|
+
*
|
|
535
|
+
* @error multi-root-editor-add-root-element-is-not-limit
|
|
536
|
+
* @param rootName The name of the root that uses a non-limit element.
|
|
537
|
+
* @param elementName The name of the model element used for the root.
|
|
538
|
+
*/ throw new CKEditorError('multi-root-editor-add-root-element-is-not-limit', this, {
|
|
539
|
+
rootName,
|
|
540
|
+
elementName: modelElement
|
|
541
|
+
});
|
|
542
|
+
}
|
|
542
543
|
if (isElement(options.element)) {
|
|
543
544
|
/**
|
|
544
545
|
* The `element` option is not supported in {@link #addRoot `addRoot()`} method, and will be ignored.
|
|
@@ -751,38 +752,6 @@ import { isElement as isElement$1 } from 'es-toolkit/compat';
|
|
|
751
752
|
}
|
|
752
753
|
return rootsAttributes;
|
|
753
754
|
}
|
|
754
|
-
/**
|
|
755
|
-
* Returns attributes for the specified root.
|
|
756
|
-
*
|
|
757
|
-
* Note: all and only {@link ~MultiRootEditor#registerRootAttribute registered} roots attributes will be returned.
|
|
758
|
-
* If a registered root attribute is not set for a given root, `null` will be returned.
|
|
759
|
-
*/ getRootAttributes(rootName) {
|
|
760
|
-
const rootAttributes = {};
|
|
761
|
-
const root = this.model.document.getRoot(rootName);
|
|
762
|
-
for (const key of this._registeredRootsAttributesKeys){
|
|
763
|
-
rootAttributes[key] = root.hasAttribute(key) ? root.getAttribute(key) : null;
|
|
764
|
-
}
|
|
765
|
-
return rootAttributes;
|
|
766
|
-
}
|
|
767
|
-
/**
|
|
768
|
-
* Registers given string as a root attribute key. Registered root attributes are added to
|
|
769
|
-
* {@link module:engine/model/schema~ModelSchema schema}, and also returned by
|
|
770
|
-
* {@link ~MultiRootEditor#getRootAttributes `getRootAttributes()`} and
|
|
771
|
-
* {@link ~MultiRootEditor#getRootsAttributes `getRootsAttributes()`}.
|
|
772
|
-
*
|
|
773
|
-
* Note: attributes passed in
|
|
774
|
-
* {@link module:core/editor/editorconfig~EditorConfig#roots `config.roots.<rootName>.modelAttributes`}
|
|
775
|
-
* are automatically registered as the editor is initialized. However, registering the same attribute twice does not have any
|
|
776
|
-
* negative impact, so it is recommended to use this method in any feature that uses roots attributes.
|
|
777
|
-
*/ registerRootAttribute(key) {
|
|
778
|
-
if (this._registeredRootsAttributesKeys.has(key)) {
|
|
779
|
-
return;
|
|
780
|
-
}
|
|
781
|
-
this._registeredRootsAttributesKeys.add(key);
|
|
782
|
-
this.editing.model.schema.extend('$root', {
|
|
783
|
-
allowAttributes: key
|
|
784
|
-
});
|
|
785
|
-
}
|
|
786
755
|
/**
|
|
787
756
|
* Switches given editor root to the read-only mode.
|
|
788
757
|
*
|
|
@@ -860,17 +829,21 @@ import { isElement as isElement$1 } from 'es-toolkit/compat';
|
|
|
860
829
|
locksForGivenRoot.delete(lockId);
|
|
861
830
|
}
|
|
862
831
|
}
|
|
863
|
-
static create(sourceElementsOrDataOrConfig, config = {}) {
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
832
|
+
static async create(sourceElementsOrDataOrConfig, config = {}) {
|
|
833
|
+
const editor = new this(sourceElementsOrDataOrConfig, config);
|
|
834
|
+
await editor.initPlugins();
|
|
835
|
+
// Roots are created in the editor constructor (before plugins are loaded), but the schema is only fully
|
|
836
|
+
// built after plugins register their items during init(). Custom root element names (e.g. registered by a
|
|
837
|
+
// plugin) may not exist in the schema at construction time, so we defer this check until here.
|
|
838
|
+
verifyRootElements(editor);
|
|
839
|
+
await editor.ui.init();
|
|
840
|
+
const initialData = extractRootsConfigField(editor.config.get('roots'), 'initialData');
|
|
841
|
+
// This is checked directly before setting the initial data,
|
|
842
|
+
// as plugins may change `EditorConfig#initialData` value.
|
|
843
|
+
editor._verifyRootsWithInitialData(initialData);
|
|
844
|
+
await editor.data.init(initialData);
|
|
845
|
+
editor.fire('ready');
|
|
846
|
+
return editor;
|
|
874
847
|
}
|
|
875
848
|
/**
|
|
876
849
|
* @internal
|