@ckeditor/ckeditor5-engine 31.1.0 → 34.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/LICENSE.md +2 -2
- package/README.md +2 -1
- package/package.json +25 -25
- package/src/controller/datacontroller.js +65 -74
- package/src/controller/editingcontroller.js +83 -6
- package/src/conversion/conversion.js +15 -14
- package/src/conversion/conversionhelpers.js +1 -1
- package/src/conversion/downcastdispatcher.js +298 -367
- package/src/conversion/downcasthelpers.js +860 -81
- package/src/conversion/mapper.js +105 -60
- package/src/conversion/modelconsumable.js +85 -35
- package/src/conversion/upcastdispatcher.js +34 -7
- package/src/conversion/upcasthelpers.js +4 -2
- package/src/conversion/viewconsumable.js +1 -1
- package/src/dataprocessor/basichtmlwriter.js +1 -1
- package/src/dataprocessor/dataprocessor.jsdoc +1 -1
- package/src/dataprocessor/htmldataprocessor.js +9 -31
- package/src/dataprocessor/htmlwriter.js +1 -1
- package/src/dataprocessor/xmldataprocessor.js +1 -1
- package/src/dev-utils/model.js +16 -14
- package/src/dev-utils/operationreplayer.js +1 -1
- package/src/dev-utils/utils.js +1 -1
- package/src/dev-utils/view.js +1 -1
- package/src/index.js +8 -1
- package/src/model/batch.js +77 -10
- package/src/model/differ.js +115 -69
- package/src/model/document.js +13 -4
- package/src/model/documentfragment.js +1 -1
- package/src/model/documentselection.js +1 -1
- package/src/model/element.js +1 -1
- package/src/model/history.js +1 -1
- package/src/model/item.jsdoc +1 -1
- package/src/model/liveposition.js +1 -1
- package/src/model/liverange.js +1 -1
- package/src/model/markercollection.js +29 -5
- package/src/model/model.js +138 -12
- package/src/model/node.js +1 -1
- package/src/model/nodelist.js +1 -1
- package/src/model/operation/attributeoperation.js +1 -1
- package/src/model/operation/detachoperation.js +1 -1
- package/src/model/operation/insertoperation.js +1 -1
- package/src/model/operation/markeroperation.js +1 -1
- package/src/model/operation/mergeoperation.js +1 -1
- package/src/model/operation/moveoperation.js +1 -1
- package/src/model/operation/nooperation.js +1 -1
- package/src/model/operation/operation.js +1 -1
- package/src/model/operation/operationfactory.js +1 -1
- package/src/model/operation/renameoperation.js +1 -1
- package/src/model/operation/rootattributeoperation.js +1 -1
- package/src/model/operation/splitoperation.js +1 -1
- package/src/model/operation/transform.js +1 -1
- package/src/model/operation/utils.js +1 -1
- package/src/model/position.js +1 -1
- package/src/model/range.js +1 -1
- package/src/model/rootelement.js +1 -1
- package/src/model/schema.js +80 -11
- package/src/model/selection.js +1 -1
- package/src/model/text.js +1 -1
- package/src/model/textproxy.js +1 -1
- package/src/model/treewalker.js +3 -4
- package/src/model/utils/autoparagraphing.js +1 -1
- package/src/model/utils/deletecontent.js +16 -3
- package/src/model/utils/findoptimalinsertionrange.js +68 -0
- package/src/model/utils/getselectedcontent.js +1 -1
- package/src/model/utils/insertcontent.js +1 -1
- package/src/model/utils/insertobject.js +173 -0
- package/src/model/utils/modifyselection.js +15 -8
- package/src/model/utils/selection-post-fixer.js +1 -1
- package/src/model/writer.js +17 -27
- package/src/view/attributeelement.js +1 -11
- package/src/view/containerelement.js +1 -1
- package/src/view/document.js +3 -2
- package/src/view/documentfragment.js +1 -1
- package/src/view/documentselection.js +1 -1
- package/src/view/domconverter.js +55 -28
- package/src/view/downcastwriter.js +91 -50
- package/src/view/editableelement.js +1 -1
- package/src/view/element.js +1 -28
- package/src/view/elementdefinition.jsdoc +1 -1
- package/src/view/emptyelement.js +1 -4
- package/src/view/filler.js +1 -1
- package/src/view/item.jsdoc +1 -1
- package/src/view/matcher.js +3 -3
- package/src/view/node.js +1 -1
- package/src/view/observer/arrowkeysobserver.js +1 -1
- package/src/view/observer/bubblingemittermixin.js +1 -1
- package/src/view/observer/bubblingeventinfo.js +1 -1
- package/src/view/observer/clickobserver.js +1 -2
- package/src/view/observer/compositionobserver.js +1 -1
- package/src/view/observer/domeventdata.js +1 -1
- package/src/view/observer/domeventobserver.js +1 -1
- package/src/view/observer/fakeselectionobserver.js +1 -1
- package/src/view/observer/focusobserver.js +1 -1
- package/src/view/observer/inputobserver.js +2 -2
- package/src/view/observer/keyobserver.js +1 -1
- package/src/view/observer/mouseobserver.js +1 -1
- package/src/view/observer/mutationobserver.js +1 -1
- package/src/view/observer/observer.js +1 -1
- package/src/view/observer/selectionobserver.js +1 -1
- package/src/view/observer/tabobserver.js +68 -0
- package/src/view/placeholder.js +2 -2
- package/src/view/position.js +1 -1
- package/src/view/range.js +1 -1
- package/src/view/rawelement.js +1 -4
- package/src/view/renderer.js +3 -2
- package/src/view/rooteditableelement.js +1 -1
- package/src/view/selection.js +1 -1
- package/src/view/styles/background.js +1 -1
- package/src/view/styles/border.js +1 -1
- package/src/view/styles/margin.js +1 -1
- package/src/view/styles/padding.js +1 -1
- package/src/view/styles/utils.js +1 -1
- package/src/view/stylesmap.js +1 -1
- package/src/view/text.js +1 -1
- package/src/view/textproxy.js +1 -1
- package/src/view/treewalker.js +1 -1
- package/src/view/uielement.js +1 -4
- package/src/view/upcastwriter.js +1 -1
- package/src/view/view.js +5 -1
- package/theme/placeholder.css +10 -1
- package/theme/renderer.css +1 -1
package/LICENSE.md
CHANGED
|
@@ -2,7 +2,7 @@ Software License Agreement
|
|
|
2
2
|
==========================
|
|
3
3
|
|
|
4
4
|
**CKEditor 5 editing engine** – https://github.com/ckeditor/ckeditor5-engine <br>
|
|
5
|
-
Copyright (c) 2003-
|
|
5
|
+
Copyright (c) 2003-2022, [CKSource](http://cksource.com) Holding sp. z o.o. All rights reserved.
|
|
6
6
|
|
|
7
7
|
Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html).
|
|
8
8
|
|
|
@@ -14,4 +14,4 @@ Where not otherwise indicated, all CKEditor content is authored by CKSource engi
|
|
|
14
14
|
Trademarks
|
|
15
15
|
----------
|
|
16
16
|
|
|
17
|
-
**CKEditor** is a trademark of [CKSource](http://cksource.com)
|
|
17
|
+
**CKEditor** is a trademark of [CKSource](http://cksource.com) Holding sp. z o.o. All other brand and product names are trademarks, registered trademarks or service marks of their respective holders.
|
package/README.md
CHANGED
|
@@ -3,7 +3,8 @@ CKEditor 5 editing engine
|
|
|
3
3
|
|
|
4
4
|
[](https://www.npmjs.com/package/@ckeditor/ckeditor5-engine)
|
|
5
5
|
[](https://coveralls.io/github/ckeditor/ckeditor5?branch=master)
|
|
6
|
-
[](https://travis-ci.com/ckeditor/ckeditor5)
|
|
6
|
+
[](https://app.travis-ci.com/github/ckeditor/ckeditor5)
|
|
7
|
+

|
|
7
8
|
|
|
8
9
|
The CKEditor 5 editing engine implements a flexible MVC-based architecture for creating rich text editing features.
|
|
9
10
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckeditor/ckeditor5-engine",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "34.0.0",
|
|
4
4
|
"description": "The editing engine of CKEditor 5 – the best browser-based rich text editor.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wysiwyg",
|
|
@@ -23,35 +23,35 @@
|
|
|
23
23
|
],
|
|
24
24
|
"main": "src/index.js",
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@ckeditor/ckeditor5-utils": "^
|
|
26
|
+
"@ckeditor/ckeditor5-utils": "^34.0.0",
|
|
27
27
|
"lodash-es": "^4.17.15"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@ckeditor/ckeditor5-basic-styles": "^
|
|
31
|
-
"@ckeditor/ckeditor5-block-quote": "^
|
|
32
|
-
"@ckeditor/ckeditor5-clipboard": "^
|
|
33
|
-
"@ckeditor/ckeditor5-cloud-services": "^
|
|
34
|
-
"@ckeditor/ckeditor5-core": "^
|
|
35
|
-
"@ckeditor/ckeditor5-editor-classic": "^
|
|
36
|
-
"@ckeditor/ckeditor5-enter": "^
|
|
37
|
-
"@ckeditor/ckeditor5-essentials": "^
|
|
38
|
-
"@ckeditor/ckeditor5-heading": "^
|
|
39
|
-
"@ckeditor/ckeditor5-image": "^
|
|
40
|
-
"@ckeditor/ckeditor5-link": "^
|
|
41
|
-
"@ckeditor/ckeditor5-list": "^
|
|
42
|
-
"@ckeditor/ckeditor5-mention": "^
|
|
43
|
-
"@ckeditor/ckeditor5-paragraph": "^
|
|
44
|
-
"@ckeditor/ckeditor5-table": "^
|
|
45
|
-
"@ckeditor/ckeditor5-theme-lark": "^
|
|
46
|
-
"@ckeditor/ckeditor5-typing": "^
|
|
47
|
-
"@ckeditor/ckeditor5-ui": "^
|
|
48
|
-
"@ckeditor/ckeditor5-undo": "^
|
|
49
|
-
"@ckeditor/ckeditor5-widget": "^
|
|
50
|
-
"webpack": "^
|
|
51
|
-
"webpack-cli": "^
|
|
30
|
+
"@ckeditor/ckeditor5-basic-styles": "^34.0.0",
|
|
31
|
+
"@ckeditor/ckeditor5-block-quote": "^34.0.0",
|
|
32
|
+
"@ckeditor/ckeditor5-clipboard": "^34.0.0",
|
|
33
|
+
"@ckeditor/ckeditor5-cloud-services": "^34.0.0",
|
|
34
|
+
"@ckeditor/ckeditor5-core": "^34.0.0",
|
|
35
|
+
"@ckeditor/ckeditor5-editor-classic": "^34.0.0",
|
|
36
|
+
"@ckeditor/ckeditor5-enter": "^34.0.0",
|
|
37
|
+
"@ckeditor/ckeditor5-essentials": "^34.0.0",
|
|
38
|
+
"@ckeditor/ckeditor5-heading": "^34.0.0",
|
|
39
|
+
"@ckeditor/ckeditor5-image": "^34.0.0",
|
|
40
|
+
"@ckeditor/ckeditor5-link": "^34.0.0",
|
|
41
|
+
"@ckeditor/ckeditor5-list": "^34.0.0",
|
|
42
|
+
"@ckeditor/ckeditor5-mention": "^34.0.0",
|
|
43
|
+
"@ckeditor/ckeditor5-paragraph": "^34.0.0",
|
|
44
|
+
"@ckeditor/ckeditor5-table": "^34.0.0",
|
|
45
|
+
"@ckeditor/ckeditor5-theme-lark": "^34.0.0",
|
|
46
|
+
"@ckeditor/ckeditor5-typing": "^34.0.0",
|
|
47
|
+
"@ckeditor/ckeditor5-ui": "^34.0.0",
|
|
48
|
+
"@ckeditor/ckeditor5-undo": "^34.0.0",
|
|
49
|
+
"@ckeditor/ckeditor5-widget": "^34.0.0",
|
|
50
|
+
"webpack": "^5.58.1",
|
|
51
|
+
"webpack-cli": "^4.9.0"
|
|
52
52
|
},
|
|
53
53
|
"engines": {
|
|
54
|
-
"node": ">=
|
|
54
|
+
"node": ">=14.0.0",
|
|
55
55
|
"npm": ">=5.7.1"
|
|
56
56
|
},
|
|
57
57
|
"author": "CKSource (http://cksource.com/)",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Copyright (c) 2003-
|
|
2
|
+
* @license Copyright (c) 2003-2022, 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
5
|
|
|
@@ -14,7 +14,7 @@ import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
|
|
|
14
14
|
import Mapper from '../conversion/mapper';
|
|
15
15
|
|
|
16
16
|
import DowncastDispatcher from '../conversion/downcastdispatcher';
|
|
17
|
-
import { insertText } from '../conversion/downcasthelpers';
|
|
17
|
+
import { insertAttributesAndChildren, insertText } from '../conversion/downcasthelpers';
|
|
18
18
|
|
|
19
19
|
import UpcastDispatcher from '../conversion/upcastdispatcher';
|
|
20
20
|
import { convertText, convertToModelFragment } from '../conversion/upcasthelpers';
|
|
@@ -31,7 +31,7 @@ import HtmlDataProcessor from '../dataprocessor/htmldataprocessor';
|
|
|
31
31
|
* Controller for the data pipeline. The data pipeline controls how data is retrieved from the document
|
|
32
32
|
* and set inside it. Hence, the controller features two methods which allow to {@link ~DataController#get get}
|
|
33
33
|
* and {@link ~DataController#set set} data of the {@link ~DataController#model model}
|
|
34
|
-
* using given:
|
|
34
|
+
* using the given:
|
|
35
35
|
*
|
|
36
36
|
* * {@link module:engine/dataprocessor/dataprocessor~DataProcessor data processor},
|
|
37
37
|
* * downcast converters,
|
|
@@ -61,8 +61,8 @@ export default class DataController {
|
|
|
61
61
|
this.model = model;
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
|
-
* Mapper used for the conversion. It has no permanent bindings, because
|
|
65
|
-
* cleared directly after the data are converted. However, the mapper is defined as a class property, because
|
|
64
|
+
* Mapper used for the conversion. It has no permanent bindings, because these are created while getting data and
|
|
65
|
+
* ae cleared directly after the data are converted. However, the mapper is defined as a class property, because
|
|
66
66
|
* it needs to be passed to the `DowncastDispatcher` as a conversion API.
|
|
67
67
|
*
|
|
68
68
|
* @readonly
|
|
@@ -81,6 +81,7 @@ export default class DataController {
|
|
|
81
81
|
schema: model.schema
|
|
82
82
|
} );
|
|
83
83
|
this.downcastDispatcher.on( 'insert:$text', insertText(), { priority: 'lowest' } );
|
|
84
|
+
this.downcastDispatcher.on( 'insert', insertAttributesAndChildren(), { priority: 'lowest' } );
|
|
84
85
|
|
|
85
86
|
/**
|
|
86
87
|
* Upcast dispatcher used by the {@link #set set method}. Upcast converters should be attached to it.
|
|
@@ -138,7 +139,7 @@ export default class DataController {
|
|
|
138
139
|
//
|
|
139
140
|
// Note that if there is no default converter for the element it will be skipped, for instance `<b>foo</b>` will be
|
|
140
141
|
// converted to nothing. We therefore add `convertToModelFragment` as a last converter so it converts children of that
|
|
141
|
-
// element to the document fragment
|
|
142
|
+
// element to the document fragment so `<b>foo</b>` will still be converted to `foo` even if there is no converter for `<b>`.
|
|
142
143
|
this.upcastDispatcher.on( 'text', convertText(), { priority: 'lowest' } );
|
|
143
144
|
this.upcastDispatcher.on( 'element', convertToModelFragment(), { priority: 'lowest' } );
|
|
144
145
|
this.upcastDispatcher.on( 'documentFragment', convertToModelFragment(), { priority: 'lowest' } );
|
|
@@ -147,16 +148,16 @@ export default class DataController {
|
|
|
147
148
|
this.decorate( 'set' );
|
|
148
149
|
this.decorate( 'get' );
|
|
149
150
|
|
|
150
|
-
// Fire the `ready` event when the initialization has completed. Such low-level listener
|
|
151
|
+
// Fire the `ready` event when the initialization has completed. Such low-level listener offers the possibility
|
|
151
152
|
// to plug into the initialization pipeline without interrupting the initialization flow.
|
|
152
153
|
this.on( 'init', () => {
|
|
153
154
|
this.fire( 'ready' );
|
|
154
155
|
}, { priority: 'lowest' } );
|
|
155
156
|
|
|
156
|
-
// Fix empty roots after DataController is 'ready' (note that init method could be decorated and stopped).
|
|
157
|
-
// We need to handle this event because initial data could be empty and post-fixer would not get triggered.
|
|
157
|
+
// Fix empty roots after DataController is 'ready' (note that the init method could be decorated and stopped).
|
|
158
|
+
// We need to handle this event because initial data could be empty and the post-fixer would not get triggered.
|
|
158
159
|
this.on( 'ready', () => {
|
|
159
|
-
this.model.enqueueChange(
|
|
160
|
+
this.model.enqueueChange( { isUndoable: false }, autoParagraphEmptyRoots );
|
|
160
161
|
}, { priority: 'lowest' } );
|
|
161
162
|
}
|
|
162
163
|
|
|
@@ -170,7 +171,7 @@ export default class DataController {
|
|
|
170
171
|
* @param {String} [options.rootName='main'] Root name.
|
|
171
172
|
* @param {String} [options.trim='empty'] Whether returned data should be trimmed. This option is set to `empty` by default,
|
|
172
173
|
* which means whenever editor content is considered empty, an empty string will be returned. To turn off trimming completely
|
|
173
|
-
* use `'none'`. In such cases exact content will be returned (for example `<p> </p>` for an empty editor).
|
|
174
|
+
* use `'none'`. In such cases the exact content will be returned (for example a `<p> </p>` for an empty editor).
|
|
174
175
|
* @returns {String} Output data.
|
|
175
176
|
*/
|
|
176
177
|
get( options = {} ) {
|
|
@@ -179,7 +180,7 @@ export default class DataController {
|
|
|
179
180
|
if ( !this._checkIfRootsExists( [ rootName ] ) ) {
|
|
180
181
|
/**
|
|
181
182
|
* Cannot get data from a non-existing root. This error is thrown when {@link #get DataController#get() method}
|
|
182
|
-
* is called with non-existent root name. For example, if there is an editor instance with only `main` root,
|
|
183
|
+
* is called with a non-existent root name. For example, if there is an editor instance with only `main` root,
|
|
183
184
|
* calling {@link #get} like:
|
|
184
185
|
*
|
|
185
186
|
* data.get( { rootName: 'root2' } );
|
|
@@ -203,10 +204,10 @@ export default class DataController {
|
|
|
203
204
|
/**
|
|
204
205
|
* Returns the content of the given {@link module:engine/model/element~Element model's element} or
|
|
205
206
|
* {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the downcast converters
|
|
206
|
-
* attached to {@link #downcastDispatcher} and formatted by the {@link #processor data processor}.
|
|
207
|
+
* attached to the {@link #downcastDispatcher} and formatted by the {@link #processor data processor}.
|
|
207
208
|
*
|
|
208
209
|
* @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} modelElementOrFragment
|
|
209
|
-
*
|
|
210
|
+
* The element whose content will be stringified.
|
|
210
211
|
* @param {Object} [options] Additional configuration passed to the conversion process.
|
|
211
212
|
* @returns {String} Output data.
|
|
212
213
|
*/
|
|
@@ -221,12 +222,12 @@ export default class DataController {
|
|
|
221
222
|
/**
|
|
222
223
|
* Returns the content of the given {@link module:engine/model/element~Element model element} or
|
|
223
224
|
* {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the downcast
|
|
224
|
-
* converters attached to {@link #downcastDispatcher}
|
|
225
|
+
* converters attached to {@link #downcastDispatcher} into a
|
|
225
226
|
* {@link module:engine/view/documentfragment~DocumentFragment view document fragment}.
|
|
226
227
|
*
|
|
227
228
|
* @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} modelElementOrFragment
|
|
228
229
|
* Element or document fragment whose content will be converted.
|
|
229
|
-
* @param {Object} [options={}] Additional configuration that will be available through
|
|
230
|
+
* @param {Object} [options={}] Additional configuration that will be available through the
|
|
230
231
|
* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi#options} during the conversion process.
|
|
231
232
|
* @returns {module:engine/view/documentfragment~DocumentFragment} Output view DocumentFragment.
|
|
232
233
|
*/
|
|
@@ -234,7 +235,7 @@ export default class DataController {
|
|
|
234
235
|
const viewDocument = this.viewDocument;
|
|
235
236
|
const viewWriter = this._viewWriter;
|
|
236
237
|
|
|
237
|
-
// Clear bindings so the call to this method
|
|
238
|
+
// Clear bindings so the call to this method returns correct results.
|
|
238
239
|
this.mapper.clearBindings();
|
|
239
240
|
|
|
240
241
|
// First, convert elements.
|
|
@@ -243,57 +244,46 @@ export default class DataController {
|
|
|
243
244
|
|
|
244
245
|
this.mapper.bindElements( modelElementOrFragment, viewDocumentFragment );
|
|
245
246
|
|
|
246
|
-
//
|
|
247
|
-
this.downcastDispatcher.conversionApi.options = options;
|
|
248
|
-
|
|
249
|
-
// We have no view controller and rendering to DOM in DataController so view.change() block is not used here.
|
|
250
|
-
this.downcastDispatcher.convertInsert( modelRange, viewWriter );
|
|
251
|
-
|
|
252
|
-
// Convert markers.
|
|
247
|
+
// Prepare list of markers.
|
|
253
248
|
// For document fragment, simply take the markers assigned to this document fragment.
|
|
254
249
|
// For model root, all markers in that root will be taken.
|
|
255
250
|
// For model element, we need to check which markers are intersecting with this element and relatively modify the markers' ranges.
|
|
256
251
|
// Collapsed markers at element boundary, although considered as not intersecting with the element, will also be returned.
|
|
257
252
|
const markers = modelElementOrFragment.is( 'documentFragment' ) ?
|
|
258
|
-
|
|
253
|
+
modelElementOrFragment.markers :
|
|
259
254
|
_getMarkersRelativeToElement( modelElementOrFragment );
|
|
260
255
|
|
|
261
|
-
|
|
262
|
-
this.downcastDispatcher.convertMarkerAdd( name, range, viewWriter );
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// Clean `conversionApi`.
|
|
266
|
-
delete this.downcastDispatcher.conversionApi.options;
|
|
256
|
+
this.downcastDispatcher.convert( modelRange, markers, viewWriter, options );
|
|
267
257
|
|
|
268
258
|
return viewDocumentFragment;
|
|
269
259
|
}
|
|
270
260
|
|
|
271
261
|
/**
|
|
272
|
-
* Sets initial input data parsed by the {@link #processor data processor} and
|
|
262
|
+
* Sets the initial input data parsed by the {@link #processor data processor} and
|
|
273
263
|
* converted by the {@link #upcastDispatcher view-to-model converters}.
|
|
274
|
-
* Initial data can be set
|
|
264
|
+
* Initial data can be only set to a document whose {@link module:engine/model/document~Document#version} is equal 0.
|
|
275
265
|
*
|
|
276
266
|
* **Note** This method is {@link module:utils/observablemixin~ObservableMixin#decorate decorated} which is
|
|
277
267
|
* used by e.g. collaborative editing plugin that syncs remote data on init.
|
|
278
268
|
*
|
|
279
|
-
* When data is passed as a string it is initialized on
|
|
269
|
+
* When data is passed as a string, it is initialized on the default `main` root:
|
|
280
270
|
*
|
|
281
|
-
* dataController.init( '<p>Foo</p>' ); // Initializes data on the `main` root.
|
|
271
|
+
* dataController.init( '<p>Foo</p>' ); // Initializes data on the `main` root only, as no other is specified.
|
|
282
272
|
*
|
|
283
|
-
* To initialize data on a different root or multiple roots at once, object containing `rootName` - `data` pairs should be passed:
|
|
273
|
+
* To initialize data on a different root or multiple roots at once, an object containing `rootName` - `data` pairs should be passed:
|
|
284
274
|
*
|
|
285
|
-
* dataController.init( { main: '<p>Foo</p>', title: '<h1>Bar</h1>' } ); // Initializes data on the `main` and `title` roots.
|
|
275
|
+
* dataController.init( { main: '<p>Foo</p>', title: '<h1>Bar</h1>' } ); // Initializes data on both the `main` and `title` roots.
|
|
286
276
|
*
|
|
287
277
|
* @fires init
|
|
288
|
-
* @param {String|Object.<String,String>} data Input data as a string or an object containing `rootName` - `data`
|
|
278
|
+
* @param {String|Object.<String,String>} data Input data as a string or an object containing the `rootName` - `data`
|
|
289
279
|
* pairs to initialize data on multiple roots at once.
|
|
290
280
|
* @returns {Promise} Promise that is resolved after the data is set on the editor.
|
|
291
281
|
*/
|
|
292
282
|
init( data ) {
|
|
293
283
|
if ( this.model.document.version ) {
|
|
294
284
|
/**
|
|
295
|
-
* Cannot set initial data to
|
|
296
|
-
* Initial data should be set once, during {@link module:core/editor/editor~Editor} initialization,
|
|
285
|
+
* Cannot set initial data to a non-empty {@link module:engine/model/document~Document}.
|
|
286
|
+
* Initial data should be set once, during the {@link module:core/editor/editor~Editor} initialization,
|
|
297
287
|
* when the {@link module:engine/model/document~Document#version} is equal 0.
|
|
298
288
|
*
|
|
299
289
|
* @error datacontroller-init-document-not-empty
|
|
@@ -310,7 +300,7 @@ export default class DataController {
|
|
|
310
300
|
|
|
311
301
|
if ( !this._checkIfRootsExists( Object.keys( initialData ) ) ) {
|
|
312
302
|
/**
|
|
313
|
-
* Cannot init data on a non-
|
|
303
|
+
* Cannot init data on a non-existent root. This error is thrown when {@link #init DataController#init() method}
|
|
314
304
|
* is called with non-existent root name. For example, if there is an editor instance with only `main` root,
|
|
315
305
|
* calling {@link #init} like:
|
|
316
306
|
*
|
|
@@ -323,7 +313,7 @@ export default class DataController {
|
|
|
323
313
|
throw new CKEditorError( 'datacontroller-init-non-existent-root', this );
|
|
324
314
|
}
|
|
325
315
|
|
|
326
|
-
this.model.enqueueChange(
|
|
316
|
+
this.model.enqueueChange( { isUndoable: false }, writer => {
|
|
327
317
|
for ( const rootName of Object.keys( initialData ) ) {
|
|
328
318
|
const modelRoot = this.model.document.getRoot( rootName );
|
|
329
319
|
writer.insert( this.parse( initialData[ rootName ], modelRoot ), modelRoot, 0 );
|
|
@@ -334,47 +324,48 @@ export default class DataController {
|
|
|
334
324
|
}
|
|
335
325
|
|
|
336
326
|
/**
|
|
337
|
-
* Sets input data parsed by the {@link #processor data processor} and
|
|
327
|
+
* Sets the input data parsed by the {@link #processor data processor} and
|
|
338
328
|
* converted by the {@link #upcastDispatcher view-to-model converters}.
|
|
339
|
-
* This method can be used any time to replace existing editor data
|
|
329
|
+
* This method can be used any time to replace existing editor data with the new one without clearing the
|
|
340
330
|
* {@link module:engine/model/document~Document#history document history}.
|
|
341
331
|
*
|
|
342
332
|
* This method also creates a batch with all the changes applied. If all you need is to parse data, use
|
|
343
333
|
* the {@link #parse} method.
|
|
344
334
|
*
|
|
345
|
-
* When data is passed as a string it is set on
|
|
335
|
+
* When data is passed as a string it is set on the default `main` root:
|
|
346
336
|
*
|
|
347
|
-
* dataController.set( '<p>Foo</p>' ); // Sets data on the `main` root.
|
|
337
|
+
* dataController.set( '<p>Foo</p>' ); // Sets data on the `main` root, as no other is specified.
|
|
348
338
|
*
|
|
349
|
-
* To set data on a different root or multiple roots at once, object containing `rootName` - `data` pairs should be passed:
|
|
339
|
+
* To set data on a different root or multiple roots at once, an object containing `rootName` - `data` pairs should be passed:
|
|
350
340
|
*
|
|
351
|
-
* dataController.set( { main: '<p>Foo</p>', title: '<h1>Bar</h1>' } ); // Sets data on the `main` and `title` roots.
|
|
341
|
+
* dataController.set( { main: '<p>Foo</p>', title: '<h1>Bar</h1>' } ); // Sets data on the `main` and `title` roots as specified.
|
|
352
342
|
*
|
|
353
|
-
* To set the data with preserved undo
|
|
343
|
+
* To set the data with a preserved undo stack and add the change to the undo stack, set `{ isUndoable: true }` as a `batchType` option.
|
|
354
344
|
*
|
|
355
|
-
* dataController.set( '<p>Foo</p>', { batchType:
|
|
345
|
+
* dataController.set( '<p>Foo</p>', { batchType: { isUndoable: true } } );
|
|
356
346
|
*
|
|
357
347
|
* @fires set
|
|
358
|
-
* @param {String|Object.<String,String>} data Input data as a string or an object containing `rootName` - `data`
|
|
348
|
+
* @param {String|Object.<String,String>} data Input data as a string or an object containing the `rootName` - `data`
|
|
359
349
|
* pairs to set data on multiple roots at once.
|
|
360
350
|
* @param {Object} [options={}] Options for setting data.
|
|
361
|
-
* @param {
|
|
362
|
-
*
|
|
363
|
-
*
|
|
351
|
+
* @param {Object} [options.batchType] The batch type that will be used to create a batch for the changes applied by this method.
|
|
352
|
+
* By default, the batch will be set as {@link module:engine/model/batch~Batch#isUndoable not undoable} and the undo stack will be
|
|
353
|
+
* cleared after the new data is applied (all undo steps will be removed). If the batch type `isUndoable` flag is be set to `true`,
|
|
354
|
+
* the undo stack will be preserved instead and not cleared when new data is applied.
|
|
364
355
|
*/
|
|
365
356
|
set( data, options = {} ) {
|
|
366
357
|
let newData = {};
|
|
367
358
|
|
|
368
359
|
if ( typeof data === 'string' ) {
|
|
369
|
-
newData.main = data; //
|
|
360
|
+
newData.main = data; // The default root is 'main'. To set data on a different root, an object should be passed.
|
|
370
361
|
} else {
|
|
371
362
|
newData = data;
|
|
372
363
|
}
|
|
373
364
|
|
|
374
365
|
if ( !this._checkIfRootsExists( Object.keys( newData ) ) ) {
|
|
375
366
|
/**
|
|
376
|
-
* Cannot set data on a non-
|
|
377
|
-
* is called with non-existent root name. For example, if there is an editor instance with only `main` root,
|
|
367
|
+
* Cannot set data on a non-existent root. This error is thrown when the {@link #set DataController#set() method}
|
|
368
|
+
* is called with non-existent root name. For example, if there is an editor instance with only the default `main` root,
|
|
378
369
|
* calling {@link #set} like:
|
|
379
370
|
*
|
|
380
371
|
* data.set( { main: '<p>Foo</p>', root2: '<p>Bar</p>' } );
|
|
@@ -386,9 +377,7 @@ export default class DataController {
|
|
|
386
377
|
throw new CKEditorError( 'datacontroller-set-non-existent-root', this );
|
|
387
378
|
}
|
|
388
379
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
this.model.enqueueChange( batchType, writer => {
|
|
380
|
+
this.model.enqueueChange( options.batchType || {}, writer => {
|
|
392
381
|
writer.setSelection( null );
|
|
393
382
|
writer.removeSelectionAttribute( this.model.document.selection.getAttributeKeys() );
|
|
394
383
|
|
|
@@ -429,7 +418,7 @@ export default class DataController {
|
|
|
429
418
|
* {@link module:engine/model/documentfragment~DocumentFragment#markers static markers map}.
|
|
430
419
|
*
|
|
431
420
|
* @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} viewElementOrFragment
|
|
432
|
-
*
|
|
421
|
+
* The element or document fragment whose content will be converted.
|
|
433
422
|
* @param {module:engine/model/schema~SchemaContextDefinition} [context='$root'] Base context in which the view will
|
|
434
423
|
* be converted to the model. See: {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#convert}.
|
|
435
424
|
* @returns {module:engine/model/documentfragment~DocumentFragment} Output document fragment.
|
|
@@ -441,7 +430,7 @@ export default class DataController {
|
|
|
441
430
|
}
|
|
442
431
|
|
|
443
432
|
/**
|
|
444
|
-
* Adds
|
|
433
|
+
* Adds the style processor normalization rules.
|
|
445
434
|
*
|
|
446
435
|
* You can implement your own rules as well as use one of the available processor rules:
|
|
447
436
|
*
|
|
@@ -457,18 +446,18 @@ export default class DataController {
|
|
|
457
446
|
}
|
|
458
447
|
|
|
459
448
|
/**
|
|
460
|
-
* Registers a {@link module:engine/view/matcher~MatcherPattern} on {@link #htmlProcessor htmlProcessor}
|
|
461
|
-
* and {@link #processor processor} for view elements whose content should be treated as
|
|
462
|
-
* and not processed during conversion from DOM to view elements.
|
|
449
|
+
* Registers a {@link module:engine/view/matcher~MatcherPattern} on an {@link #htmlProcessor htmlProcessor}
|
|
450
|
+
* and a {@link #processor processor} for view elements whose content should be treated as raw data
|
|
451
|
+
* and not processed during the conversion from DOM to view elements.
|
|
463
452
|
*
|
|
464
|
-
* The raw data can be later accessed by {@link module:engine/view/element~Element#getCustomProperty view element custom property}
|
|
453
|
+
* The raw data can be later accessed by the {@link module:engine/view/element~Element#getCustomProperty view element custom property}
|
|
465
454
|
* `"$rawContent"`.
|
|
466
455
|
*
|
|
467
456
|
* @param {module:engine/view/matcher~MatcherPattern} pattern Pattern matching all view elements whose content should
|
|
468
457
|
* be treated as a raw data.
|
|
469
458
|
*/
|
|
470
459
|
registerRawContentMatcher( pattern ) {
|
|
471
|
-
// No need to register the pattern if both `htmlProcessor` and `processor` are the same instances.
|
|
460
|
+
// No need to register the pattern if both the `htmlProcessor` and `processor` are the same instances.
|
|
472
461
|
if ( this.processor && this.processor !== this.htmlProcessor ) {
|
|
473
462
|
this.processor.registerRawContentMatcher( pattern );
|
|
474
463
|
}
|
|
@@ -484,7 +473,7 @@ export default class DataController {
|
|
|
484
473
|
}
|
|
485
474
|
|
|
486
475
|
/**
|
|
487
|
-
* Checks
|
|
476
|
+
* Checks whether all provided root names are actually existing editor roots.
|
|
488
477
|
*
|
|
489
478
|
* @private
|
|
490
479
|
* @param {Array.<String>} rootNames Root names to check.
|
|
@@ -507,7 +496,7 @@ export default class DataController {
|
|
|
507
496
|
*/
|
|
508
497
|
|
|
509
498
|
/**
|
|
510
|
-
*
|
|
499
|
+
* An event fired after the {@link #init `init()` method} was run. It can be {@link #listenTo listened to} in order to adjust or modify
|
|
511
500
|
* the initialization flow. However, if the `init` event is stopped or prevented, the {@link #event:ready `ready` event}
|
|
512
501
|
* should be fired manually.
|
|
513
502
|
*
|
|
@@ -518,9 +507,9 @@ export default class DataController {
|
|
|
518
507
|
*/
|
|
519
508
|
|
|
520
509
|
/**
|
|
521
|
-
*
|
|
510
|
+
* An event fired after {@link #set set() method} has been run.
|
|
522
511
|
*
|
|
523
|
-
* The `set` event is fired by decorated {@link #set} method.
|
|
512
|
+
* The `set` event is fired by the decorated {@link #set} method.
|
|
524
513
|
* See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.
|
|
525
514
|
*
|
|
526
515
|
* @event set
|
|
@@ -529,7 +518,7 @@ export default class DataController {
|
|
|
529
518
|
/**
|
|
530
519
|
* Event fired after the {@link #get get() method} has been run.
|
|
531
520
|
*
|
|
532
|
-
* The `get` event is fired by decorated {@link #get} method.
|
|
521
|
+
* The `get` event is fired by the decorated {@link #get} method.
|
|
533
522
|
* See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.
|
|
534
523
|
*
|
|
535
524
|
* @event get
|
|
@@ -548,7 +537,7 @@ function _getMarkersRelativeToElement( element ) {
|
|
|
548
537
|
const doc = element.root.document;
|
|
549
538
|
|
|
550
539
|
if ( !doc ) {
|
|
551
|
-
return
|
|
540
|
+
return new Map();
|
|
552
541
|
}
|
|
553
542
|
|
|
554
543
|
const elementRange = ModelRange._createIn( element );
|
|
@@ -582,7 +571,7 @@ function _getMarkersRelativeToElement( element ) {
|
|
|
582
571
|
// reverse DOM order, and intersecting ranges are in something approximating
|
|
583
572
|
// reverse DOM order (since reverse DOM order doesn't have a precise meaning
|
|
584
573
|
// when working with intersecting ranges).
|
|
585
|
-
|
|
574
|
+
result.sort( ( [ n1, r1 ], [ n2, r2 ] ) => {
|
|
586
575
|
if ( r1.end.compareWith( r2.start ) !== 'after' ) {
|
|
587
576
|
// m1.end <= m2.start -- m1 is entirely <= m2
|
|
588
577
|
return 1;
|
|
@@ -609,4 +598,6 @@ function _getMarkersRelativeToElement( element ) {
|
|
|
609
598
|
}
|
|
610
599
|
}
|
|
611
600
|
} );
|
|
601
|
+
|
|
602
|
+
return new Map( result );
|
|
612
603
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Copyright (c) 2003-
|
|
2
|
+
* @license Copyright (c) 2003-2022, 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
5
|
|
|
@@ -11,16 +11,24 @@ import RootEditableElement from '../view/rooteditableelement';
|
|
|
11
11
|
import View from '../view/view';
|
|
12
12
|
import Mapper from '../conversion/mapper';
|
|
13
13
|
import DowncastDispatcher from '../conversion/downcastdispatcher';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
clearAttributes,
|
|
16
|
+
convertCollapsedSelection,
|
|
17
|
+
convertRangeSelection,
|
|
18
|
+
insertAttributesAndChildren,
|
|
19
|
+
insertText,
|
|
20
|
+
remove
|
|
21
|
+
} from '../conversion/downcasthelpers';
|
|
15
22
|
|
|
16
23
|
import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
|
|
17
24
|
import mix from '@ckeditor/ckeditor5-utils/src/mix';
|
|
25
|
+
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
|
|
18
26
|
import { convertSelectionChange } from '../conversion/upcasthelpers';
|
|
19
27
|
|
|
20
28
|
// @if CK_DEBUG_ENGINE // const { dumpTrees, initDocumentDumping } = require( '../dev-utils/utils' );
|
|
21
29
|
|
|
22
30
|
/**
|
|
23
|
-
*
|
|
31
|
+
* A controller for the editing pipeline. The editing pipeline controls the {@link ~EditingController#model model} rendering,
|
|
24
32
|
* including selection handling. It also creates the {@link ~EditingController#view view} which builds a
|
|
25
33
|
* browser-independent virtualization over the DOM elements. The editing controller also attaches default converters.
|
|
26
34
|
*
|
|
@@ -51,7 +59,7 @@ export default class EditingController {
|
|
|
51
59
|
this.view = new View( stylesProcessor );
|
|
52
60
|
|
|
53
61
|
/**
|
|
54
|
-
*
|
|
62
|
+
* A mapper that describes the model-view binding.
|
|
55
63
|
*
|
|
56
64
|
* @readonly
|
|
57
65
|
* @member {module:engine/conversion/mapper~Mapper}
|
|
@@ -59,7 +67,7 @@ export default class EditingController {
|
|
|
59
67
|
this.mapper = new Mapper();
|
|
60
68
|
|
|
61
69
|
/**
|
|
62
|
-
* Downcast dispatcher that converts changes from the model to {@link #view
|
|
70
|
+
* Downcast dispatcher that converts changes from the model to the {@link #view editing view}.
|
|
63
71
|
*
|
|
64
72
|
* @readonly
|
|
65
73
|
* @member {module:engine/conversion/downcastdispatcher~DowncastDispatcher} #downcastDispatcher
|
|
@@ -74,7 +82,7 @@ export default class EditingController {
|
|
|
74
82
|
const markers = this.model.markers;
|
|
75
83
|
|
|
76
84
|
// When plugins listen on model changes (on selection change, post fixers, etc.) and change the view as a result of
|
|
77
|
-
// model's change, they might trigger view rendering before the conversion is completed (e.g. before the selection
|
|
85
|
+
// the model's change, they might trigger view rendering before the conversion is completed (e.g. before the selection
|
|
78
86
|
// is converted). We disable rendering for the length of the outermost model change() block to prevent that.
|
|
79
87
|
//
|
|
80
88
|
// See https://github.com/ckeditor/ckeditor5-engine/issues/1528
|
|
@@ -101,6 +109,7 @@ export default class EditingController {
|
|
|
101
109
|
|
|
102
110
|
// Attach default model converters.
|
|
103
111
|
this.downcastDispatcher.on( 'insert:$text', insertText(), { priority: 'lowest' } );
|
|
112
|
+
this.downcastDispatcher.on( 'insert', insertAttributesAndChildren(), { priority: 'lowest' } );
|
|
104
113
|
this.downcastDispatcher.on( 'remove', remove(), { priority: 'low' } );
|
|
105
114
|
|
|
106
115
|
// Attach default model selection converters.
|
|
@@ -144,6 +153,74 @@ export default class EditingController {
|
|
|
144
153
|
this.view.destroy();
|
|
145
154
|
this.stopListening();
|
|
146
155
|
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Calling this method will refresh the marker by triggering the downcast conversion for it.
|
|
159
|
+
*
|
|
160
|
+
* Reconverting the marker is useful when you want to change its {@link module:engine/view/element~Element view element}
|
|
161
|
+
* without changing any marker data. For instance:
|
|
162
|
+
*
|
|
163
|
+
* let isCommentActive = false;
|
|
164
|
+
*
|
|
165
|
+
* model.conversion.markerToHighlight( {
|
|
166
|
+
* model: 'comment',
|
|
167
|
+
* view: data => {
|
|
168
|
+
* const classes = [ 'comment-marker' ];
|
|
169
|
+
*
|
|
170
|
+
* if ( isCommentActive ) {
|
|
171
|
+
* classes.push( 'comment-marker--active' );
|
|
172
|
+
* }
|
|
173
|
+
*
|
|
174
|
+
* return { classes };
|
|
175
|
+
* }
|
|
176
|
+
* } );
|
|
177
|
+
*
|
|
178
|
+
* // ...
|
|
179
|
+
*
|
|
180
|
+
* // Change the property that indicates if marker is displayed as active or not.
|
|
181
|
+
* isCommentActive = true;
|
|
182
|
+
*
|
|
183
|
+
* // Reconverting will downcast and synchronize the marker with the new isCommentActive state value.
|
|
184
|
+
* editor.editing.reconvertMarker( 'comment' );
|
|
185
|
+
*
|
|
186
|
+
* **Note**: If you want to reconvert a model item, use {@link #reconvertItem} instead.
|
|
187
|
+
*
|
|
188
|
+
* @param {String|module:engine/model/markercollection~Marker} markerOrName Name of a marker to update, or a marker instance.
|
|
189
|
+
*/
|
|
190
|
+
reconvertMarker( markerOrName ) {
|
|
191
|
+
const markerName = typeof markerOrName == 'string' ? markerOrName : markerOrName.name;
|
|
192
|
+
const currentMarker = this.model.markers.get( markerName );
|
|
193
|
+
|
|
194
|
+
if ( !currentMarker ) {
|
|
195
|
+
/**
|
|
196
|
+
* The marker with the provided name does not exist and cannot be reconverted.
|
|
197
|
+
*
|
|
198
|
+
* @error editingcontroller-reconvertmarker-marker-not-exist
|
|
199
|
+
* @param {String} markerName The name of the reconverted marker.
|
|
200
|
+
*/
|
|
201
|
+
throw new CKEditorError( 'editingcontroller-reconvertmarker-marker-not-exist', this, { markerName } );
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
this.model.change( () => {
|
|
205
|
+
this.model.markers._refresh( currentMarker );
|
|
206
|
+
} );
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Calling this method will downcast a model item on demand (by requesting a refresh in the {@link module:engine/model/differ~Differ}).
|
|
211
|
+
*
|
|
212
|
+
* You can use it if you want the view representation of a specific item updated as a response to external modifications. For instance,
|
|
213
|
+
* when the view structure depends not only on the associated model data but also on some external state.
|
|
214
|
+
*
|
|
215
|
+
* **Note**: If you want to reconvert a model marker, use {@link #reconvertMarker} instead.
|
|
216
|
+
*
|
|
217
|
+
* @param {module:engine/model/item~Item} item Item to refresh.
|
|
218
|
+
*/
|
|
219
|
+
reconvertItem( item ) {
|
|
220
|
+
this.model.change( () => {
|
|
221
|
+
this.model.document.differ._refreshItem( item );
|
|
222
|
+
} );
|
|
223
|
+
}
|
|
147
224
|
}
|
|
148
225
|
|
|
149
226
|
mix( EditingController, ObservableMixin );
|