@ckeditor/ckeditor5-engine 45.0.0-alpha.9 → 45.1.0-alpha.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/dist/index.js +187 -84
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/controller/editingcontroller.js +1 -1
- package/src/conversion/conversion.d.ts +3 -0
- package/src/conversion/conversion.js +3 -0
- package/src/conversion/downcasthelpers.d.ts +2 -7
- package/src/conversion/downcasthelpers.js +8 -11
- package/src/dev-utils/utils.js +1 -0
- package/src/dev-utils/view.d.ts +1 -3
- package/src/dev-utils/view.js +1 -3
- package/src/model/documentselection.js +2 -2
- package/src/model/history.js +2 -1
- package/src/model/nodelist.js +2 -2
- package/src/model/operation/attributeoperation.js +5 -5
- package/src/model/operation/operation.d.ts +1 -1
- package/src/model/operation/operation.js +1 -1
- package/src/model/operation/rootattributeoperation.js +8 -10
- package/src/model/operation/transform.js +67 -10
- package/src/model/operation/utils.d.ts +1 -1
- package/src/model/operation/utils.js +1 -1
- package/src/model/position.js +7 -7
- package/src/model/range.d.ts +1 -1
- package/src/model/range.js +1 -1
- package/src/model/selection.js +2 -2
- package/src/model/utils/deletecontent.d.ts +13 -0
- package/src/model/utils/deletecontent.js +20 -1
- package/src/model/utils/insertcontent.d.ts +0 -1
- package/src/model/utils/insertcontent.js +2 -3
- package/src/model/utils/insertobject.d.ts +0 -1
- package/src/model/utils/insertobject.js +0 -1
- package/src/model/writer.d.ts +1 -1
- package/src/model/writer.js +2 -2
- package/src/view/domconverter.d.ts +5 -5
- package/src/view/domconverter.js +5 -5
- package/src/view/downcastwriter.d.ts +3 -2
- package/src/view/downcastwriter.js +3 -2
- package/src/view/editableelement.d.ts +1 -1
- package/src/view/editableelement.js +1 -1
- package/src/view/emptyelement.d.ts +1 -1
- package/src/view/emptyelement.js +1 -1
- package/src/view/filler.d.ts +1 -1
- package/src/view/filler.js +1 -1
- package/src/view/observer/compositionobserver.js +2 -2
- package/src/view/observer/inputobserver.js +29 -3
- package/src/view/position.js +3 -3
- package/src/view/renderer.js +8 -0
- package/src/view/textproxy.d.ts +1 -2
- package/src/view/textproxy.js +1 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckeditor/ckeditor5-engine",
|
|
3
|
-
"version": "45.
|
|
3
|
+
"version": "45.1.0-alpha.0",
|
|
4
4
|
"description": "The editing engine of CKEditor 5 – the best browser-based rich text editor.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wysiwyg",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"type": "module",
|
|
25
25
|
"main": "src/index.js",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@ckeditor/ckeditor5-utils": "45.
|
|
27
|
+
"@ckeditor/ckeditor5-utils": "45.1.0-alpha.0",
|
|
28
28
|
"es-toolkit": "1.32.0"
|
|
29
29
|
},
|
|
30
30
|
"author": "CKSource (http://cksource.com/)",
|
|
@@ -158,7 +158,7 @@ export default class EditingController extends /* #__PURE__ */ ObservableMixin()
|
|
|
158
158
|
* The marker with the provided name does not exist and cannot be reconverted.
|
|
159
159
|
*
|
|
160
160
|
* @error editingcontroller-reconvertmarker-marker-not-exist
|
|
161
|
-
* @param {
|
|
161
|
+
* @param {string} markerName The name of the reconverted marker.
|
|
162
162
|
*/
|
|
163
163
|
throw new CKEditorError('editingcontroller-reconvertmarker-marker-not-exist', this, { markerName });
|
|
164
164
|
}
|
|
@@ -470,7 +470,10 @@ export default class Conversion {
|
|
|
470
470
|
/**
|
|
471
471
|
* Creates and caches conversion helpers for given dispatchers group.
|
|
472
472
|
*
|
|
473
|
+
* @param options Group name.
|
|
473
474
|
* @param options.name Group name.
|
|
475
|
+
* @param options.dispatchers Dispatchers to register.
|
|
476
|
+
* @param options.isDowncast Whether downcast group.
|
|
474
477
|
*/
|
|
475
478
|
private _createConversionHelpers;
|
|
476
479
|
}
|
|
@@ -559,7 +559,10 @@ export default class Conversion {
|
|
|
559
559
|
/**
|
|
560
560
|
* Creates and caches conversion helpers for given dispatchers group.
|
|
561
561
|
*
|
|
562
|
+
* @param options Group name.
|
|
562
563
|
* @param options.name Group name.
|
|
564
|
+
* @param options.dispatchers Dispatchers to register.
|
|
565
|
+
* @param options.isDowncast Whether downcast group.
|
|
563
566
|
*/
|
|
564
567
|
_createConversionHelpers({ name, dispatchers, isDowncast }) {
|
|
565
568
|
if (this._helpers.has(name)) {
|
|
@@ -169,13 +169,10 @@ export default class DowncastHelpers extends ConversionHelpers<DowncastDispatche
|
|
|
169
169
|
*
|
|
170
170
|
* @param config Conversion configuration.
|
|
171
171
|
* @param config.model The description or a name of the model element to convert.
|
|
172
|
-
* @param config.model.attributes The list of attribute names that should be consumed while creating
|
|
173
|
-
* the view element. Note that the view will be reconverted if any of the listed attributes changes.
|
|
174
|
-
* @param config.model.children Specifies whether the view element requires reconversion if the list
|
|
175
|
-
* of the model child nodes changed.
|
|
176
172
|
* @param config.view A view element definition or a function that takes the model element and
|
|
177
173
|
* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}
|
|
178
174
|
* as parameters and returns a view container element.
|
|
175
|
+
* @param config.converterPriority Converter priority.
|
|
179
176
|
*/
|
|
180
177
|
elementToElement(config: {
|
|
181
178
|
model: string | {
|
|
@@ -290,12 +287,10 @@ export default class DowncastHelpers extends ConversionHelpers<DowncastDispatche
|
|
|
290
287
|
*
|
|
291
288
|
* @param config Conversion configuration.
|
|
292
289
|
* @param config.model The description or a name of the model element to convert.
|
|
293
|
-
* @param config.model.name The name of the model element to convert.
|
|
294
|
-
* @param config.model.attributes The list of attribute names that should be consumed while creating
|
|
295
|
-
* the view structure. Note that the view will be reconverted if any of the listed attributes will change.
|
|
296
290
|
* @param config.view A function that takes the model element and
|
|
297
291
|
* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as parameters
|
|
298
292
|
* and returns a view container element with slots for model child nodes to be converted into.
|
|
293
|
+
* @param config.converterPriority Converter priority.
|
|
299
294
|
*/
|
|
300
295
|
elementToStructure(config: {
|
|
301
296
|
model: string | {
|
|
@@ -161,13 +161,10 @@ export default class DowncastHelpers extends ConversionHelpers {
|
|
|
161
161
|
*
|
|
162
162
|
* @param config Conversion configuration.
|
|
163
163
|
* @param config.model The description or a name of the model element to convert.
|
|
164
|
-
* @param config.model.attributes The list of attribute names that should be consumed while creating
|
|
165
|
-
* the view element. Note that the view will be reconverted if any of the listed attributes changes.
|
|
166
|
-
* @param config.model.children Specifies whether the view element requires reconversion if the list
|
|
167
|
-
* of the model child nodes changed.
|
|
168
164
|
* @param config.view A view element definition or a function that takes the model element and
|
|
169
165
|
* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}
|
|
170
166
|
* as parameters and returns a view container element.
|
|
167
|
+
* @param config.converterPriority Converter priority.
|
|
171
168
|
*/
|
|
172
169
|
elementToElement(config) {
|
|
173
170
|
return this.add(downcastElementToElement(config));
|
|
@@ -276,12 +273,10 @@ export default class DowncastHelpers extends ConversionHelpers {
|
|
|
276
273
|
*
|
|
277
274
|
* @param config Conversion configuration.
|
|
278
275
|
* @param config.model The description or a name of the model element to convert.
|
|
279
|
-
* @param config.model.name The name of the model element to convert.
|
|
280
|
-
* @param config.model.attributes The list of attribute names that should be consumed while creating
|
|
281
|
-
* the view structure. Note that the view will be reconverted if any of the listed attributes will change.
|
|
282
276
|
* @param config.view A function that takes the model element and
|
|
283
277
|
* {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as parameters
|
|
284
278
|
* and returns a view container element with slots for model child nodes to be converted into.
|
|
279
|
+
* @param config.converterPriority Converter priority.
|
|
285
280
|
*/
|
|
286
281
|
elementToStructure(config) {
|
|
287
282
|
return this.add(downcastElementToStructure(config));
|
|
@@ -1348,6 +1343,7 @@ function changeAttribute(attributeCreator) {
|
|
|
1348
1343
|
* ```
|
|
1349
1344
|
*
|
|
1350
1345
|
* @error conversion-attribute-to-attribute-on-text
|
|
1346
|
+
* @param {object} data The conversion data.
|
|
1351
1347
|
*/
|
|
1352
1348
|
throw new CKEditorError('conversion-attribute-to-attribute-on-text', conversionApi.dispatcher, data);
|
|
1353
1349
|
}
|
|
@@ -1610,7 +1606,7 @@ function downcastElementToStructure(config) {
|
|
|
1610
1606
|
* ```
|
|
1611
1607
|
*
|
|
1612
1608
|
* @error conversion-element-to-structure-disallowed-text
|
|
1613
|
-
* @param {
|
|
1609
|
+
* @param {string} elementName The name of the element the structure is to be created for.
|
|
1614
1610
|
*/
|
|
1615
1611
|
throw new CKEditorError('conversion-element-to-structure-disallowed-text', dispatcher, { elementName: model.name });
|
|
1616
1612
|
}
|
|
@@ -1999,9 +1995,9 @@ function createConsumer(model) {
|
|
|
1999
1995
|
};
|
|
2000
1996
|
}
|
|
2001
1997
|
/**
|
|
2002
|
-
* Creates a function that
|
|
1998
|
+
* Creates a function that creates view slots.
|
|
2003
1999
|
*
|
|
2004
|
-
* @returns Function exposed by writer as createSlot()
|
|
2000
|
+
* @returns Function exposed by the writer as `createSlot()`.
|
|
2005
2001
|
*/
|
|
2006
2002
|
function createSlotFactory(element, slotsMap, conversionApi) {
|
|
2007
2003
|
return (writer, modeOrFilter) => {
|
|
@@ -2015,9 +2011,10 @@ function createSlotFactory(element, slotsMap, conversionApi) {
|
|
|
2015
2011
|
}
|
|
2016
2012
|
else {
|
|
2017
2013
|
/**
|
|
2018
|
-
* Unknown slot mode was provided to `writer.createSlot()` in downcast converter.
|
|
2014
|
+
* Unknown slot mode was provided to `writer.createSlot()` in the downcast converter.
|
|
2019
2015
|
*
|
|
2020
2016
|
* @error conversion-slot-mode-unknown
|
|
2017
|
+
* @param {never} modeOrFilter The specified mode or filter.
|
|
2021
2018
|
*/
|
|
2022
2019
|
throw new CKEditorError('conversion-slot-mode-unknown', conversionApi.dispatcher, { modeOrFilter });
|
|
2023
2020
|
}
|
package/src/dev-utils/utils.js
CHANGED
|
@@ -107,6 +107,7 @@ export function logDocument(document, version) {
|
|
|
107
107
|
// @if CK_DEBUG_TYPING // editor.editing.view.domConverter,
|
|
108
108
|
// @if CK_DEBUG_TYPING // ...editor.editing.view._observers.values(),
|
|
109
109
|
// @if CK_DEBUG_TYPING // editor.plugins.get( 'Input' ),
|
|
110
|
+
// @if CK_DEBUG_TYPING // editor.plugins.get( 'Input' )._typingQueue,
|
|
110
111
|
// @if CK_DEBUG_TYPING // editor.plugins.get( 'WidgetTypeAround' ),
|
|
111
112
|
// @if CK_DEBUG_TYPING // editor.commands.get( 'delete' ),
|
|
112
113
|
// @if CK_DEBUG_TYPING // editor.commands.get( 'deleteForward' )
|
package/src/dev-utils/view.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ import type DomConverter from '../view/domconverter.js';
|
|
|
19
19
|
/**
|
|
20
20
|
* Writes the content of the {@link module:engine/view/document~Document document} to an HTML-like string.
|
|
21
21
|
*
|
|
22
|
+
* @param view The view to stringify.
|
|
22
23
|
* @param options.withoutSelection Whether to write the selection. When set to `true`, the selection will
|
|
23
24
|
* not be included in the returned string.
|
|
24
25
|
* @param options.rootName The name of the root from which the data should be stringified. If not provided,
|
|
@@ -27,8 +28,6 @@ import type DomConverter from '../view/domconverter.js';
|
|
|
27
28
|
* instead of `<p>`, `<attribute:b>` instead of `<b>` and `<empty:img>` instead of `<img>`).
|
|
28
29
|
* @param options.showPriority When set to `true`, the attribute element's priority will be printed
|
|
29
30
|
* (`<span view-priority="12">`, `<b view-priority="10">`).
|
|
30
|
-
* @param options.showAttributeElementId When set to `true`, the attribute element's ID will be printed
|
|
31
|
-
* (`<span id="marker:foo">`).
|
|
32
31
|
* @param options.renderUIElements When set to `true`, the inner content of each
|
|
33
32
|
* {@link module:engine/view/uielement~UIElement} will be printed.
|
|
34
33
|
* @param options.renderRawElements When set to `true`, the inner content of each
|
|
@@ -304,7 +303,6 @@ export declare function stringify(node: ViewNode | ViewDocumentFragment, selecti
|
|
|
304
303
|
* this node will be used as the root for all parsed nodes.
|
|
305
304
|
* @param options.sameSelectionCharacters When set to `false`, the selection inside the text should be marked using
|
|
306
305
|
* `{` and `}` and the selection outside the ext using `[` and `]`. When set to `true`, both should be marked with `[` and `]` only.
|
|
307
|
-
* @param options.stylesProcessor Styles processor.
|
|
308
306
|
* @returns Returns the parsed view node or an object with two fields: `view` and `selection` when selection ranges were included in the
|
|
309
307
|
* data to parse.
|
|
310
308
|
*/
|
package/src/dev-utils/view.js
CHANGED
|
@@ -44,6 +44,7 @@ const domConverterStub = {
|
|
|
44
44
|
/**
|
|
45
45
|
* Writes the content of the {@link module:engine/view/document~Document document} to an HTML-like string.
|
|
46
46
|
*
|
|
47
|
+
* @param view The view to stringify.
|
|
47
48
|
* @param options.withoutSelection Whether to write the selection. When set to `true`, the selection will
|
|
48
49
|
* not be included in the returned string.
|
|
49
50
|
* @param options.rootName The name of the root from which the data should be stringified. If not provided,
|
|
@@ -52,8 +53,6 @@ const domConverterStub = {
|
|
|
52
53
|
* instead of `<p>`, `<attribute:b>` instead of `<b>` and `<empty:img>` instead of `<img>`).
|
|
53
54
|
* @param options.showPriority When set to `true`, the attribute element's priority will be printed
|
|
54
55
|
* (`<span view-priority="12">`, `<b view-priority="10">`).
|
|
55
|
-
* @param options.showAttributeElementId When set to `true`, the attribute element's ID will be printed
|
|
56
|
-
* (`<span id="marker:foo">`).
|
|
57
56
|
* @param options.renderUIElements When set to `true`, the inner content of each
|
|
58
57
|
* {@link module:engine/view/uielement~UIElement} will be printed.
|
|
59
58
|
* @param options.renderRawElements When set to `true`, the inner content of each
|
|
@@ -351,7 +350,6 @@ export function stringify(node, selectionOrPositionOrRange = null, options = {})
|
|
|
351
350
|
* this node will be used as the root for all parsed nodes.
|
|
352
351
|
* @param options.sameSelectionCharacters When set to `false`, the selection inside the text should be marked using
|
|
353
352
|
* `{` and `}` and the selection outside the ext using `[` and `]`. When set to `true`, both should be marked with `[` and `]` only.
|
|
354
|
-
* @param options.stylesProcessor Styles processor.
|
|
355
353
|
* @returns Returns the parsed view node or an object with two fields: `view` and `selection` when selection ranges were included in the
|
|
356
354
|
* data to parse.
|
|
357
355
|
*/
|
|
@@ -612,7 +612,7 @@ class LiveSelection extends Selection {
|
|
|
612
612
|
* UID obtained from the {@link module:engine/model/writer~Writer#overrideSelectionGravity} to restore.
|
|
613
613
|
*
|
|
614
614
|
* @error document-selection-gravity-wrong-restore
|
|
615
|
-
* @param uid The unique identifier returned by
|
|
615
|
+
* @param {string} uid The unique identifier returned by
|
|
616
616
|
* {@link module:engine/model/documentselection~DocumentSelection#_overrideGravity}.
|
|
617
617
|
*/
|
|
618
618
|
throw new CKEditorError('document-selection-gravity-wrong-restore', this, { uid });
|
|
@@ -649,7 +649,7 @@ class LiveSelection extends Selection {
|
|
|
649
649
|
* starts or ends at incorrect position.
|
|
650
650
|
*
|
|
651
651
|
* @error document-selection-wrong-position
|
|
652
|
-
* @param range
|
|
652
|
+
* @param {module:engine/model/range~Range} range The invalid range.
|
|
653
653
|
*/
|
|
654
654
|
throw new CKEditorError('document-selection-wrong-position', this, { range });
|
|
655
655
|
}
|
package/src/model/history.js
CHANGED
|
@@ -77,7 +77,8 @@ export default class History {
|
|
|
77
77
|
* Only operations with matching versions can be added to the history.
|
|
78
78
|
*
|
|
79
79
|
* @error model-document-history-addoperation-incorrect-version
|
|
80
|
-
* @param
|
|
80
|
+
* @param {module:engine/model/operation/operation~Operation} operation The current operation.
|
|
81
|
+
* @param {number} historyVersion The current document history version.
|
|
81
82
|
*/
|
|
82
83
|
throw new CKEditorError('model-document-history-addoperation-incorrect-version', this, {
|
|
83
84
|
operation,
|
package/src/model/nodelist.js
CHANGED
|
@@ -121,8 +121,8 @@ export default class NodeList {
|
|
|
121
121
|
* Given offset cannot be found in the node list.
|
|
122
122
|
*
|
|
123
123
|
* @error model-nodelist-offset-out-of-bounds
|
|
124
|
-
* @param offset
|
|
125
|
-
* @param nodeList Stringified node list.
|
|
124
|
+
* @param {number} offset The offset value.
|
|
125
|
+
* @param {module:engine/model/nodelist~NodeList} nodeList Stringified node list.
|
|
126
126
|
*/
|
|
127
127
|
throw new CKEditorError('model-nodelist-offset-out-of-bounds', this, {
|
|
128
128
|
offset,
|
|
@@ -125,9 +125,9 @@ export default class AttributeOperation extends Operation {
|
|
|
125
125
|
* Changed node has different attribute value than operation's old attribute value.
|
|
126
126
|
*
|
|
127
127
|
* @error attribute-operation-wrong-old-value
|
|
128
|
-
* @param item
|
|
129
|
-
* @param key
|
|
130
|
-
* @param value
|
|
128
|
+
* @param {module:engine/model/item~Item} root The item element.
|
|
129
|
+
* @param {string} key The key of the attribute.
|
|
130
|
+
* @param {never} value The value.
|
|
131
131
|
*/
|
|
132
132
|
throw new CKEditorError('attribute-operation-wrong-old-value', this, { item, key: this.key, value: this.oldValue });
|
|
133
133
|
}
|
|
@@ -136,8 +136,8 @@ export default class AttributeOperation extends Operation {
|
|
|
136
136
|
* The attribute with given key already exists for the given node.
|
|
137
137
|
*
|
|
138
138
|
* @error attribute-operation-attribute-exists
|
|
139
|
-
* @param
|
|
140
|
-
* @param key
|
|
139
|
+
* @param {module:engine/model/item~Item} root The item element.
|
|
140
|
+
* @param {string} key The key of the attribute.
|
|
141
141
|
*/
|
|
142
142
|
throw new CKEditorError('attribute-operation-attribute-exists', this, { node: item, key: this.key });
|
|
143
143
|
}
|
|
@@ -93,7 +93,7 @@ export default abstract class Operation {
|
|
|
93
93
|
* Creates `Operation` object from deserialized object, i.e. from parsed JSON string.
|
|
94
94
|
*
|
|
95
95
|
* @param json Deserialized JSON object.
|
|
96
|
-
* @param
|
|
96
|
+
* @param document Document on which this operation will be applied.
|
|
97
97
|
*/
|
|
98
98
|
static fromJSON(json: any, document: Document): Operation;
|
|
99
99
|
}
|
|
@@ -70,7 +70,7 @@ export default class Operation {
|
|
|
70
70
|
* Creates `Operation` object from deserialized object, i.e. from parsed JSON string.
|
|
71
71
|
*
|
|
72
72
|
* @param json Deserialized JSON object.
|
|
73
|
-
* @param
|
|
73
|
+
* @param document Document on which this operation will be applied.
|
|
74
74
|
*/
|
|
75
75
|
static fromJSON(json, document) {
|
|
76
76
|
return new this(json.baseVersion);
|
|
@@ -100,9 +100,8 @@ export default class RootAttributeOperation extends Operation {
|
|
|
100
100
|
* The element to change is not a root element.
|
|
101
101
|
*
|
|
102
102
|
* @error rootattribute-operation-not-a-root
|
|
103
|
-
* @param root
|
|
104
|
-
* @param key
|
|
105
|
-
* @param value
|
|
103
|
+
* @param {module:engine/model/rootelement~RootElement} root The root element.
|
|
104
|
+
* @param {string} key The key of the attribute.
|
|
106
105
|
*/
|
|
107
106
|
throw new CKEditorError('rootattribute-operation-not-a-root', this, { root: this.root, key: this.key });
|
|
108
107
|
}
|
|
@@ -111,9 +110,8 @@ export default class RootAttributeOperation extends Operation {
|
|
|
111
110
|
* The attribute which should be removed does not exist for the given node.
|
|
112
111
|
*
|
|
113
112
|
* @error rootattribute-operation-wrong-old-value
|
|
114
|
-
* @param root
|
|
115
|
-
* @param key
|
|
116
|
-
* @param value
|
|
113
|
+
* @param {module:engine/model/rootelement~RootElement} root The root element.
|
|
114
|
+
* @param {string} key The key of the attribute.
|
|
117
115
|
*/
|
|
118
116
|
throw new CKEditorError('rootattribute-operation-wrong-old-value', this, { root: this.root, key: this.key });
|
|
119
117
|
}
|
|
@@ -122,8 +120,8 @@ export default class RootAttributeOperation extends Operation {
|
|
|
122
120
|
* The attribute with given key already exists for the given node.
|
|
123
121
|
*
|
|
124
122
|
* @error rootattribute-operation-attribute-exists
|
|
125
|
-
* @param root
|
|
126
|
-
* @param key
|
|
123
|
+
* @param {module:engine/model/rootelement~RootElement} root The root element.
|
|
124
|
+
* @param {string} key The key of the attribute.
|
|
127
125
|
*/
|
|
128
126
|
throw new CKEditorError('rootattribute-operation-attribute-exists', this, { root: this.root, key: this.key });
|
|
129
127
|
}
|
|
@@ -163,10 +161,10 @@ export default class RootAttributeOperation extends Operation {
|
|
|
163
161
|
static fromJSON(json, document) {
|
|
164
162
|
if (!document.getRoot(json.root)) {
|
|
165
163
|
/**
|
|
166
|
-
* Cannot create RootAttributeOperation for document. Root with specified name does not exist.
|
|
164
|
+
* Cannot create RootAttributeOperation for document. Root with the specified name does not exist.
|
|
167
165
|
*
|
|
168
166
|
* @error rootattribute-operation-fromjson-no-root
|
|
169
|
-
* @param rootName
|
|
167
|
+
* @param {string} rootName The root name.
|
|
170
168
|
*/
|
|
171
169
|
throw new CKEditorError('rootattribute-operation-fromjson-no-root', this, { rootName: json.root });
|
|
172
170
|
}
|
|
@@ -1037,23 +1037,80 @@ setTransformation(MarkerOperation, SplitOperation, (a, b, context) => {
|
|
|
1037
1037
|
}
|
|
1038
1038
|
if (a.newRange) {
|
|
1039
1039
|
if (context.abRelation) {
|
|
1040
|
+
// If we have context, it means that there was previously a merge operation which transformed this marker operation, and that
|
|
1041
|
+
// merge operation was then undone, and this split operation should reverse the marker to state before the merge operation.
|
|
1040
1042
|
const aNewRange = a.newRange._getTransformedBySplitOperation(b);
|
|
1041
|
-
if (a.newRange.start.isEqual(b.splitPosition)
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1043
|
+
if (a.newRange.start.isEqual(b.splitPosition)) {
|
|
1044
|
+
// If marker range start is same as split position, we need to decide where marker start should be placed, as there
|
|
1045
|
+
// are three possible options.
|
|
1046
|
+
//
|
|
1047
|
+
if (context.abRelation.wasStartBeforeMergedElement) {
|
|
1048
|
+
// If the marker start was initially before the merged element, move it back to that place.
|
|
1049
|
+
//
|
|
1050
|
+
// <p>Foo</p>[<p>Bar]</p> -- merge -> <p>Foo[Bar]</p> -- default split -> <p>Foo</p><p>[Bar]</p>
|
|
1051
|
+
// <p>Foo</p>[<p>Bar]</p> -- merge -> <p>Foo[Bar]</p> --- fixed split --> <p>Foo</p>[<p>Bar]</p>
|
|
1052
|
+
//
|
|
1053
|
+
a.newRange.start = Position._createAt(b.insertionPosition);
|
|
1054
|
+
}
|
|
1055
|
+
else if (context.abRelation.wasInLeftElement) {
|
|
1056
|
+
// If the marker start was initially in the "left" element, keep the start position there.
|
|
1057
|
+
//
|
|
1058
|
+
// <p>Foo[</p><p>Bar]</p> -- merge -> <p>Foo[Bar]</p> -- default split -> <p>Foo</p><p>[Bar]</p>
|
|
1059
|
+
// <p>Foo[</p><p>Bar]</p> -- merge -> <p>Foo[Bar]</p> --- fixed split --> <p>Foo[</p><p>Bar]</p>
|
|
1060
|
+
//
|
|
1061
|
+
a.newRange.start = Position._createAt(a.newRange.start);
|
|
1062
|
+
}
|
|
1063
|
+
else {
|
|
1064
|
+
// Finally, the start position must have been at the beginning of the "right" (merged) element.
|
|
1065
|
+
// In this case, move it back to the "right" element.
|
|
1066
|
+
//
|
|
1067
|
+
// Note, that this what the default transformation (`_getTransformedBySplitOperation()`) does, BUT ONLY for
|
|
1068
|
+
// a non-collapsed marker. For a collapsed marker, by default, the whole marker is kept at the split position,
|
|
1069
|
+
// which would be incorrect. This is why this case is needed, and why we don't use `aNewRange.start` here.
|
|
1070
|
+
//
|
|
1071
|
+
// <p>Foo</p><p>[]Bar</p> -- merge -> <p>Foo[]Bar</p> -- default split -> <p>Foo[]</p><p>Bar</p>
|
|
1072
|
+
// <p>Foo</p><p>[]Bar</p> -- merge -> <p>Foo[]Bar</p> --- fixed split --> <p>Foo</p><p>[]Bar</p>
|
|
1073
|
+
//
|
|
1074
|
+
a.newRange.start = Position._createAt(b.moveTargetPosition);
|
|
1075
|
+
}
|
|
1046
1076
|
}
|
|
1047
1077
|
else {
|
|
1078
|
+
// If marker range start is not the same as split position, simply use the default transformation, as there is no
|
|
1079
|
+
// ambiguity in this case.
|
|
1048
1080
|
a.newRange.start = aNewRange.start;
|
|
1049
1081
|
}
|
|
1050
|
-
if (a.newRange.end.isEqual(b.splitPosition)
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
a.newRange.end
|
|
1082
|
+
if (a.newRange.end.isEqual(b.splitPosition)) {
|
|
1083
|
+
// If marker range end is same as split position, we need to decide where marker end should be placed, as there
|
|
1084
|
+
// are three possible options.
|
|
1085
|
+
//
|
|
1086
|
+
if (a.newRange.end.isEqual(b.splitPosition) && context.abRelation.wasEndBeforeMergedElement) {
|
|
1087
|
+
// If the marker end was initially before the merged element, move it back to that place.
|
|
1088
|
+
//
|
|
1089
|
+
// <p>[Foo</p>]<p>Bar</p> -- merge -> <p>[Foo]Bar</p> -- default split -> <p>[Foo]</p><p>Bar</p>
|
|
1090
|
+
// <p>[Foo</p>]<p>Bar</p> -- merge -> <p>[Foo]Bar</p> --- fixed split --> <p>[Foo</p>]<p>Bar</p>
|
|
1091
|
+
//
|
|
1092
|
+
a.newRange.end = Position._createAt(b.insertionPosition);
|
|
1093
|
+
}
|
|
1094
|
+
else if (context.abRelation.wasInRightElement) {
|
|
1095
|
+
// If the marker was initially in the "right" element, keep the end position there.
|
|
1096
|
+
//
|
|
1097
|
+
// <p>[Foo</p><p>]Bar</p> -- merge -> <p>[Foo]Bar</p> -- default split -> <p>[Foo]</p><p>Bar</p>
|
|
1098
|
+
// <p>[Foo</p><p>]Bar</p> -- merge -> <p>[Foo]Bar</p> --- fixed split --> <p>[Foo</p><p>]Bar</p>
|
|
1099
|
+
//
|
|
1100
|
+
a.newRange.end = Position._createAt(b.moveTargetPosition);
|
|
1101
|
+
}
|
|
1102
|
+
else {
|
|
1103
|
+
// Finally, the end position must have been at the end of the "left" (merged) element.
|
|
1104
|
+
// In this case, keep it where it is.
|
|
1105
|
+
//
|
|
1106
|
+
// Note, that this is what the default transformation does, so we could use `aNewRange.end`, but this is more clear.
|
|
1107
|
+
//
|
|
1108
|
+
a.newRange.end = Position._createAt(a.newRange.end);
|
|
1109
|
+
}
|
|
1055
1110
|
}
|
|
1056
1111
|
else {
|
|
1112
|
+
// If marker range end is not the same as split position, simply use the default transformation, as there is no
|
|
1113
|
+
// ambiguity in this case.
|
|
1057
1114
|
a.newRange.end = aNewRange.end;
|
|
1058
1115
|
}
|
|
1059
1116
|
return [a];
|
|
@@ -16,7 +16,7 @@ import type Position from '../position.js';
|
|
|
16
16
|
*
|
|
17
17
|
* @internal
|
|
18
18
|
* @param position Position at which nodes should be inserted.
|
|
19
|
-
* @param
|
|
19
|
+
* @param nodes Nodes to insert.
|
|
20
20
|
* @returns Range spanning over inserted elements.
|
|
21
21
|
*/
|
|
22
22
|
export declare function _insert(position: Position, nodes: NodeSet): Range;
|
|
@@ -15,7 +15,7 @@ import { CKEditorError, isIterable } from '@ckeditor/ckeditor5-utils';
|
|
|
15
15
|
*
|
|
16
16
|
* @internal
|
|
17
17
|
* @param position Position at which nodes should be inserted.
|
|
18
|
-
* @param
|
|
18
|
+
* @param nodes Nodes to insert.
|
|
19
19
|
* @returns Range spanning over inserted elements.
|
|
20
20
|
*/
|
|
21
21
|
export function _insert(position, nodes) {
|
package/src/model/position.js
CHANGED
|
@@ -100,7 +100,7 @@ export default class Position extends TypeCheckable {
|
|
|
100
100
|
* Position path must be an array with at least one item.
|
|
101
101
|
*
|
|
102
102
|
* @error model-position-path-incorrect-format
|
|
103
|
-
* @param path
|
|
103
|
+
* @param {Array.<number>} path A path to the position.
|
|
104
104
|
*/
|
|
105
105
|
throw new CKEditorError('model-position-path-incorrect-format', root, { path });
|
|
106
106
|
}
|
|
@@ -155,7 +155,7 @@ export default class Position extends TypeCheckable {
|
|
|
155
155
|
* the {@glink framework/architecture/editing-engine#indexes-and-offsets Editing engine architecture} guide.
|
|
156
156
|
*
|
|
157
157
|
* @error model-position-path-incorrect
|
|
158
|
-
* @param position The incorrect position.
|
|
158
|
+
* @param {module:engine/model/position~Position} position The incorrect position.
|
|
159
159
|
*/
|
|
160
160
|
throw new CKEditorError('model-position-path-incorrect', this, { position: this });
|
|
161
161
|
}
|
|
@@ -823,10 +823,10 @@ export default class Position extends TypeCheckable {
|
|
|
823
823
|
static _createAfter(item, stickiness) {
|
|
824
824
|
if (!item.parent) {
|
|
825
825
|
/**
|
|
826
|
-
* You
|
|
826
|
+
* You cannot make a position after a root element.
|
|
827
827
|
*
|
|
828
828
|
* @error model-position-after-root
|
|
829
|
-
* @param root
|
|
829
|
+
* @param {module:engine/model/rootelement~RootElement} root The root element..
|
|
830
830
|
*/
|
|
831
831
|
throw new CKEditorError('model-position-after-root', [this, item], { root: item });
|
|
832
832
|
}
|
|
@@ -842,10 +842,10 @@ export default class Position extends TypeCheckable {
|
|
|
842
842
|
static _createBefore(item, stickiness) {
|
|
843
843
|
if (!item.parent) {
|
|
844
844
|
/**
|
|
845
|
-
* You
|
|
845
|
+
* You cannot make a position before a root element.
|
|
846
846
|
*
|
|
847
847
|
* @error model-position-before-root
|
|
848
|
-
* @param root
|
|
848
|
+
* @param {module:engine/model/rootelement~RootElement} root The root element..
|
|
849
849
|
*/
|
|
850
850
|
throw new CKEditorError('model-position-before-root', item, { root: item });
|
|
851
851
|
}
|
|
@@ -869,7 +869,7 @@ export default class Position extends TypeCheckable {
|
|
|
869
869
|
* Cannot create position for document. Root with specified name does not exist.
|
|
870
870
|
*
|
|
871
871
|
* @error model-position-fromjson-no-root
|
|
872
|
-
* @param rootName
|
|
872
|
+
* @param {string} rootName The root name.
|
|
873
873
|
*/
|
|
874
874
|
throw new CKEditorError('model-position-fromjson-no-root', doc, { rootName: json.root });
|
|
875
875
|
}
|
package/src/model/range.d.ts
CHANGED
|
@@ -400,7 +400,7 @@ export default class Range extends TypeCheckable implements Iterable<TreeWalkerV
|
|
|
400
400
|
* If the deleted range contains transformed range, `null` will be returned.
|
|
401
401
|
*
|
|
402
402
|
* @internal
|
|
403
|
-
* @param
|
|
403
|
+
* @param deletePosition Position from which nodes are removed.
|
|
404
404
|
* @param howMany How many nodes are removed.
|
|
405
405
|
* @returns Result of the transformation.
|
|
406
406
|
*/
|
package/src/model/range.js
CHANGED
|
@@ -744,7 +744,7 @@ export default class Range extends TypeCheckable {
|
|
|
744
744
|
* If the deleted range contains transformed range, `null` will be returned.
|
|
745
745
|
*
|
|
746
746
|
* @internal
|
|
747
|
-
* @param
|
|
747
|
+
* @param deletePosition Position from which nodes are removed.
|
|
748
748
|
* @param howMany How many nodes are removed.
|
|
749
749
|
* @returns Result of the transformation.
|
|
750
750
|
*/
|
package/src/model/selection.js
CHANGED
|
@@ -635,8 +635,8 @@ export default class Selection extends /* #__PURE__ */ EmitterMixin(TypeCheckabl
|
|
|
635
635
|
* Trying to add a range that intersects with another range in the selection.
|
|
636
636
|
*
|
|
637
637
|
* @error model-selection-range-intersects
|
|
638
|
-
* @param addedRange Range that was added to the selection.
|
|
639
|
-
* @param intersectingRange Range in the selection that intersects with `addedRange`.
|
|
638
|
+
* @param {module:engine/model/range~Range} addedRange Range that was added to the selection.
|
|
639
|
+
* @param {module:engine/model/range~Range} intersectingRange Range in the selection that intersects with `addedRange`.
|
|
640
640
|
*/
|
|
641
641
|
throw new CKEditorError('model-selection-range-intersects', [this, range], { addedRange: range, intersectingRange: this._ranges[i] });
|
|
642
642
|
}
|
|
@@ -50,9 +50,22 @@ import type Selection from '../selection.js';
|
|
|
50
50
|
* **Note:** If there is no valid position for the selection, the paragraph will always be created:
|
|
51
51
|
*
|
|
52
52
|
* `[<imageBlock src="foo.jpg"></imageBlock>]` -> `<paragraph>[]</paragraph>`.
|
|
53
|
+
*
|
|
54
|
+
* @param options.doNotFixSelection Whether given selection-to-remove should be fixed if it ends at the beginning of an element.
|
|
55
|
+
*
|
|
56
|
+
* By default, `deleteContent()` will fix selection before performing a deletion, so that the selection does not end at the beginning of
|
|
57
|
+
* an element. For example, selection `<heading>[Heading</heading><paragraph>]Some text.</paragraph>` will be treated as it was
|
|
58
|
+
* `<heading>[Heading]</heading><paragraph>Some text.</paragraph>`. As a result, the elements will not get merged.
|
|
59
|
+
*
|
|
60
|
+
* If selection is as in example, visually, the next element (paragraph) is not selected and it may be confusing for the user that
|
|
61
|
+
* the elements got merged. Selection is set up like this by browsers when a user triple-clicks on some text.
|
|
62
|
+
*
|
|
63
|
+
* However, in some cases, it is expected to remove content exactly as selected in the selection, without any fixing. In these cases,
|
|
64
|
+
* this flag can be set to `true`, which will prevent fixing the selection.
|
|
53
65
|
*/
|
|
54
66
|
export default function deleteContent(model: Model, selection: Selection | DocumentSelection, options?: {
|
|
55
67
|
leaveUnmerged?: boolean;
|
|
56
68
|
doNotResetEntireContent?: boolean;
|
|
57
69
|
doNotAutoparagraph?: boolean;
|
|
70
|
+
doNotFixSelection?: boolean;
|
|
58
71
|
}): void;
|
|
@@ -50,6 +50,18 @@ import Range from '../range.js';
|
|
|
50
50
|
* **Note:** If there is no valid position for the selection, the paragraph will always be created:
|
|
51
51
|
*
|
|
52
52
|
* `[<imageBlock src="foo.jpg"></imageBlock>]` -> `<paragraph>[]</paragraph>`.
|
|
53
|
+
*
|
|
54
|
+
* @param options.doNotFixSelection Whether given selection-to-remove should be fixed if it ends at the beginning of an element.
|
|
55
|
+
*
|
|
56
|
+
* By default, `deleteContent()` will fix selection before performing a deletion, so that the selection does not end at the beginning of
|
|
57
|
+
* an element. For example, selection `<heading>[Heading</heading><paragraph>]Some text.</paragraph>` will be treated as it was
|
|
58
|
+
* `<heading>[Heading]</heading><paragraph>Some text.</paragraph>`. As a result, the elements will not get merged.
|
|
59
|
+
*
|
|
60
|
+
* If selection is as in example, visually, the next element (paragraph) is not selected and it may be confusing for the user that
|
|
61
|
+
* the elements got merged. Selection is set up like this by browsers when a user triple-clicks on some text.
|
|
62
|
+
*
|
|
63
|
+
* However, in some cases, it is expected to remove content exactly as selected in the selection, without any fixing. In these cases,
|
|
64
|
+
* this flag can be set to `true`, which will prevent fixing the selection.
|
|
53
65
|
*/
|
|
54
66
|
export default function deleteContent(model, selection, options = {}) {
|
|
55
67
|
if (selection.isCollapsed) {
|
|
@@ -77,7 +89,14 @@ export default function deleteContent(model, selection, options = {}) {
|
|
|
77
89
|
}
|
|
78
90
|
}
|
|
79
91
|
// Get the live positions for the range adjusted to span only blocks selected from the user perspective.
|
|
80
|
-
|
|
92
|
+
let startPosition, endPosition;
|
|
93
|
+
if (!options.doNotFixSelection) {
|
|
94
|
+
[startPosition, endPosition] = getLivePositionsForSelectedBlocks(selRange);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
startPosition = LivePosition.fromPosition(selRange.start, 'toPrevious');
|
|
98
|
+
endPosition = LivePosition.fromPosition(selRange.end, 'toNext');
|
|
99
|
+
}
|
|
81
100
|
// 2. Remove the content if there is any.
|
|
82
101
|
if (!startPosition.isTouching(endPosition)) {
|
|
83
102
|
writer.remove(writer.createRange(startPosition, endPosition));
|
|
@@ -38,7 +38,6 @@ import type Selection from '../selection.js';
|
|
|
38
38
|
* @param model The model in context of which the insertion should be performed.
|
|
39
39
|
* @param content The content to insert.
|
|
40
40
|
* @param selectable Selection into which the content should be inserted.
|
|
41
|
-
* @param placeOrOffset Sets place or offset of the selection.
|
|
42
41
|
* @returns Range which contains all the performed changes. This is a range that, if removed,
|
|
43
42
|
* would return the model to the state before the insertion. If no changes were preformed by `insertContent`, returns a range collapsed
|
|
44
43
|
* at the insertion position.
|