@ckeditor/ckeditor5-editor-multi-root 37.0.1 → 37.1.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.
@@ -1,4 +1,4 @@
1
1
  /*!
2
2
  * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md.
4
- */(()=>{var t={704:(t,e,o)=>{t.exports=o(79)("./src/core.js")},492:(t,e,o)=>{t.exports=o(79)("./src/engine.js")},273:(t,e,o)=>{t.exports=o(79)("./src/ui.js")},209:(t,e,o)=>{t.exports=o(79)("./src/utils.js")},434:(t,e,o)=>{t.exports=o(79)("./src/watchdog.js")},79: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:()=>A});var t=o(704),e=o(209),s=o(434),r=o(273),n=o(492);class a extends r.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.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])}if(!e)return;const o=this.editor.editing.view,i=o.document.getRoot(t.name);(0,n.enablePlaceholder)({view:o,element:i,text:e,isDirectHost:!1,keepOnFocus:!0})}}class c extends r.EditorUIView{constructor(t,e,o,i={}){super(t),this._editingView=e,this.toolbar=new r.ToolbarView(t,{shouldGroupWhenFull:i.shouldToolbarGroupWhenFull}),this.editables={};for(const t of o){const e=i.editableElements?i.editableElements[t]:void 0;this.createEditable(t,e)}this.editable=Object.values(this.editables)[0],this.toolbar.extendTemplate({attributes:{class:["ck-reset_all","ck-rounded-corners"],dir:t.uiLanguageDirection}})}createEditable(t,e){const o=this.locale.t,i=new r.InlineEditableUIView(this.locale,this._editingView,e,{label:t=>o("Rich Text Editor. Editing area: %0",t.name)});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)}}const l=function(t){return null!=t&&"object"==typeof t};const d="object"==typeof global&&global&&global.Object===Object&&global;var u="object"==typeof self&&self&&self.Object===Object&&self;const h=(d||u||Function("return this")()).Symbol;var b=Object.prototype,f=b.hasOwnProperty,m=b.toString,g=h?h.toStringTag:void 0;const E=function(t){var e=f.call(t,g),o=t[g];try{t[g]=void 0;var i=!0}catch(t){}var s=m.call(t);return i&&(e?t[g]=o:delete t[g]),s};var v=Object.prototype.toString;const p=function(t){return v.call(t)};var y=h?h.toStringTag:void 0;const w=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":y&&y in Object(t)?E(t):p(t)};const j=function(t,e){return function(o){return t(e(o))}}(Object.getPrototypeOf,Object);var O=Function.prototype,R=Object.prototype,x=O.toString,C=R.hasOwnProperty,F=x.call(Object);const T=function(t){if(!l(t)||"[object Object]"!=w(t))return!1;var e=j(t);if(null===e)return!0;var o=C.call(e,"constructor")&&e.constructor;return"function"==typeof o&&o instanceof o&&x.call(o)==F};const _=function(t){return l(t)&&1===t.nodeType&&!T(t)};class A extends((0,t.DataApiMixin)(t.Editor)){constructor(o,i={}){const s=Object.keys(o),r=0===s.length||"string"==typeof o[s[0]];if(r&&void 0!==i.initialData)throw new e.CKEditorError("editor-create-initial-data",null);if(super(i),this._registeredRootsAttributesKeys=new Set,this.sourceElements=r?{}:o,void 0===this.config.get("initialData")){const t={};for(const i of s)t[i]=D(n=o[i])?(0,e.getDataFromElement)(n):n;this.config.set("initialData",t)}var n;if(!r)for(const e of s)(0,t.secureSourceElement)(this,o[e]);for(const t of s)this.model.document.createRoot("$root",t);if(this.config.get("rootsAttributes")){const t=this.config.get("rootsAttributes");for(const[o,i]of Object.entries(t)){if(!s.includes(o))throw new e.CKEditorError("multi-root-editor-root-attributes-no-root",null);for(const t of Object.keys(i))this._registeredRootsAttributesKeys.add(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},d=new c(this.locale,this.editing.view,s,l);this.ui=new a(this,d),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);"attached"==e.state?this.fire("addRoot",t):"detached"==e.state&&this.fire("detachRoot",t)}}))}destroy(){const t=this.config.get("updateSourceElementOnDestroy"),o={};if(this.sourceElements)for(const e of Object.keys(this.sourceElements))o[e]=t?this.getData({rootName:e}):"";return this.ui.destroy(),super.destroy().then((()=>{if(this.sourceElements)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=this.data,n=this._registeredRootsAttributesKeys;function a(s){const a=s.addRoot(t,i);e&&s.insert(r.parse(e,a),a,0);for(const t of Object.keys(o))n.add(t),s.setAttribute(t,o[t],a)}s?this.model.change(a):this.model.enqueueChange({isUndoable:!1},a)}detachRoot(t,e=!1){e?this.model.change((e=>e.detachRoot(t))):this.model.enqueueChange({isUndoable:!1},(e=>e.detachRoot(t)))}createEditable(t,e){const o=this.ui.view.createEditable(t.rootName);return this.ui.addEditable(o,e),this.editing.view.forceRender(),o.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}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={},e=Array.from(this._registeredRootsAttributesKeys);for(const o of this.model.document.getRootNames()){t[o]={};const i=this.model.document.getRoot(o);for(const s of e)t[o][s]=i.hasAttribute(s)?i.getAttribute(s):null}return t}static create(t,o={}){return new Promise((i=>{for(const o of Object.values(t))if(D(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.data.init(s.config.get("initialData")))).then((()=>s.fire("ready"))).then((()=>s)))}))}}function D(t){return _(t)}A.Context=t.Context,A.EditorWatchdog=s.EditorWatchdog,A.ContextWatchdog=s.ContextWatchdog})(),(window.CKEditor5=window.CKEditor5||{}).editorMultiRoot=i})();
4
+ */(()=>{var t={704:(t,e,o)=>{t.exports=o(79)("./src/core.js")},492:(t,e,o)=>{t.exports=o(79)("./src/engine.js")},273:(t,e,o)=>{t.exports=o(79)("./src/ui.js")},209:(t,e,o)=>{t.exports=o(79)("./src/utils.js")},434:(t,e,o)=>{t.exports=o(79)("./src/watchdog.js")},79:t=>{"use strict";t.exports=CKEditor5.dll}},e={};function o(i){var r=e[i];if(void 0!==r)return r.exports;var s=e[i]={exports:{}};return t[i](s,s.exports,o),s.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:()=>I});var t=o(704),e=o(209),r=o(434),s=o(273),n=o(492);class a 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.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])}if(!e)return;const o=this.editor.editing.view,i=o.document.getRoot(t.name);(0,n.enablePlaceholder)({view:o,element:i,text:e,isDirectHost:!1,keepOnFocus:!0})}}class c extends s.EditorUIView{constructor(t,e,o,i={}){super(t),this._editingView=e,this.toolbar=new s.ToolbarView(t,{shouldGroupWhenFull:i.shouldToolbarGroupWhenFull}),this.editables={};for(const t of o){const e=i.editableElements?i.editableElements[t]:void 0;this.createEditable(t,e)}this.editable=Object.values(this.editables)[0],this.toolbar.extendTemplate({attributes:{class:["ck-reset_all","ck-rounded-corners"],dir:t.uiLanguageDirection}})}createEditable(t,e){const o=this.locale.t,i=new s.InlineEditableUIView(this.locale,this._editingView,e,{label:t=>o("Rich Text Editor. Editing area: %0",t.name)});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)}}const l=function(t){return null!=t&&"object"==typeof t};const d="object"==typeof global&&global&&global.Object===Object&&global;var u="object"==typeof self&&self&&self.Object===Object&&self;const h=(d||u||Function("return this")()).Symbol;var b=Object.prototype,f=b.hasOwnProperty,m=b.toString,g=h?h.toStringTag:void 0;const p=function(t){var e=f.call(t,g),o=t[g];try{t[g]=void 0;var i=!0}catch(t){}var r=m.call(t);return i&&(e?t[g]=o:delete t[g]),r};var v=Object.prototype.toString;const E=function(t){return v.call(t)};var y=h?h.toStringTag:void 0;const w=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":y&&y in Object(t)?p(t):E(t)};const j=function(t,e){return function(o){return t(e(o))}}(Object.getPrototypeOf,Object);var O=Function.prototype,R=Object.prototype,x=O.toString,C=R.hasOwnProperty,F=x.call(Object);const T=function(t){if(!l(t)||"[object Object]"!=w(t))return!1;var e=j(t);if(null===e)return!0;var o=C.call(e,"constructor")&&e.constructor;return"function"==typeof o&&o instanceof o&&x.call(o)==F};const _=function(t){return l(t)&&1===t.nodeType&&!T(t)};var D=Object.defineProperty,P=Object.defineProperties,A=Object.getOwnPropertyDescriptors,S=Object.getOwnPropertySymbols,k=Object.prototype.hasOwnProperty,K=Object.prototype.propertyIsEnumerable,N=(t,e,o)=>e in t?D(t,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[e]=o,W=(t,e)=>{for(var o in e||(e={}))k.call(e,o)&&N(t,o,e[o]);if(S)for(var o of S(e))K.call(e,o)&&N(t,o,e[o]);return t};class I extends((0,t.DataApiMixin)(t.Editor)){constructor(o,i={}){const r=Object.keys(o),s=0===r.length||"string"==typeof o[r[0]];if(s&&void 0!==i.initialData)throw new e.CKEditorError("editor-create-initial-data",null);if(super(i),this._registeredRootsAttributesKeys=new Set,this.sourceElements=s?{}:o,void 0===this.config.get("initialData")){const t={};for(const i of r)t[i]=U(n=o[i])?(0,e.getDataFromElement)(n):n;this.config.set("initialData",t)}var n;if(!s)for(const e of r)(0,t.secureSourceElement)(this,o[e]);for(const t of r)this.model.document.createRoot("$root",t);if(this.config.get("rootsAttributes")){const t=this.config.get("rootsAttributes");for(const[o,i]of Object.entries(t)){if(!r.includes(o))throw new e.CKEditorError("multi-root-editor-root-attributes-no-root",null);for(const t of Object.keys(i))this._registeredRootsAttributesKeys.add(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,r]of Object.entries(i))null!==r&&e.setAttribute(o,r,t)}}))}))}const l={shouldToolbarGroupWhenFull:!this.config.get("toolbar.shouldNotGroupWhenFull"),editableElements:s?void 0:o},d=new c(this.locale,this.editing.view,r,l);this.ui=new a(this,d),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)}}))}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:r=!1}={}){const s=this.data,n=this._registeredRootsAttributesKeys;function a(r){const a=r.addRoot(t,i);e&&r.insert(s.parse(e,a),a,0);for(const t of Object.keys(o))n.add(t),r.setAttribute(t,o[t],a)}r?this.model.change(a):this.model.enqueueChange({isUndoable:!1},a)}detachRoot(t,e=!1){e?this.model.change((e=>e.detachRoot(t))):this.model.enqueueChange({isUndoable:!1},(e=>e.detachRoot(t)))}createEditable(t,e){const o=this.ui.view.createEditable(t.rootName);return this.ui.addEditable(o,e),this.editing.view.forceRender(),o.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}getFullData(t){const e={};for(const i of this.model.document.getRootNames())e[i]=this.data.get((o=W({},t),P(o,A({rootName:i}))));var o;return e}getRootsAttributes(){const t={},e=Array.from(this._registeredRootsAttributesKeys);for(const o of this.model.document.getRootNames()){t[o]={};const i=this.model.document.getRoot(o);for(const r of e)t[o][r]=i.hasAttribute(r)?i.getAttribute(r):null}return t}static create(t,o={}){return new Promise((i=>{for(const o of Object.values(t))if(U(o)&&"TEXTAREA"===o.tagName)throw new e.CKEditorError("editor-wrong-element",null);const r=new this(t,o);i(r.initPlugins().then((()=>r.ui.init())).then((()=>(r._verifyRootsWithInitialData(),r.data.init(r.config.get("initialData"))))).then((()=>r.fire("ready"))).then((()=>r)))}))}_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 U(t){return _(t)}I.Context=t.Context,I.EditorWatchdog=r.EditorWatchdog,I.ContextWatchdog=r.ContextWatchdog})(),(window.CKEditor5=window.CKEditor5||{}).editorMultiRoot=i})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-editor-multi-root",
3
- "version": "37.0.1",
3
+ "version": "37.1.0",
4
4
  "description": "Multi-root editor implementation for CKEditor 5.",
