@ckeditor/ckeditor5-editor-multi-root 38.2.0-alpha.1 → 39.0.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/README.md +0 -1
- package/build/editor-multi-root.js +1 -1
- package/package.json +3 -4
- package/src/augmentation.d.ts +11 -1
- package/src/index.d.ts +3 -3
- package/src/index.js +2 -2
- package/src/multirooteditor.d.ts +58 -7
- package/src/multirooteditor.js +96 -17
- package/src/multirooteditorui.d.ts +4 -4
- package/src/multirooteditorui.js +6 -7
- package/src/multirooteditoruiview.d.ts +3 -3
- package/src/multirooteditoruiview.js +1 -1
package/README.md
CHANGED
@@ -4,7 +4,6 @@ CKEditor 5 multi-root editor implementation
|
|
4
4
|
[](https://www.npmjs.com/package/@ckeditor/ckeditor5-editor-multi-root)
|
5
5
|
[](https://coveralls.io/github/ckeditor/ckeditor5?branch=master)
|
6
6
|
[](https://app.travis-ci.com/github/ckeditor/ckeditor5)
|
7
|
-

|
8
7
|
|
9
8
|
The multi-root editor implementation for CKEditor 5. Read more about the [multi-root editor build](https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/predefined-builds.html#multi-root-editor) and see the [demo](https://ckeditor.com/docs/ckeditor5/latest/examples/builds/multi-root-editor.html).
|
10
9
|
|
@@ -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 d 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 c=function(t){return null!=t&&"object"==typeof t};const l="object"==typeof global&&global&&global.Object===Object&&global;var h="object"==typeof self&&self&&self.Object===Object&&self;const u=(l||h||Function("return this")()).Symbol;var f=Object.prototype,b=f.hasOwnProperty,m=f.toString,g=u?u.toStringTag:void 0;const y=function(t){var e=b.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 E=Object.prototype.toString;const v=function(t){return E.call(t)};var w=u?u.toStringTag:void 0;const R=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":w&&w in Object(t)?y(t):v(t)};const p=function(t,e){return function(o){return t(e(o))}}(Object.getPrototypeOf,Object);var O=Function.prototype,j=Object.prototype,_=O.toString,C=j.hasOwnProperty,k=_.call(Object);const x=function(t){if(!c(t)||"[object Object]"!=R(t))return!1;var e=p(t);if(null===e)return!0;var o=C.call(e,"constructor")&&e.constructor;return"function"==typeof o&&o instanceof o&&_.call(o)==k};const T=function(t){return c(t)&&1===t.nodeType&&!x(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._readOnlyRootLocks=new Map,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]);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("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 c={shouldToolbarGroupWhenFull:!this.config.get("toolbar.shouldNotGroupWhenFull"),editableElements:r?void 0:o},l=new d(this.locale,this.editing.view,s,c);this.ui=new a(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.rootName;if(this._readOnlyRootLocks.has(e)){o=!0;break}}o&&(t.return=!1,t.stop())}),{priority:"high"})}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=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}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(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._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 D(t){return T(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 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(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])}const o=this.editor.editing.view,i=o.document.getRoot(t.name);e&&(i.placeholder=e),(0,n.enablePlaceholder)({view:o,element:i,isDirectHost:!1,keepOnFocus:!0})}}class d 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 c="object"==typeof global&&global&&global.Object===Object&&global;var h="object"==typeof self&&self&&self.Object===Object&&self;const u=(c||h||Function("return this")()).Symbol;var f=Object.prototype,m=f.hasOwnProperty,b=f.toString,g=u?u.toStringTag:void 0;const y=function(t){var e=m.call(t,g),o=t[g];try{t[g]=void 0;var i=!0}catch(t){}var s=b.call(t);return i&&(e?t[g]=o:delete t[g]),s};var E=Object.prototype.toString;const R=function(t){return E.call(t)};var v=u?u.toStringTag:void 0;const p=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":v&&v in Object(t)?y(t):R(t)};const w=function(t,e){return function(o){return t(e(o))}}(Object.getPrototypeOf,Object);var O=Function.prototype,j=Object.prototype,_=O.toString,C=j.hasOwnProperty,k=_.call(Object);const A=function(t){if(!l(t)||"[object Object]"!=p(t))return!1;var e=w(t);if(null===e)return!0;var o=C.call(e,"constructor")&&e.constructor;return"function"==typeof o&&o instanceof o&&_.call(o)==k};const x=function(t){return l(t)&&1===t.nodeType&&!A(t)};class D 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&&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(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]);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._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},c=new d(this.locale,this.editing.view,s,l);this.ui=new a(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=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}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._registeredRootsAttributesKeys.add(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}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 x(t)}D.Context=t.Context,D.EditorWatchdog=s.EditorWatchdog,D.ContextWatchdog=s.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": "
|
3
|
+
"version": "39.0.0",
|
4
4
|
"description": "Multi-root editor implementation for CKEditor 5.",
|
5
5
|
"keywords": [
|
6
6
|
"ckeditor",
|
@@ -10,10 +10,9 @@
|
|
10
10
|
"ckeditor5-dll"
|
11
11
|
],
|
12
12
|
"main": "src/index.js",
|
13
|
-
"type": "module",
|
14
13
|
"dependencies": {
|
15
|
-
"ckeditor5": "
|
16
|
-
"lodash-es": "
|
14
|
+
"ckeditor5": "39.0.0",
|
15
|
+
"lodash-es": "4.17.21"
|
17
16
|
},
|
18
17
|
"engines": {
|
19
18
|
"node": ">=16.0.0",
|
package/src/augmentation.d.ts
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
4
4
|
*/
|
5
|
-
import { type RootAttributes } from './multirooteditor
|
5
|
+
import { type RootAttributes } from './multirooteditor';
|
6
6
|
declare module '@ckeditor/ckeditor5-core' {
|
7
7
|
interface EditorConfig {
|
8
8
|
/**
|
@@ -76,5 +76,15 @@ declare module '@ckeditor/ckeditor5-core' {
|
|
76
76
|
* ```
|
77
77
|
*/
|
78
78
|
rootsAttributes?: Record<string, RootAttributes>;
|
79
|
+
/**
|
80
|
+
* List of names of all the roots that exist in the document but are not initially loaded by the editor.
|
81
|
+
*
|
82
|
+
* These roots can be loaded at any time after the editor has been initialized, using
|
83
|
+
* {@link module:editor-multi-root/multirooteditor~MultiRootEditor#loadRoot `MultiRootEditor#lazyRoot()`}.
|
84
|
+
*
|
85
|
+
* This is useful for handling big documents that contain hundreds of roots, or contain very large roots, which may have
|
86
|
+
* impact editor performance if loaded all together.
|
87
|
+
*/
|
88
|
+
lazyRoots?: Array<string>;
|
79
89
|
}
|
80
90
|
}
|
package/src/index.d.ts
CHANGED
@@ -5,6 +5,6 @@
|
|
5
5
|
/**
|
6
6
|
* @module editor-multi-root
|
7
7
|
*/
|
8
|
-
export { default as MultiRootEditor } from './multirooteditor
|
9
|
-
export type { RootAttributes } from './multirooteditor
|
10
|
-
import './augmentation
|
8
|
+
export { default as MultiRootEditor } from './multirooteditor';
|
9
|
+
export type { RootAttributes } from './multirooteditor';
|
10
|
+
import './augmentation';
|
package/src/index.js
CHANGED
package/src/multirooteditor.d.ts
CHANGED
@@ -5,11 +5,12 @@
|
|
5
5
|
/**
|
6
6
|
* @module editor-multi-root/multirooteditor
|
7
7
|
*/
|
8
|
-
import { Editor, Context, type EditorConfig } from 'ckeditor5/src/core
|
9
|
-
import {
|
10
|
-
import
|
11
|
-
import
|
12
|
-
|
8
|
+
import { Editor, Context, type EditorConfig } from 'ckeditor5/src/core';
|
9
|
+
import { type DecoratedMethodEvent } from 'ckeditor5/src/utils';
|
10
|
+
import { ContextWatchdog, EditorWatchdog } from 'ckeditor5/src/watchdog';
|
11
|
+
import MultiRootEditorUI from './multirooteditorui';
|
12
|
+
import { type RootElement } from 'ckeditor5/src/engine';
|
13
|
+
declare const MultiRootEditor_base: import("ckeditor5/src/utils").Mixed<typeof Editor, import("ckeditor5/src/core").DataApi>;
|
13
14
|
/**
|
14
15
|
* The {@glink installation/getting-started/predefined-builds#multi-root-editor multi-root editor} implementation.
|
15
16
|
*
|
@@ -241,6 +242,31 @@ export default class MultiRootEditor extends MultiRootEditor_base {
|
|
241
242
|
* @returns The DOM element that was detached. You may want to remove it from your application DOM structure.
|
242
243
|
*/
|
243
244
|
detachEditable(root: RootElement): HTMLElement;
|
245
|
+
/**
|
246
|
+
* Loads a root that has been previously declared in {@link module:core/editor/editorconfig~EditorConfig#lazyRoots `lazyRoots`}
|
247
|
+
* configuration option.
|
248
|
+
*
|
249
|
+
* Only roots specified in the editor config can be loaded. A root cannot be loaded multiple times. A root cannot be unloaded and
|
250
|
+
* loading a root cannot be reverted using the undo feature.
|
251
|
+
*
|
252
|
+
* When a root becomes loaded, it will be treated by the editor as though it was just added. This, among other, means that all
|
253
|
+
* related events and mechanisms will be fired, including {@link ~MultiRootEditor#event:addRoot `addRoot` event},
|
254
|
+
* {@link module:engine/model/document~Document#event:change `model.Document` `change` event}, model post-fixers and conversion.
|
255
|
+
*
|
256
|
+
* Until the root becomes loaded, all above mechanisms are suppressed.
|
257
|
+
*
|
258
|
+
* This method is {@link module:utils/observablemixin~Observable#decorate decorated}.
|
259
|
+
*
|
260
|
+
* When this method is used in real-time collaboration environment, its effects become asynchronous as the editor will first synchronize
|
261
|
+
* with the remote editing session, before the root is added to the editor.
|
262
|
+
*
|
263
|
+
* If the root has been already loaded by any other client, the additional data passed in `loadRoot()` parameters will be ignored.
|
264
|
+
*
|
265
|
+
* @param rootName Name of the root to load.
|
266
|
+
* @param options Additional options for the loaded root.
|
267
|
+
* @fires loadRoot
|
268
|
+
*/
|
269
|
+
loadRoot(rootName: string, { data, attributes }?: LoadRootOptions): void;
|
244
270
|
/**
|
245
271
|
* Returns the document data for all attached roots.
|
246
272
|
*
|
@@ -253,12 +279,23 @@ export default class MultiRootEditor extends MultiRootEditor_base {
|
|
253
279
|
*/
|
254
280
|
getFullData(options?: Record<string, unknown>): Record<string, string>;
|
255
281
|
/**
|
256
|
-
* Returns
|
257
|
-
*
|
282
|
+
* Returns attributes for all attached roots.
|
283
|
+
*
|
284
|
+
* Note: only attributes specified in {@link module:core/editor/editorconfig~EditorConfig#rootsAttributes `rootsAttributes`}
|
285
|
+
* configuration option will be returned.
|
258
286
|
*
|
259
287
|
* @returns Object with roots attributes. Keys are roots names, while values are attributes set on given root.
|
260
288
|
*/
|
261
289
|
getRootsAttributes(): Record<string, RootAttributes>;
|
290
|
+
/**
|
291
|
+
* Returns attributes for the specified root.
|
292
|
+
*
|
293
|
+
* Note: only attributes specified in {@link module:core/editor/editorconfig~EditorConfig#rootsAttributes `rootsAttributes`}
|
294
|
+
* configuration option will be returned.
|
295
|
+
*
|
296
|
+
* @param rootName
|
297
|
+
*/
|
298
|
+
getRootAttributes(rootName: string): RootAttributes;
|
262
299
|
/**
|
263
300
|
* Switches given editor root to the read-only mode.
|
264
301
|
*
|
@@ -494,6 +531,16 @@ export type DetachRootEvent = {
|
|
494
531
|
name: 'detachRoot';
|
495
532
|
args: [root: RootElement];
|
496
533
|
};
|
534
|
+
/**
|
535
|
+
* Event fired when {@link ~MultiRootEditor#loadRoot} method is called.
|
536
|
+
*
|
537
|
+
* The {@link ~MultiRootEditor#loadRoot default action of that method} is implemented as a
|
538
|
+
* listener to this event, so it can be fully customized by the features.
|
539
|
+
*
|
540
|
+
* @eventName ~MultiRootEditor#loadRoot
|
541
|
+
* @param args The arguments passed to the original method.
|
542
|
+
*/
|
543
|
+
export type LoadRootEvent = DecoratedMethodEvent<MultiRootEditor, 'loadRoot'>;
|
497
544
|
/**
|
498
545
|
* Additional options available when adding a root.
|
499
546
|
*/
|
@@ -515,6 +562,10 @@ export type AddRootOptions = {
|
|
515
562
|
*/
|
516
563
|
isUndoable?: boolean;
|
517
564
|
};
|
565
|
+
/**
|
566
|
+
* Additional options available when loading a root.
|
567
|
+
*/
|
568
|
+
export type LoadRootOptions = Omit<AddRootOptions, 'elementName' | 'isUndoable'>;
|
518
569
|
/**
|
519
570
|
* Attributes set on a model root element.
|
520
571
|
*/
|
package/src/multirooteditor.js
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
/**
|
6
6
|
* @module editor-multi-root/multirooteditor
|
7
7
|
*/
|
8
|
-
import { Editor, Context, DataApiMixin, secureSourceElement } from 'ckeditor5/src/core
|
9
|
-
import { CKEditorError, getDataFromElement, setDataInElement } from 'ckeditor5/src/utils
|
10
|
-
import { ContextWatchdog, EditorWatchdog } from 'ckeditor5/src/watchdog
|
11
|
-
import MultiRootEditorUI from './multirooteditorui
|
12
|
-
import MultiRootEditorUIView from './multirooteditoruiview
|
8
|
+
import { Editor, Context, DataApiMixin, secureSourceElement } from 'ckeditor5/src/core';
|
9
|
+
import { CKEditorError, getDataFromElement, setDataInElement, logWarning } from 'ckeditor5/src/utils';
|
10
|
+
import { ContextWatchdog, EditorWatchdog } from 'ckeditor5/src/watchdog';
|
11
|
+
import MultiRootEditorUI from './multirooteditorui';
|
12
|
+
import MultiRootEditorUIView from './multirooteditoruiview';
|
13
13
|
import { isElement as _isElement } from 'lodash-es';
|
14
14
|
/**
|
15
15
|
* The {@glink installation/getting-started/predefined-builds#multi-root-editor multi-root editor} implementation.
|
@@ -56,7 +56,7 @@ export default class MultiRootEditor extends DataApiMixin(Editor) {
|
|
56
56
|
constructor(sourceElementsOrData, config = {}) {
|
57
57
|
const rootNames = Object.keys(sourceElementsOrData);
|
58
58
|
const sourceIsData = rootNames.length === 0 || typeof sourceElementsOrData[rootNames[0]] === 'string';
|
59
|
-
if (sourceIsData && config.initialData !== undefined) {
|
59
|
+
if (sourceIsData && config.initialData !== undefined && Object.keys(config.initialData).length > 0) {
|
60
60
|
// Documented in core/editor/editorconfig.jsdoc.
|
61
61
|
// eslint-disable-next-line ckeditor5-rules/ckeditor-error-message
|
62
62
|
throw new CKEditorError('editor-create-initial-data', null);
|
@@ -113,10 +113,16 @@ export default class MultiRootEditor extends DataApiMixin(Editor) {
|
|
113
113
|
// Create root and `UIView` element for each editable container.
|
114
114
|
this.model.document.createRoot('$root', rootName);
|
115
115
|
}
|
116
|
+
if (this.config.get('lazyRoots')) {
|
117
|
+
for (const rootName of this.config.get('lazyRoots')) {
|
118
|
+
const root = this.model.document.createRoot('$root', rootName);
|
119
|
+
root._isLoaded = false;
|
120
|
+
}
|
121
|
+
}
|
116
122
|
if (this.config.get('rootsAttributes')) {
|
117
123
|
const rootsAttributes = this.config.get('rootsAttributes');
|
118
124
|
for (const [rootName, attributes] of Object.entries(rootsAttributes)) {
|
119
|
-
if (!
|
125
|
+
if (!this.model.document.getRoot(rootName)) {
|
120
126
|
/**
|
121
127
|
* Trying to set attributes on a non-existing root.
|
122
128
|
*
|
@@ -177,8 +183,8 @@ export default class MultiRootEditor extends DataApiMixin(Editor) {
|
|
177
183
|
}
|
178
184
|
let selectionInReadOnlyRoot = false;
|
179
185
|
for (const range of selection.getRanges()) {
|
180
|
-
const
|
181
|
-
if (this._readOnlyRootLocks.has(rootName)) {
|
186
|
+
const root = range.root;
|
187
|
+
if (this._readOnlyRootLocks.has(root.rootName)) {
|
182
188
|
selectionInReadOnlyRoot = true;
|
183
189
|
break;
|
184
190
|
}
|
@@ -190,6 +196,27 @@ export default class MultiRootEditor extends DataApiMixin(Editor) {
|
|
190
196
|
evt.stop();
|
191
197
|
}
|
192
198
|
}, { priority: 'high' });
|
199
|
+
this.decorate('loadRoot');
|
200
|
+
this.on('loadRoot', (evt, [rootName]) => {
|
201
|
+
const root = this.model.document.getRoot(rootName);
|
202
|
+
if (!root) {
|
203
|
+
/**
|
204
|
+
* The root to load does not exist.
|
205
|
+
*
|
206
|
+
* @error multi-root-editor-load-root-no-root
|
207
|
+
*/
|
208
|
+
throw new CKEditorError('multi-root-editor-load-root-no-root', this, { rootName });
|
209
|
+
}
|
210
|
+
if (root._isLoaded) {
|
211
|
+
/**
|
212
|
+
* The root to load was already loaded before. The `loadRoot()` call has no effect.
|
213
|
+
*
|
214
|
+
* @error multi-root-editor-load-root-already-loaded
|
215
|
+
*/
|
216
|
+
logWarning('multi-root-editor-load-root-already-loaded');
|
217
|
+
evt.stop();
|
218
|
+
}
|
219
|
+
}, { priority: 'highest' });
|
193
220
|
}
|
194
221
|
/**
|
195
222
|
* Destroys the editor instance, releasing all resources used by it.
|
@@ -415,6 +442,45 @@ export default class MultiRootEditor extends DataApiMixin(Editor) {
|
|
415
442
|
this.ui.view.removeEditable(rootName);
|
416
443
|
return editable.element;
|
417
444
|
}
|
445
|
+
/**
|
446
|
+
* Loads a root that has been previously declared in {@link module:core/editor/editorconfig~EditorConfig#lazyRoots `lazyRoots`}
|
447
|
+
* configuration option.
|
448
|
+
*
|
449
|
+
* Only roots specified in the editor config can be loaded. A root cannot be loaded multiple times. A root cannot be unloaded and
|
450
|
+
* loading a root cannot be reverted using the undo feature.
|
451
|
+
*
|
452
|
+
* When a root becomes loaded, it will be treated by the editor as though it was just added. This, among other, means that all
|
453
|
+
* related events and mechanisms will be fired, including {@link ~MultiRootEditor#event:addRoot `addRoot` event},
|
454
|
+
* {@link module:engine/model/document~Document#event:change `model.Document` `change` event}, model post-fixers and conversion.
|
455
|
+
*
|
456
|
+
* Until the root becomes loaded, all above mechanisms are suppressed.
|
457
|
+
*
|
458
|
+
* This method is {@link module:utils/observablemixin~Observable#decorate decorated}.
|
459
|
+
*
|
460
|
+
* When this method is used in real-time collaboration environment, its effects become asynchronous as the editor will first synchronize
|
461
|
+
* with the remote editing session, before the root is added to the editor.
|
462
|
+
*
|
463
|
+
* If the root has been already loaded by any other client, the additional data passed in `loadRoot()` parameters will be ignored.
|
464
|
+
*
|
465
|
+
* @param rootName Name of the root to load.
|
466
|
+
* @param options Additional options for the loaded root.
|
467
|
+
* @fires loadRoot
|
468
|
+
*/
|
469
|
+
loadRoot(rootName, { data = '', attributes = {} } = {}) {
|
470
|
+
// `root` will be defined as it is guaranteed by a check in a higher priority callback.
|
471
|
+
const root = this.model.document.getRoot(rootName);
|
472
|
+
this.model.enqueueChange({ isUndoable: false }, writer => {
|
473
|
+
if (data) {
|
474
|
+
writer.insert(this.data.parse(data, root), root, 0);
|
475
|
+
}
|
476
|
+
for (const key of Object.keys(attributes)) {
|
477
|
+
this._registeredRootsAttributesKeys.add(key);
|
478
|
+
writer.setAttribute(key, attributes[key], root);
|
479
|
+
}
|
480
|
+
root._isLoaded = true;
|
481
|
+
this.model.document.differ._bufferRootLoad(root);
|
482
|
+
});
|
483
|
+
}
|
418
484
|
/**
|
419
485
|
* Returns the document data for all attached roots.
|
420
486
|
*
|
@@ -433,23 +499,36 @@ export default class MultiRootEditor extends DataApiMixin(Editor) {
|
|
433
499
|
return data;
|
434
500
|
}
|
435
501
|
/**
|
436
|
-
* Returns
|
437
|
-
*
|
502
|
+
* Returns attributes for all attached roots.
|
503
|
+
*
|
504
|
+
* Note: only attributes specified in {@link module:core/editor/editorconfig~EditorConfig#rootsAttributes `rootsAttributes`}
|
505
|
+
* configuration option will be returned.
|
438
506
|
*
|
439
507
|
* @returns Object with roots attributes. Keys are roots names, while values are attributes set on given root.
|
440
508
|
*/
|
441
509
|
getRootsAttributes() {
|
442
510
|
const rootsAttributes = {};
|
443
|
-
const keys = Array.from(this._registeredRootsAttributesKeys);
|
444
511
|
for (const rootName of this.model.document.getRootNames()) {
|
445
|
-
rootsAttributes[rootName] =
|
446
|
-
const root = this.model.document.getRoot(rootName);
|
447
|
-
for (const key of keys) {
|
448
|
-
rootsAttributes[rootName][key] = root.hasAttribute(key) ? root.getAttribute(key) : null;
|
449
|
-
}
|
512
|
+
rootsAttributes[rootName] = this.getRootAttributes(rootName);
|
450
513
|
}
|
451
514
|
return rootsAttributes;
|
452
515
|
}
|
516
|
+
/**
|
517
|
+
* Returns attributes for the specified root.
|
518
|
+
*
|
519
|
+
* Note: only attributes specified in {@link module:core/editor/editorconfig~EditorConfig#rootsAttributes `rootsAttributes`}
|
520
|
+
* configuration option will be returned.
|
521
|
+
*
|
522
|
+
* @param rootName
|
523
|
+
*/
|
524
|
+
getRootAttributes(rootName) {
|
525
|
+
const rootAttributes = {};
|
526
|
+
const root = this.model.document.getRoot(rootName);
|
527
|
+
for (const key of this._registeredRootsAttributesKeys) {
|
528
|
+
rootAttributes[key] = root.hasAttribute(key) ? root.getAttribute(key) : null;
|
529
|
+
}
|
530
|
+
return rootAttributes;
|
531
|
+
}
|
453
532
|
/**
|
454
533
|
* Switches given editor root to the read-only mode.
|
455
534
|
*
|
@@ -5,9 +5,9 @@
|
|
5
5
|
/**
|
6
6
|
* @module editor-multi-root/multirooteditorui
|
7
7
|
*/
|
8
|
-
import { type Editor } from 'ckeditor5/src/core
|
9
|
-
import { EditorUI, type InlineEditableUIView } from 'ckeditor5/src/ui
|
10
|
-
import type MultiRootEditorUIView from './multirooteditoruiview
|
8
|
+
import { type Editor } from 'ckeditor5/src/core';
|
9
|
+
import { EditorUI, type InlineEditableUIView } from 'ckeditor5/src/ui';
|
10
|
+
import type MultiRootEditorUIView from './multirooteditoruiview';
|
11
11
|
/**
|
12
12
|
* The multi-root editor UI class.
|
13
13
|
*/
|
@@ -64,7 +64,7 @@ export default class MultiRootEditorUI extends EditorUI {
|
|
64
64
|
*/
|
65
65
|
private _initToolbar;
|
66
66
|
/**
|
67
|
-
* Enables the placeholder text on a given editable
|
67
|
+
* Enables the placeholder text on a given editable.
|
68
68
|
*
|
69
69
|
* @param editable Editable on which the placeholder should be set.
|
70
70
|
* @param placeholder Placeholder for the editable element. If not set, placeholder value from the
|
package/src/multirooteditorui.js
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
3
3
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
4
4
|
*/
|
5
|
-
import { EditorUI } from 'ckeditor5/src/ui
|
6
|
-
import { enablePlaceholder } from 'ckeditor5/src/engine
|
5
|
+
import { EditorUI } from 'ckeditor5/src/ui';
|
6
|
+
import { enablePlaceholder } from 'ckeditor5/src/engine';
|
7
7
|
/**
|
8
8
|
* The multi-root editor UI class.
|
9
9
|
*/
|
@@ -140,7 +140,7 @@ export default class MultiRootEditorUI extends EditorUI {
|
|
140
140
|
this.addToolbar(view.toolbar);
|
141
141
|
}
|
142
142
|
/**
|
143
|
-
* Enables the placeholder text on a given editable
|
143
|
+
* Enables the placeholder text on a given editable.
|
144
144
|
*
|
145
145
|
* @param editable Editable on which the placeholder should be set.
|
146
146
|
* @param placeholder Placeholder for the editable element. If not set, placeholder value from the
|
@@ -153,15 +153,14 @@ export default class MultiRootEditorUI extends EditorUI {
|
|
153
153
|
placeholder = typeof configPlaceholder === 'string' ? configPlaceholder : configPlaceholder[editable.name];
|
154
154
|
}
|
155
155
|
}
|
156
|
-
if (!placeholder) {
|
157
|
-
return;
|
158
|
-
}
|
159
156
|
const editingView = this.editor.editing.view;
|
160
157
|
const editingRoot = editingView.document.getRoot(editable.name);
|
158
|
+
if (placeholder) {
|
159
|
+
editingRoot.placeholder = placeholder;
|
160
|
+
}
|
161
161
|
enablePlaceholder({
|
162
162
|
view: editingView,
|
163
163
|
element: editingRoot,
|
164
|
-
text: placeholder,
|
165
164
|
isDirectHost: false,
|
166
165
|
keepOnFocus: true
|
167
166
|
});
|
@@ -5,9 +5,9 @@
|
|
5
5
|
/**
|
6
6
|
* @module editor-multi-root/multirooteditoruiview
|
7
7
|
*/
|
8
|
-
import { EditorUIView, InlineEditableUIView, ToolbarView } from 'ckeditor5/src/ui
|
9
|
-
import type { Locale } from 'ckeditor5/src/utils
|
10
|
-
import type { View } from 'ckeditor5/src/engine
|
8
|
+
import { EditorUIView, InlineEditableUIView, ToolbarView } from 'ckeditor5/src/ui';
|
9
|
+
import type { Locale } from 'ckeditor5/src/utils';
|
10
|
+
import type { View } from 'ckeditor5/src/engine';
|
11
11
|
/**
|
12
12
|
* The multi-root editor UI view. It is a virtual view providing an inline
|
13
13
|
* {@link module:editor-multi-root/multirooteditoruiview~MultiRootEditorUIView#editable} and a
|
@@ -5,7 +5,7 @@
|
|
5
5
|
/**
|
6
6
|
* @module editor-multi-root/multirooteditoruiview
|
7
7
|
*/
|
8
|
-
import { EditorUIView, InlineEditableUIView, ToolbarView } from 'ckeditor5/src/ui
|
8
|
+
import { EditorUIView, InlineEditableUIView, ToolbarView } from 'ckeditor5/src/ui';
|
9
9
|
/**
|
10
10
|
* The multi-root editor UI view. It is a virtual view providing an inline
|
11
11
|
* {@link module:editor-multi-root/multirooteditoruiview~MultiRootEditorUIView#editable} and a
|