@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.
- package/build/editor-multi-root.js +1 -1
- package/package.json +15 -15
- package/src/multirooteditor.d.ts +4 -0
- package/src/multirooteditor.js +52 -12
@@ -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
|
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
|
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
|
14
|
+
"ckeditor5": "^37.1.0",
|
15
15
|
"lodash-es": "^4.17.15"
|
16
16
|
},
|
17
17
|
"devDependencies": {
|
18
|
-
"@ckeditor/ckeditor5-basic-styles": "^37.0
|
19
|
-
"@ckeditor/ckeditor5-core": "^37.0
|
20
|
-
"@ckeditor/ckeditor5-dev-utils": "^
|
21
|
-
"@ckeditor/ckeditor5-engine": "^37.0
|
22
|
-
"@ckeditor/ckeditor5-enter": "^37.0
|
23
|
-
"@ckeditor/ckeditor5-heading": "^37.0
|
24
|
-
"@ckeditor/ckeditor5-paragraph": "^37.0
|
25
|
-
"@ckeditor/ckeditor5-theme-lark": "^37.0
|
26
|
-
"@ckeditor/ckeditor5-typing": "^37.0
|
27
|
-
"@ckeditor/ckeditor5-ui": "^37.0
|
28
|
-
"@ckeditor/ckeditor5-undo": "^37.0
|
29
|
-
"@ckeditor/ckeditor5-utils": "^37.0
|
30
|
-
"@ckeditor/ckeditor5-watchdog": "^37.0
|
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"
|
package/src/multirooteditor.d.ts
CHANGED
@@ -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.
|
package/src/multirooteditor.js
CHANGED
@@ -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
|
-
|
174
|
-
|
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
|
-
|
182
|
-
|
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(() =>
|
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.
|