@ckeditor/ckeditor5-editor-multi-root 0.0.0-internal-20241017.0 → 0.0.0-internal-20251210.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/LICENSE.md CHANGED
@@ -1,19 +1,24 @@
1
1
  Software License Agreement
2
2
  ==========================
3
3
 
4
- **Multi-root editor implementation** https://github.com/ckeditor/ckeditor5-editor-multi-root <br>
5
- Copyright (c) 2003–2024, [CKSource Holding sp. z o.o.](https://cksource.com) All rights reserved.
4
+ **CKEditor&nbsp;5 Multi-root editor** (https://github.com/ckeditor/ckeditor5)<br>
5
+ Copyright (c) 2003–2025, [CKSource Holding sp. z o.o.](https://cksource.com) All rights reserved.
6
6
 
7
- Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html).
7
+ Licensed under a dual-license model, this software is available under:
8
8
 
9
- Sources of Intellectual Property Included in CKEditor
10
- -----------------------------------------------------
9
+ * the [GNU General Public License Version 2 or later](https://www.gnu.org/licenses/gpl.html),
10
+ * or commercial license terms from CKSource Holding sp. z o.o.
11
11
 
12
- Where not otherwise indicated, all CKEditor content is authored by CKSource engineers and consists of CKSource-owned intellectual property. In some specific instances, CKEditor will incorporate work done by developers outside of CKSource with their express permission.
12
+ For more information, see: [https://ckeditor.com/legal/ckeditor-licensing-options](https://ckeditor.com/legal/ckeditor-licensing-options).
13
13
 
14
- The following libraries are included in CKEditor under the [MIT license](https://opensource.org/licenses/MIT):
14
+ Sources of Intellectual Property Included in CKEditor&nbsp;5
15
+ ------------------------------------------------------------
15
16
 
16
- * Lodash - Copyright (c) JS Foundation and other contributors https://js.foundation/. Based on Underscore.js, copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors http://underscorejs.org/.
17
+ Where not otherwise indicated, all CKEditor&nbsp;5 content is authored by CKSource engineers and consists of CKSource-owned intellectual property. In some specific instances, CKEditor&nbsp;5 will incorporate work done by developers outside of CKSource with their express permission.
18
+
19
+ The following libraries are included in CKEditor&nbsp;5 under the [MIT license](https://opensource.org/licenses/MIT):
20
+
21
+ * es-toolkit - Copyright (c) 2024 Viva Republica, Inc.
17
22
 
18
23
  Trademarks
19
24
  ----------
package/README.md CHANGED
@@ -2,15 +2,13 @@ CKEditor&nbsp;5 multi-root editor implementation
2
2
  ========================================
3
3
 
4
4
  [![npm version](https://badge.fury.io/js/%40ckeditor%2Fckeditor5-editor-multi-root.svg)](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-multi-root)
5
- [![Coverage Status](https://coveralls.io/repos/github/ckeditor/ckeditor5/badge.svg?branch=master)](https://coveralls.io/github/ckeditor/ckeditor5?branch=master)
6
- [![Build Status](https://travis-ci.com/ckeditor/ckeditor5.svg?branch=master)](https://app.travis-ci.com/github/ckeditor/ckeditor5)
5
+ [![codecov](https://codecov.io/gh/ckeditor/ckeditor5/branch/master/graph/badge.svg)](https://codecov.io/gh/ckeditor/ckeditor5)
6
+ [![CircleCI](https://circleci.com/gh/ckeditor/ckeditor5.svg?style=shield)](https://app.circleci.com/pipelines/github/ckeditor/ckeditor5?branch=master)
7
7
 
8
8
  The multi-root editor implementation for CKEditor&nbsp;5. Read more about the [multi-root editor build](https://ckeditor.com/docs/ckeditor5/latest/getting-started/legacy/installation-methods/predefined-builds.html#multi-root-editor) and see the [demo](https://ckeditor.com/docs/ckeditor5/latest/examples/builds/multi-root-editor.html).
9
9
 
10
10
  This package contains the [`MultiRootEditor`](https://ckeditor.com/docs/ckeditor5/latest/api/module_editor-multi-root_multirooteditor-MultiRootEditor.html) class. Follow there to learn more about this type of editor and how to initialize it.
11
11
 
12
- This package contains the source version of the multi-root editor. Read more about [CKEditor&nbsp;5 predefined builds](https://ckeditor.com/docs/ckeditor5/latest/getting-started/legacy/advanced/alternative-setups/predefined-builds.html) in the CKEditor&nbsp;5 documentation.
13
-
14
12
  ## Documentation
15
13
 
16
14
  See the [`@ckeditor/ckeditor5-editor-multi-root` package](https://ckeditor.com/docs/ckeditor5/latest/api/editor-multi-root.html) page in [CKEditor&nbsp;5 documentation](https://ckeditor.com/docs/ckeditor5/latest/).
@@ -23,4 +21,9 @@ npm install ckeditor5
23
21
 
24
22
  ## License
25
23
 
26
- Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). For full details about the license, please check the `LICENSE.md` file or [https://ckeditor.com/legal/ckeditor-oss-license](https://ckeditor.com/legal/ckeditor-oss-license).
24
+ Licensed under a dual-license model, this software is available under:
25
+
26
+ * the [GNU General Public License Version 2 or later](https://www.gnu.org/licenses/gpl.html),
27
+ * or commercial license terms from CKSource Holding sp. z o.o.
28
+
29
+ For more information, see: [https://ckeditor.com/legal/ckeditor-licensing-options](https://ckeditor.com/legal/ckeditor-licensing-options).
@@ -1,4 +1,4 @@
1
1
  /*!
2
- * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md.
4
- */(()=>{var t={782:(t,e,o)=>{t.exports=o(237)("./src/core.js")},783:(t,e,o)=>{t.exports=o(237)("./src/engine.js")},311:(t,e,o)=>{t.exports=o(237)("./src/ui.js")},584:(t,e,o)=>{t.exports=o(237)("./src/utils.js")},237:t=>{"use strict";t.exports=CKEditor5.dll}},e={};function o(i){var s=e[i];if(void 0!==s)return s.exports;var r=e[i]={exports:{}};return t[i](r,r.exports,o),r.exports}o.d=(t,e)=>{for(var i in e)o.o(e,i)&&!o.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},o.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),o.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var i={};(()=>{"use strict";o.r(i),o.d(i,{MultiRootEditor:()=>D});var t=o(782),e=o(584),s=o(311),r=o(783);class n extends s.EditorUI{constructor(t,e){super(t),this.view=e,this._lastFocusedEditableElement=null}init(){this.view.render(),this.focusTracker.on("change:focusedElement",((t,e,o)=>{for(const t of Object.values(this.view.editables))o===t.element&&(this._lastFocusedEditableElement=t.element)})),this.focusTracker.on("change:isFocused",((t,e,o)=>{o||(this._lastFocusedEditableElement=null)}));for(const t of Object.values(this.view.editables))this.addEditable(t);this._initToolbar(),this._initMenuBar(this.view.menuBarView),this.fire("ready")}addEditable(t,e){const o=t.element;this.editor.editing.view.attachDomRoot(o,t.name),this.setEditableElement(t.name,o),t.bind("isFocused").to(this.focusTracker,"isFocused",this.focusTracker,"focusedElement",((t,e)=>!!t&&(e===o||this._lastFocusedEditableElement===o))),this._initPlaceholder(t,e)}removeEditable(t){this.editor.editing.view.detachDomRoot(t.name),t.unbind("isFocused"),this.removeEditableElement(t.name)}destroy(){super.destroy();for(const t of Object.values(this.view.editables))this.removeEditable(t);this.view.destroy()}_initToolbar(){const t=this.editor,e=this.view;e.toolbar.fillFromConfig(t.config.get("toolbar"),this.componentFactory),this.addToolbar(e.toolbar)}_initPlaceholder(t,e){if(!e){const o=this.editor.config.get("placeholder");o&&(e="string"==typeof o?o:o[t.name])}const o=this.editor.editing.view,i=o.document.getRoot(t.name);e&&(i.placeholder=e),(0,r.enablePlaceholder)({view:o,element:i,isDirectHost:!1,keepOnFocus:!0})}}class a extends s.EditorUIView{constructor(t,e,o,i={}){super(t),this._editingView=e,this.toolbar=new s.ToolbarView(t,{shouldGroupWhenFull:i.shouldToolbarGroupWhenFull}),this.menuBarView=new s.MenuBarView(t),this.editables={};for(const t of o){const e=i.editableElements?i.editableElements[t]:void 0;let{label:o}=i;"object"==typeof o&&(o=o[t]),this.createEditable(t,e,o)}this.editable=Object.values(this.editables)[0],this.toolbar.extendTemplate({attributes:{class:["ck-reset_all","ck-rounded-corners"],dir:t.uiLanguageDirection}}),this.menuBarView.extendTemplate({attributes:{class:["ck-reset_all","ck-rounded-corners"],dir:t.uiLanguageDirection}})}createEditable(t,e,o){const i=new s.InlineEditableUIView(this.locale,this._editingView,e,{label:o});return this.editables[t]=i,i.name=t,this.isRendered&&this.registerChild(i),i}removeEditable(t){const e=this.editables[t];this.isRendered&&this.deregisterChild(e),delete this.editables[t],e.destroy()}render(){super.render(),this.registerChild(Object.values(this.editables)),this.registerChild(this.toolbar),this.registerChild(this.menuBarView)}}const d=function(t){return null!=t&&"object"==typeof t};const l="object"==typeof global&&global&&global.Object===Object&&global;var c="object"==typeof self&&self&&self.Object===Object&&self;const h=(l||c||Function("return this")()).Symbol;var u=Object.prototype,f=u.hasOwnProperty,b=u.toString,m=h?h.toStringTag:void 0;const g=function(t){var e=f.call(t,m),o=t[m];try{t[m]=void 0;var i=!0}catch(t){}var s=b.call(t);return i&&(e?t[m]=o:delete t[m]),s};var y=Object.prototype.toString;const R=function(t){return y.call(t)};var v=h?h.toStringTag:void 0;const E=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":v&&v in Object(t)?g(t):R(t)};const w=function(t,e){return function(o){return t(e(o))}}(Object.getPrototypeOf,Object);var p=Function.prototype,O=Object.prototype,j=p.toString,_=O.hasOwnProperty,k=j.call(Object);const A=function(t){if(!d(t)||"[object Object]"!=E(t))return!1;var e=w(t);if(null===e)return!0;var o=_.call(e,"constructor")&&e.constructor;return"function"==typeof o&&o instanceof o&&j.call(o)==k};const C=function(t){return d(t)&&1===t.nodeType&&!A(t)};class D extends t.Editor{static get editorName(){return"MultiRootEditor"}constructor(o,i={}){const s=Object.keys(o),r=0===s.length||"string"==typeof o[s[0]];if(r&&void 0!==i.initialData&&Object.keys(i.initialData).length>0)throw new e.CKEditorError("editor-create-initial-data",null);if(super(i),this._registeredRootsAttributesKeys=new Set,this._readOnlyRootLocks=new Map,this.sourceElements=r?{}:o,void 0===this.config.get("initialData")){const t={};for(const i of s)t[i]=T(d=o[i])?(0,e.getDataFromElement)(d):d;this.config.set("initialData",t)}var d;if(!r)for(const e of s)(0,t.secureSourceElement)(this,o[e]);this.editing.view.document.roots.on("add",((t,e)=>{e.unbind("isReadOnly"),e.bind("isReadOnly").to(this.editing.view.document,"isReadOnly",(t=>t||this._readOnlyRootLocks.has(e.rootName))),e.on("change:isReadOnly",((t,o,i)=>{const s=this.editing.view.createRangeIn(e);for(const t of s.getItems())t.is("editableElement")&&(t.unbind("isReadOnly"),t.isReadOnly=i)}))}));for(const t of s)this.model.document.createRoot("$root",t);if(this.config.get("lazyRoots"))for(const t of this.config.get("lazyRoots")){this.model.document.createRoot("$root",t)._isLoaded=!1}if(this.config.get("rootsAttributes")){const t=this.config.get("rootsAttributes");for(const[o,i]of Object.entries(t)){if(!this.model.document.getRoot(o))throw new e.CKEditorError("multi-root-editor-root-attributes-no-root",null);for(const t of Object.keys(i))this.registerRootAttribute(t)}this.data.on("init",(()=>{this.model.enqueueChange({isUndoable:!1},(e=>{for(const[o,i]of Object.entries(t)){const t=this.model.document.getRoot(o);for(const[o,s]of Object.entries(i))null!==s&&e.setAttribute(o,s,t)}}))}))}const l={shouldToolbarGroupWhenFull:!this.config.get("toolbar.shouldNotGroupWhenFull"),editableElements:r?void 0:o,label:this.config.get("label")},c=new a(this.locale,this.editing.view,s,l);this.ui=new n(this,c),this.model.document.on("change:data",(()=>{const t=this.model.document.differ.getChangedRoots();for(const e of t){const t=this.model.document.getRoot(e.name);"detached"==e.state&&this.fire("detachRoot",t)}for(const e of t){const t=this.model.document.getRoot(e.name);"attached"==e.state&&this.fire("addRoot",t)}})),this.listenTo(this.model,"canEditAt",((t,[e])=>{if(!e)return;let o=!1;for(const t of e.getRanges()){const e=t.root;if(this._readOnlyRootLocks.has(e.rootName)){o=!0;break}}o&&(t.return=!1,t.stop())}),{priority:"high"}),this.decorate("loadRoot"),this.on("loadRoot",((t,[o])=>{const i=this.model.document.getRoot(o);if(!i)throw new e.CKEditorError("multi-root-editor-load-root-no-root",this,{rootName:o});i._isLoaded&&((0,e.logWarning)("multi-root-editor-load-root-already-loaded"),t.stop())}),{priority:"highest"})}destroy(){const t=this.config.get("updateSourceElementOnDestroy"),o={};for(const e of Object.keys(this.sourceElements))o[e]=t?this.getData({rootName:e}):"";return this.ui.destroy(),super.destroy().then((()=>{for(const t of Object.keys(this.sourceElements))(0,e.setDataInElement)(this.sourceElements[t],o[t])}))}addRoot(t,{data:e="",attributes:o={},elementName:i="$root",isUndoable:s=!1}={}){const r=s=>{const r=s.addRoot(t,i);e&&s.insert(this.data.parse(e,r),r,0);for(const t of Object.keys(o))this.registerRootAttribute(t),s.setAttribute(t,o[t],r)};s?this.model.change(r):this.model.enqueueChange({isUndoable:!1},r)}detachRoot(t,e=!1){e?this.model.change((e=>e.detachRoot(t))):this.model.enqueueChange({isUndoable:!1},(e=>e.detachRoot(t)))}createEditable(t,e,o){const i=this.ui.view.createEditable(t.rootName,void 0,o);return this.ui.addEditable(i,e),this.editing.view.forceRender(),i.element}detachEditable(t){const e=t.rootName,o=this.ui.view.editables[e];return this.ui.removeEditable(o),this.ui.view.removeEditable(e),o.element}loadRoot(t,{data:e="",attributes:o={}}={}){const i=this.model.document.getRoot(t);this.model.enqueueChange({isUndoable:!1},(t=>{e&&t.insert(this.data.parse(e,i),i,0);for(const e of Object.keys(o))this.registerRootAttribute(e),t.setAttribute(e,o[e],i);i._isLoaded=!0,this.model.document.differ._bufferRootLoad(i)}))}getFullData(t){const e={};for(const o of this.model.document.getRootNames())e[o]=this.data.get({...t,rootName:o});return e}getRootsAttributes(){const t={};for(const e of this.model.document.getRootNames())t[e]=this.getRootAttributes(e);return t}getRootAttributes(t){const e={},o=this.model.document.getRoot(t);for(const t of this._registeredRootsAttributesKeys)e[t]=o.hasAttribute(t)?o.getAttribute(t):null;return e}registerRootAttribute(t){this._registeredRootsAttributesKeys.has(t)||(this._registeredRootsAttributesKeys.add(t),this.editing.model.schema.extend("$root",{allowAttributes:t}))}disableRoot(t,o){if("$graveyard"==t)throw new e.CKEditorError("multi-root-editor-cannot-disable-graveyard-root",this);const i=this._readOnlyRootLocks.get(t);if(i)i.add(o);else{this._readOnlyRootLocks.set(t,new Set([o]));this.editing.view.document.getRoot(t).isReadOnly=!0,Array.from(this.commands.commands()).forEach((t=>t.affectsData&&t.refresh()))}}enableRoot(t,e){const o=this._readOnlyRootLocks.get(t);if(o&&o.has(e))if(1===o.size){this._readOnlyRootLocks.delete(t);this.editing.view.document.getRoot(t).isReadOnly=this.isReadOnly,Array.from(this.commands.commands()).forEach((t=>t.affectsData&&t.refresh()))}else o.delete(e)}static create(t,o={}){return new Promise((i=>{for(const o of Object.values(t))if(T(o)&&"TEXTAREA"===o.tagName)throw new e.CKEditorError("editor-wrong-element",null);const s=new this(t,o);i(s.initPlugins().then((()=>s.ui.init())).then((()=>(s._verifyRootsWithInitialData(),s.data.init(s.config.get("initialData"))))).then((()=>s.fire("ready"))).then((()=>s)))}))}_verifyRootsWithInitialData(){const t=this.config.get("initialData");for(const o of this.model.document.getRootNames())if(!(o in t))throw new e.CKEditorError("multi-root-editor-root-initial-data-mismatch",null);for(const o of Object.keys(t)){const t=this.model.document.getRoot(o);if(!t||!t.isAttached())throw new e.CKEditorError("multi-root-editor-root-initial-data-mismatch",null)}}}function T(t){return C(t)}})(),(window.CKEditor5=window.CKEditor5||{}).editorMultiRoot=i})();
4
+ */(()=>{var t={237:t=>{"use strict";t.exports=CKEditor5.dll},311:(t,e,o)=>{t.exports=o(237)("./src/ui.js")},584:(t,e,o)=>{t.exports=o(237)("./src/utils.js")},782:(t,e,o)=>{t.exports=o(237)("./src/core.js")},783:(t,e,o)=>{t.exports=o(237)("./src/engine.js")}},e={};function o(i){var s=e[i];if(void 0!==s)return s.exports;var r=e[i]={exports:{}};return t[i](r,r.exports,o),r.exports}o.d=(t,e)=>{for(var i in e)o.o(e,i)&&!o.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},o.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),o.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var i={};(()=>{"use strict";o.r(i),o.d(i,{MultiRootEditor:()=>l,MultiRootEditorUI:()=>n,MultiRootEditorUIView:()=>a});var t=o(782),e=o(584),s=o(311),r=o(783);class n extends s.EditorUI{view;_lastFocusedEditableElement;constructor(t,e){super(t),this.view=e,this._lastFocusedEditableElement=null}init(){this.view.render(),this.focusTracker.on("change:focusedElement",(t,e,o)=>{for(const t of Object.values(this.view.editables))o===t.element&&(this._lastFocusedEditableElement=t.element)}),this.focusTracker.on("change:isFocused",(t,e,o)=>{o||(this._lastFocusedEditableElement=null)});for(const t of Object.values(this.view.editables))this.addEditable(t);this._initToolbar(),this.initMenuBar(this.view.menuBarView),this.fire("ready")}addEditable(t,e){const o=t.element;this.editor.editing.view.attachDomRoot(o,t.name),this.setEditableElement(t.name,o),t.bind("isFocused").to(this.focusTracker,"isFocused",this.focusTracker,"focusedElement",(t,e)=>!!t&&(e===o||this._lastFocusedEditableElement===o)),this._initPlaceholder(t,e)}removeEditable(t){const e=this.editor.editing.view;e.getDomRoot(t.name)&&e.detachDomRoot(t.name),t.unbind("isFocused"),this.removeEditableElement(t.name)}destroy(){super.destroy();for(const t of Object.values(this.view.editables))this.removeEditable(t);this.view.destroy()}_initToolbar(){const t=this.editor,e=this.view;e.toolbar.fillFromConfig(t.config.get("toolbar"),this.componentFactory),this.addToolbar(e.toolbar)}_initPlaceholder(t,e){if(!e){const o=this.editor.config.get("placeholder");o&&(e="string"==typeof o?o:o[t.name])}const o=this.editor.editing.view,i=o.document.getRoot(t.name);e&&(i.placeholder=e),(0,r.enableViewPlaceholder)({view:o,element:i,isDirectHost:!1,keepOnFocus:!0})}}class a extends s.EditorUIView{toolbar;editables;editable;menuBarView;_editingView;constructor(t,e,o,i={}){super(t),this._editingView=e,this.toolbar=new s.ToolbarView(t,{shouldGroupWhenFull:i.shouldToolbarGroupWhenFull}),this.menuBarView=new s.MenuBarView(t),this.editables={};for(const t of o){const e=i.editableElements?i.editableElements[t]:void 0;let{label:o}=i;"object"==typeof o&&(o=o[t]),this.createEditable(t,e,o)}this.editable=Object.values(this.editables)[0],this.toolbar.extendTemplate({attributes:{class:["ck-reset_all","ck-rounded-corners"],dir:t.uiLanguageDirection}}),this.menuBarView.extendTemplate({attributes:{class:["ck-reset_all","ck-rounded-corners"],dir:t.uiLanguageDirection}})}createEditable(t,e,o){const i=new s.InlineEditableUIView(this.locale,this._editingView,e,{label:o});return this.editables[t]=i,i.name=t,this.isRendered&&this.registerChild(i),i}removeEditable(t){const e=this.editables[t];this.isRendered&&this.deregisterChild(e),delete this.editables[t],e.destroy()}render(){super.render(),this.registerChild(Object.values(this.editables)),this.registerChild(this.toolbar),this.registerChild(this.menuBarView)}}function d(t){return function(t){return"object"==typeof t&&null!==t}(t)&&1===t.nodeType&&!function(t){if("object"!=typeof t)return!1;if(null==t)return!1;if(null===Object.getPrototypeOf(t))return!0;if("[object Object]"!==Object.prototype.toString.call(t)){const e=t[Symbol.toStringTag];return null!=e&&(!!Object.getOwnPropertyDescriptor(t,Symbol.toStringTag)?.writable&&t.toString()===`[object ${e}]`)}let e=t;for(;null!==Object.getPrototypeOf(e);)e=Object.getPrototypeOf(e);return Object.getPrototypeOf(t)===e}(t)}class l extends t.Editor{static get editorName(){return"MultiRootEditor"}ui;sourceElements;_registeredRootsAttributesKeys=new Set;_readOnlyRootLocks=new Map;constructor(o,i={}){const s=Object.keys(o),r=0===s.length||"string"==typeof o[s[0]];if(r&&void 0!==i.initialData&&Object.keys(i.initialData).length>0)throw new e.CKEditorError("editor-create-initial-data",null);if(super(i),this.sourceElements=r?{}:o,void 0===this.config.get("initialData")){const t={};for(const e of s)t[e]=c(o[e]);this.config.set("initialData",t)}if(!r)for(const e of s)(0,t.secureSourceElement)(this,o[e]);this.editing.view.document.roots.on("add",(t,e)=>{e.unbind("isReadOnly"),e.bind("isReadOnly").to(this.editing.view.document,"isReadOnly",t=>t||this._readOnlyRootLocks.has(e.rootName)),e.on("change:isReadOnly",(t,o,i)=>{const s=this.editing.view.createRangeIn(e);for(const t of s.getItems())t.is("editableElement")&&(t.unbind("isReadOnly"),t.isReadOnly=i)})});for(const t of s)this.model.document.createRoot("$root",t);if(this.config.get("lazyRoots"))for(const t of this.config.get("lazyRoots")){this.model.document.createRoot("$root",t)._isLoaded=!1}if(this.config.get("rootsAttributes")){const t=this.config.get("rootsAttributes");for(const[o,i]of Object.entries(t)){if(!this.model.document.getRoot(o))throw new e.CKEditorError("multi-root-editor-root-attributes-no-root",null);for(const t of Object.keys(i))this.registerRootAttribute(t)}this.data.on("init",()=>{this.model.enqueueChange({isUndoable:!1},e=>{for(const[o,i]of Object.entries(t)){const t=this.model.document.getRoot(o);for(const[o,s]of Object.entries(i))null!==s&&e.setAttribute(o,s,t)}})})}const d={shouldToolbarGroupWhenFull:!this.config.get("toolbar.shouldNotGroupWhenFull"),editableElements:r?void 0:o,label:this.config.get("label")},l=new a(this.locale,this.editing.view,s,d);this.ui=new n(this,l),this.model.document.on("change:data",()=>{const t=this.model.document.differ.getChangedRoots();for(const e of t){const t=this.model.document.getRoot(e.name);"detached"==e.state&&this.fire("detachRoot",t)}for(const e of t){const t=this.model.document.getRoot(e.name);"attached"==e.state&&this.fire("addRoot",t)}}),this.listenTo(this.model,"canEditAt",(t,[e])=>{if(!e)return;let o=!1;for(const t of e.getRanges()){const e=t.root;if(this._readOnlyRootLocks.has(e.rootName)){o=!0;break}}o&&(t.return=!1,t.stop())},{priority:"high"}),this.decorate("loadRoot"),this.on("loadRoot",(t,[o])=>{const i=this.model.document.getRoot(o);if(!i)throw new e.CKEditorError("multi-root-editor-load-root-no-root",this,{rootName:o});i._isLoaded&&((0,e.logWarning)("multi-root-editor-load-root-already-loaded"),t.stop())},{priority:"highest"}),function(t){const o=t.config.get("licenseKey"),i=(0,e.decodeLicenseKey)(o);if(!i)return;(0,e.isFeatureBlockedByLicenseKey)(i,"MRE")&&(t.enableReadOnlyMode(Symbol("invalidLicense")),t._showLicenseError("featureNotAllowed","Multi-root editor"))}(this)}destroy(){const t=this.config.get("updateSourceElementOnDestroy"),o={};for(const e of Object.keys(this.sourceElements))o[e]=t?this.getData({rootName:e}):"";return this.ui.destroy(),super.destroy().then(()=>{for(const t of Object.keys(this.sourceElements))(0,e.setDataInElement)(this.sourceElements[t],o[t])})}addRoot(t,{data:e="",attributes:o={},elementName:i="$root",isUndoable:s=!1}={}){const r=s=>{const r=s.addRoot(t,i);e&&s.insert(this.data.parse(e,r),r,0);for(const t of Object.keys(o))this.registerRootAttribute(t),s.setAttribute(t,o[t],r)};s?this.model.change(r):this.model.enqueueChange({isUndoable:!1},r)}detachRoot(t,e=!1){e?this.model.change(e=>e.detachRoot(t)):this.model.enqueueChange({isUndoable:!1},e=>e.detachRoot(t))}createEditable(t,e,o){const i=this.ui.view.createEditable(t.rootName,void 0,o);return this.ui.addEditable(i,e),this.editing.view.forceRender(),i.element}detachEditable(t){const e=t.rootName,o=this.ui.view.editables[e];return this.ui.removeEditable(o),this.ui.view.removeEditable(e),o.element}loadRoot(t,{data:e="",attributes:o={}}={}){const i=this.model.document.getRoot(t);this.model.enqueueChange({isUndoable:!1},t=>{e&&t.insert(this.data.parse(e,i),i,0);for(const e of Object.keys(o))this.registerRootAttribute(e),t.setAttribute(e,o[e],i);i._isLoaded=!0,this.model.document.differ._bufferRootLoad(i)})}getFullData(t){const e={};for(const o of this.model.document.getRootNames())e[o]=this.data.get({...t,rootName:o});return e}getRootsAttributes(){const t={};for(const e of this.model.document.getRootNames())t[e]=this.getRootAttributes(e);return t}getRootAttributes(t){const e={},o=this.model.document.getRoot(t);for(const t of this._registeredRootsAttributesKeys)e[t]=o.hasAttribute(t)?o.getAttribute(t):null;return e}registerRootAttribute(t){this._registeredRootsAttributesKeys.has(t)||(this._registeredRootsAttributesKeys.add(t),this.editing.model.schema.extend("$root",{allowAttributes:t}))}disableRoot(t,o){if("$graveyard"==t)throw new e.CKEditorError("multi-root-editor-cannot-disable-graveyard-root",this);const i=this._readOnlyRootLocks.get(t);if(i)i.add(o);else{this._readOnlyRootLocks.set(t,new Set([o]));this.editing.view.document.getRoot(t).isReadOnly=!0,Array.from(this.commands.commands()).forEach(t=>t.affectsData&&t.refresh())}}enableRoot(t,e){const o=this._readOnlyRootLocks.get(t);if(o&&o.has(e))if(1===o.size){this._readOnlyRootLocks.delete(t);this.editing.view.document.getRoot(t).isReadOnly=this.isReadOnly,Array.from(this.commands.commands()).forEach(t=>t.affectsData&&t.refresh())}else o.delete(e)}static create(t,o={}){return new Promise(i=>{for(const o of Object.values(t))if(h(o)&&"TEXTAREA"===o.tagName)throw new e.CKEditorError("editor-wrong-element",null);const s=new this(t,o);i(s.initPlugins().then(()=>s.ui.init()).then(()=>(s._verifyRootsWithInitialData(),s.data.init(s.config.get("initialData")))).then(()=>s.fire("ready")).then(()=>s))})}_verifyRootsWithInitialData(){const t=this.config.get("initialData");for(const o of this.model.document.getRootNames())if(!(o in t))throw new e.CKEditorError("multi-root-editor-root-initial-data-mismatch",null);for(const o of Object.keys(t)){const t=this.model.document.getRoot(o);if(!t||!t.isAttached())throw new e.CKEditorError("multi-root-editor-root-initial-data-mismatch",null)}}}function c(t){return h(t)?(0,e.getDataFromElement)(t):t}function h(t){return d(t)}})(),(window.CKEditor5=window.CKEditor5||{}).editorMultiRoot=i})();
@@ -1,4 +1,4 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
4
  */
@@ -1,4 +1,4 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
4
  */
package/dist/index.css CHANGED
@@ -1,4 +1,4 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
4
  */
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
4
  */
5
5
  import { Editor, secureSourceElement } from '@ckeditor/ckeditor5-core/dist/index.js';
6
- import { CKEditorError, logWarning, setDataInElement, getDataFromElement } from '@ckeditor/ckeditor5-utils/dist/index.js';
6
+ import { CKEditorError, logWarning, decodeLicenseKey, isFeatureBlockedByLicenseKey, setDataInElement, getDataFromElement } from '@ckeditor/ckeditor5-utils/dist/index.js';
7
7
  import { EditorUI, EditorUIView, ToolbarView, MenuBarView, InlineEditableUIView } from '@ckeditor/ckeditor5-ui/dist/index.js';
8
- import { enablePlaceholder } from '@ckeditor/ckeditor5-engine/dist/index.js';
9
- import { isElement as isElement$1 } from 'lodash-es';
8
+ import { enableViewPlaceholder } from '@ckeditor/ckeditor5-engine/dist/index.js';
9
+ import { isElement as isElement$1 } from 'es-toolkit/compat';
10
10
 
11
11
  /**
12
12
  * The multi-root editor UI class.
@@ -57,7 +57,7 @@ import { isElement as isElement$1 } from 'lodash-es';
57
57
  this.addEditable(editable);
58
58
  }
59
59
  this._initToolbar();
60
- this._initMenuBar(this.view.menuBarView);
60
+ this.initMenuBar(this.view.menuBarView);
61
61
  this.fire('ready');
62
62
  }
63
63
  /**
@@ -113,7 +113,10 @@ import { isElement as isElement$1 } from 'lodash-es';
113
113
  *
114
114
  * @param editable Editable to remove from the editor UI.
115
115
  */ removeEditable(editable) {
116
- this.editor.editing.view.detachDomRoot(editable.name);
116
+ const editingView = this.editor.editing.view;
117
+ if (editingView.getDomRoot(editable.name)) {
118
+ editingView.detachDomRoot(editable.name);
119
+ }
117
120
  editable.unbind('isFocused');
118
121
  this.removeEditableElement(editable.name);
119
122
  }
@@ -154,7 +157,7 @@ import { isElement as isElement$1 } from 'lodash-es';
154
157
  if (placeholder) {
155
158
  editingRoot.placeholder = placeholder;
156
159
  }
157
- enablePlaceholder({
160
+ enableViewPlaceholder({
158
161
  view: editingView,
159
162
  element: editingRoot,
160
163
  isDirectHost: false,
@@ -300,7 +303,7 @@ import { isElement as isElement$1 } from 'lodash-es';
300
303
  * Note that you will need to attach the editor toolbar to your web page manually, in a desired place, after the editor is initialized.
301
304
  */ class MultiRootEditor extends Editor {
302
305
  /**
303
- * @inheritdoc
306
+ * @inheritDoc
304
307
  */ static get editorName() {
305
308
  return 'MultiRootEditor';
306
309
  }
@@ -487,6 +490,18 @@ import { isElement as isElement$1 } from 'lodash-es';
487
490
  }, {
488
491
  priority: 'highest'
489
492
  });
493
+ verifyLicenseKey(this);
494
+ function verifyLicenseKey(editor) {
495
+ const licenseKey = editor.config.get('licenseKey');
496
+ const decodedPayload = decodeLicenseKey(licenseKey);
497
+ if (!decodedPayload) {
498
+ return;
499
+ }
500
+ if (isFeatureBlockedByLicenseKey(decodedPayload, 'MRE')) {
501
+ editor.enableReadOnlyMode(Symbol('invalidLicense'));
502
+ editor._showLicenseError('featureNotAllowed', 'Multi-root editor');
503
+ }
504
+ }
490
505
  }
491
506
  /**
492
507
  * Destroys the editor instance, releasing all resources used by it.
@@ -631,7 +646,7 @@ import { isElement as isElement$1 } from 'lodash-es';
631
646
  *
632
647
  * After a root is detached all its children are removed, all markers inside it are removed, and whenever something is inserted to it,
633
648
  * it is automatically removed as well. Finally, a detached root is not returned by
634
- * {@link module:engine/model/document~Document#getRootNames} by default.
649
+ * {@link module:engine/model/document~ModelDocument#getRootNames} by default.
635
650
  *
636
651
  * It is possible to re-add a previously detached root calling {@link #addRoot}.
637
652
  *
@@ -714,12 +729,25 @@ import { isElement as isElement$1 } from 'lodash-es';
714
729
  * Loads a root that has previously been declared in {@link module:core/editor/editorconfig~EditorConfig#lazyRoots `lazyRoots`}
715
730
  * configuration option.
716
731
  *
732
+ * **Important! Lazy roots loading is an experimental feature, and may become deprecated. Be advised of the following
733
+ * known limitations:**
734
+ *
735
+ * * **Real-time collaboration integrations that use
736
+ * [uploaded editor bundles](https://ckeditor.com/docs/cs/latest/guides/collaboration/editor-bundle.html) are not supported. Using
737
+ * lazy roots will lead to unexpected behavior and data loss.**
738
+ * * **Revision history feature will read and process the whole document on editor initialization, possibly defeating the purpose
739
+ * of using the lazy roots loading. Additionally, when the document is loaded for the first time, all roots need to be loaded,
740
+ * to make sure that the initial revision data includes all roots. Otherwise, you may experience data loss.**
741
+ * * **Multiple features, that require full document data to be loaded, will produce incorrect or confusing results if not all
742
+ * roots are loaded. These include: bookmarks, find and replace, word count, pagination, document exports, document outline,
743
+ * and table of contents.**
744
+ *
717
745
  * Only roots specified in the editor config can be loaded. A root cannot be loaded multiple times. A root cannot be unloaded and
718
746
  * loading a root cannot be reverted using the undo feature.
719
747
  *
720
748
  * When a root becomes loaded, it will be treated by the editor as though it was just added. This, among others, means that all
721
749
  * related events and mechanisms will be fired, including {@link ~MultiRootEditor#event:addRoot `addRoot` event},
722
- * {@link module:engine/model/document~Document#event:change `model.Document` `change` event}, model post-fixers and conversion.
750
+ * {@link module:engine/model/document~ModelDocument#event:change `model.Document` `change` event}, model post-fixers and conversion.
723
751
  *
724
752
  * Until the root becomes loaded, all above mechanisms are suppressed.
725
753
  *
@@ -803,7 +831,7 @@ import { isElement as isElement$1 } from 'lodash-es';
803
831
  }
804
832
  /**
805
833
  * Registers given string as a root attribute key. Registered root attributes are added to
806
- * {@link module:engine/model/schema~Schema schema}, and also returned by
834
+ * {@link module:engine/model/schema~ModelSchema schema}, and also returned by
807
835
  * {@link ~MultiRootEditor#getRootAttributes `getRootAttributes()`} and
808
836
  * {@link ~MultiRootEditor#getRootsAttributes `getRootsAttributes()`}.
809
837
  *
@@ -1062,7 +1090,6 @@ import { isElement as isElement$1 } from 'lodash-es';
1062
1090
  for (const rootName of Object.keys(initialData)){
1063
1091
  const root = this.model.document.getRoot(rootName);
1064
1092
  if (!root || !root.isAttached()) {
1065
- // eslint-disable-next-line ckeditor5-rules/ckeditor-error-message
1066
1093
  throw new CKEditorError('multi-root-editor-root-initial-data-mismatch', null);
1067
1094
  }
1068
1095
  }
@@ -1075,5 +1102,5 @@ function isElement(value) {
1075
1102
  return isElement$1(value);
1076
1103
  }
1077
1104
 
1078
- export { MultiRootEditor };
1105
+ export { MultiRootEditor, MultiRootEditorUI, MultiRootEditorUIView };
1079
1106
  //# sourceMappingURL=index.js.map