5
5
  "keywords": [
6
6
  "ckeditor",
@@ -11,23 +11,23 @@
11
11
  ],
12
12
  "main": "src/index.js",
13
13
  "dependencies": {
14
- "ckeditor5": "^37.0.1",
14
+ "ckeditor5": "^37.1.0",
15
15
  "lodash-es": "^4.17.15"
16
16
  },
17
17
  "devDependencies": {
18
- "@ckeditor/ckeditor5-basic-styles": "^37.0.1",
19
- "@ckeditor/ckeditor5-core": "^37.0.1",
20
- "@ckeditor/ckeditor5-dev-utils": "^36.0.0",
21
- "@ckeditor/ckeditor5-engine": "^37.0.1",
22
- "@ckeditor/ckeditor5-enter": "^37.0.1",
23
- "@ckeditor/ckeditor5-heading": "^37.0.1",
24
- "@ckeditor/ckeditor5-paragraph": "^37.0.1",
25
- "@ckeditor/ckeditor5-theme-lark": "^37.0.1",
26
- "@ckeditor/ckeditor5-typing": "^37.0.1",
27
- "@ckeditor/ckeditor5-ui": "^37.0.1",
28
- "@ckeditor/ckeditor5-undo": "^37.0.1",
29
- "@ckeditor/ckeditor5-utils": "^37.0.1",
30
- "@ckeditor/ckeditor5-watchdog": "^37.0.1",
18
+ "@ckeditor/ckeditor5-basic-styles": "^37.1.0",
19
+ "@ckeditor/ckeditor5-core": "^37.1.0",
20
+ "@ckeditor/ckeditor5-dev-utils": "^37.0.0",
21
+ "@ckeditor/ckeditor5-engine": "^37.1.0",
22
+ "@ckeditor/ckeditor5-enter": "^37.1.0",
23
+ "@ckeditor/ckeditor5-heading": "^37.1.0",
24
+ "@ckeditor/ckeditor5-paragraph": "^37.1.0",
25
+ "@ckeditor/ckeditor5-theme-lark": "^37.1.0",
26
+ "@ckeditor/ckeditor5-typing": "^37.1.0",
27
+ "@ckeditor/ckeditor5-ui": "^37.1.0",
28
+ "@ckeditor/ckeditor5-undo": "^37.1.0",
29
+ "@ckeditor/ckeditor5-utils": "^37.1.0",
30
+ "@ckeditor/ckeditor5-watchdog": "^37.1.0",
31
31
  "typescript": "^4.8.4",
32
32
  "webpack": "^5.58.1",
33
33
  "webpack-cli": "^4.9.0"
@@ -408,6 +408,10 @@ export default class MultiRootEditor extends MultiRootEditor_base {
408
408
  * Exposed as static editor field for easier access in editor builds.
409
409
  */
410
410
  static ContextWatchdog: typeof ContextWatchdog;
411
+ /**
412
+ * @internal
413
+ */
414
+ private _verifyRootsWithInitialData;
411
415
  }
412
416
  /**
413
417
  * Fired whenever a root is {@link ~MultiRootEditor#addRoot added or re-added} to the editor model.
@@ -129,14 +129,20 @@ export default class MultiRootEditor extends DataApiMixin(Editor) {
129
129
  this.ui = new MultiRootEditorUI(this, view);
130
130
  this.model.document.on('change:data', () => {
131
131
  const changedRoots = this.model.document.differ.getChangedRoots();
132
+ // Fire detaches first. If there are multiple roots removed and added in one batch, it should be easier to handle if
133
+ // changes aren't mixed. Detaching will usually lead to just removing DOM elements. Detaching first will lead to a clean DOM
134
+ // when new editables are added in `addRoot` event.
135
+ for (const changes of changedRoots) {
136
+ const root = this.model.document.getRoot(changes.name);
137
+ if (changes.state == 'detached') {
138
+ this.fire('detachRoot', root);
139
+ }
140
+ }
132
141
  for (const changes of changedRoots) {
133
142
  const root = this.model.document.getRoot(changes.name);
134
143
  if (changes.state == 'attached') {
135
144
  this.fire('addRoot', root);
136
145
  }
137
- else if (changes.state == 'detached') {
138
- this.fire('detachRoot', root);
139
- }
140
146
  }
141
147
  });
142
148
  }
@@ -170,18 +176,14 @@ export default class MultiRootEditor extends DataApiMixin(Editor) {
170
176
  // It's safe to assume that the model->view conversion will not work after `super.destroy()`,
171
177
  // same as `ui.getEditableElement()` method will not return editables.
172
178
  const data = {};
173
- if (this.sourceElements) {
174
- for (const rootName of Object.keys(this.sourceElements)) {
175
- data[rootName] = shouldUpdateSourceElement ? this.getData({ rootName }) : '';
176
- }
179
+ for (const rootName of Object.keys(this.sourceElements)) {
180
+ data[rootName] = shouldUpdateSourceElement ? this.getData({ rootName }) : '';
177
181
  }
178
182
  this.ui.destroy();
179
183
  return super.destroy()
180
184
  .then(() => {
181
- if (this.sourceElements) {
182
- for (const rootName of Object.keys(this.sourceElements)) {
183
- setDataInElement(this.sourceElements[rootName], data[rootName]);
184
- }
185
+ for (const rootName of Object.keys(this.sourceElements)) {
186
+ setDataInElement(this.sourceElements[rootName], data[rootName]);
185
187
  }
186
188
  });
187
189
  }
@@ -549,11 +551,49 @@ export default class MultiRootEditor extends DataApiMixin(Editor) {
549
551
  const editor = new this(sourceElementsOrData, config);
550
552
  resolve(editor.initPlugins()
551
553
  .then(() => editor.ui.init())
552
- .then(() => editor.data.init(editor.config.get('initialData')))
554
+ .then(() => {
555
+ // This is checked directly before setting the initial data,
556
+ // as plugins may change `EditorConfig#initialData` value.
557
+ editor._verifyRootsWithInitialData();
558
+ return editor.data.init(editor.config.get('initialData'));
559
+ })
553
560
  .then(() => editor.fire('ready'))
554
561
  .then(() => editor));
555
562
  });
556
563
  }
564
+ /**
565
+ * @internal
566
+ */
567
+ _verifyRootsWithInitialData() {
568
+ const initialData = this.config.get('initialData');
569
+ // Roots that are not in the initial data.
570
+ for (const rootName of this.model.document.getRootNames()) {
571
+ if (!(rootName in initialData)) {
572
+ /**
573
+ * Editor roots do not match {@link module:core/editor/editorconfig~EditorConfig#initialData `initialData` configuration}.
574
+ *
575
+ * This can happen for one of the two reasons:
576
+ *
577
+ * * Configuration error. `sourceElementsOrData` parameter in
578
+ * {@link module:editor-multi-root/multirooteditor~MultiRootEditor.create `MultiRootEditor.create()`} contains different
579
+ * roots than {@link module:core/editor/editorconfig~EditorConfig#initialData `initialData` configuration}.
580
+ * * As the editor was initialized, {@link module:core/editor/editorconfig~EditorConfig#initialData `initialData`}
581
+ * configuration value or the state of the editor roots has been changed.
582
+ *
583
+ * @error multi-root-editor-root-initial-data-mismatch
584
+ */
585
+ throw new CKEditorError('multi-root-editor-root-initial-data-mismatch', null);
586
+ }
587
+ }
588
+ // Roots that are not in the editor.
589
+ for (const rootName of Object.keys(initialData)) {
590
+ const root = this.model.document.getRoot(rootName);
591
+ if (!root || !root.isAttached()) {
592
+ // eslint-disable-next-line ckeditor5-rules/ckeditor-error-message
593
+ throw new CKEditorError('multi-root-editor-root-initial-data-mismatch', null);
594
+ }
595
+ }
596
+ }
557
597
  }
558
598
  /**
559
599
  * The {@link module:core/context~Context} class.