@ckeditor/ckeditor5-engine 36.0.1 → 37.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +25 -24
- package/src/controller/datacontroller.d.ts +331 -0
- package/src/controller/datacontroller.js +72 -116
- package/src/controller/editingcontroller.d.ts +98 -0
- package/src/controller/editingcontroller.js +22 -46
- package/src/conversion/conversion.d.ts +476 -0
- package/src/conversion/conversion.js +328 -347
- package/src/conversion/conversionhelpers.d.ts +26 -0
- package/src/conversion/conversionhelpers.js +1 -5
- package/src/conversion/downcastdispatcher.d.ts +547 -0
- package/src/conversion/downcastdispatcher.js +74 -152
- package/src/conversion/downcasthelpers.d.ts +1226 -0
- package/src/conversion/downcasthelpers.js +843 -762
- package/src/conversion/mapper.d.ts +503 -0
- package/src/conversion/mapper.js +84 -99
- package/src/conversion/modelconsumable.d.ts +201 -0
- package/src/conversion/modelconsumable.js +96 -99
- package/src/conversion/upcastdispatcher.d.ts +492 -0
- package/src/conversion/upcastdispatcher.js +73 -100
- package/src/conversion/upcasthelpers.d.ts +499 -0
- package/src/conversion/upcasthelpers.js +406 -373
- package/src/conversion/viewconsumable.d.ts +369 -0
- package/src/conversion/viewconsumable.js +139 -173
- package/src/dataprocessor/basichtmlwriter.d.ts +18 -0
- package/src/dataprocessor/basichtmlwriter.js +0 -9
- package/src/dataprocessor/dataprocessor.d.ts +61 -0
- package/src/dataprocessor/htmldataprocessor.d.ts +76 -0
- package/src/dataprocessor/htmldataprocessor.js +6 -28
- package/src/dataprocessor/htmlwriter.d.ts +16 -0
- package/src/dataprocessor/xmldataprocessor.d.ts +90 -0
- package/src/dataprocessor/xmldataprocessor.js +8 -40
- package/src/dev-utils/model.d.ts +124 -0
- package/src/dev-utils/model.js +41 -38
- package/src/dev-utils/operationreplayer.d.ts +51 -0
- package/src/dev-utils/operationreplayer.js +6 -14
- package/src/dev-utils/utils.d.ts +37 -0
- package/src/dev-utils/utils.js +5 -18
- package/src/dev-utils/view.d.ts +319 -0
- package/src/dev-utils/view.js +205 -226
- package/src/index.d.ts +108 -0
- package/src/index.js +4 -0
- package/src/model/batch.d.ts +106 -0
- package/src/model/differ.d.ts +329 -0
- package/src/model/document.d.ts +246 -0
- package/src/model/document.js +1 -1
- package/src/model/documentfragment.d.ts +196 -0
- package/src/model/documentfragment.js +2 -2
- package/src/model/documentselection.d.ts +420 -0
- package/src/model/element.d.ts +165 -0
- package/src/model/history.d.ts +114 -0
- package/src/model/item.d.ts +14 -0
- package/src/model/liveposition.d.ts +77 -0
- package/src/model/liverange.d.ts +102 -0
- package/src/model/markercollection.d.ts +335 -0
- package/src/model/model.d.ts +885 -0
- package/src/model/model.js +59 -81
- package/src/model/node.d.ts +256 -0
- package/src/model/nodelist.d.ts +91 -0
- package/src/model/operation/attributeoperation.d.ts +98 -0
- package/src/model/operation/detachoperation.d.ts +55 -0
- package/src/model/operation/insertoperation.d.ts +85 -0
- package/src/model/operation/markeroperation.d.ts +86 -0
- package/src/model/operation/mergeoperation.d.ts +95 -0
- package/src/model/operation/mergeoperation.js +1 -1
- package/src/model/operation/moveoperation.d.ts +91 -0
- package/src/model/operation/nooperation.d.ts +33 -0
- package/src/model/operation/operation.d.ts +89 -0
- package/src/model/operation/operationfactory.d.ts +18 -0
- package/src/model/operation/renameoperation.d.ts +78 -0
- package/src/model/operation/rootattributeoperation.d.ts +97 -0
- package/src/model/operation/rootattributeoperation.js +1 -1
- package/src/model/operation/splitoperation.d.ts +104 -0
- package/src/model/operation/splitoperation.js +1 -1
- package/src/model/operation/transform.d.ts +100 -0
- package/src/model/operation/utils.d.ts +71 -0
- package/src/model/operation/utils.js +1 -1
- package/src/model/position.d.ts +539 -0
- package/src/model/position.js +1 -1
- package/src/model/range.d.ts +458 -0
- package/src/model/range.js +1 -1
- package/src/model/rootelement.d.ts +40 -0
- package/src/model/schema.d.ts +1176 -0
- package/src/model/schema.js +19 -19
- package/src/model/selection.d.ts +472 -0
- package/src/model/text.d.ts +66 -0
- package/src/model/text.js +0 -2
- package/src/model/textproxy.d.ts +144 -0
- package/src/model/treewalker.d.ts +186 -0
- package/src/model/treewalker.js +19 -10
- package/src/model/typecheckable.d.ts +285 -0
- package/src/model/utils/autoparagraphing.d.ts +37 -0
- package/src/model/utils/deletecontent.d.ts +58 -0
- package/src/model/utils/findoptimalinsertionrange.d.ts +32 -0
- package/src/model/utils/getselectedcontent.d.ts +30 -0
- package/src/model/utils/insertcontent.d.ts +46 -0
- package/src/model/utils/insertcontent.js +2 -12
- package/src/model/utils/insertobject.d.ts +44 -0
- package/src/model/utils/insertobject.js +3 -14
- package/src/model/utils/modifyselection.d.ts +48 -0
- package/src/model/utils/selection-post-fixer.d.ts +65 -0
- package/src/model/writer.d.ts +823 -0
- package/src/model/writer.js +6 -61
- package/src/view/attributeelement.d.ts +108 -0
- package/src/view/attributeelement.js +25 -69
- package/src/view/containerelement.d.ts +49 -0
- package/src/view/containerelement.js +10 -43
- package/src/view/datatransfer.d.ts +75 -0
- package/src/view/document.d.ts +184 -0
- package/src/view/document.js +15 -84
- package/src/view/documentfragment.d.ts +149 -0
- package/src/view/documentfragment.js +39 -81
- package/src/view/documentselection.d.ts +306 -0
- package/src/view/documentselection.js +42 -143
- package/src/view/domconverter.d.ts +650 -0
- package/src/view/domconverter.js +157 -283
- package/src/view/downcastwriter.d.ts +996 -0
- package/src/view/downcastwriter.js +259 -426
- package/src/view/editableelement.d.ts +52 -0
- package/src/view/editableelement.js +9 -49
- package/src/view/element.d.ts +468 -0
- package/src/view/element.js +150 -222
- package/src/view/elementdefinition.d.ts +87 -0
- package/src/view/emptyelement.d.ts +41 -0
- package/src/view/emptyelement.js +11 -44
- package/src/view/filler.d.ts +111 -0
- package/src/view/filler.js +24 -21
- package/src/view/item.d.ts +14 -0
- package/src/view/matcher.d.ts +486 -0
- package/src/view/matcher.js +247 -218
- package/src/view/node.d.ts +163 -0
- package/src/view/node.js +26 -100
- package/src/view/observer/arrowkeysobserver.d.ts +41 -0
- package/src/view/observer/arrowkeysobserver.js +0 -13
- package/src/view/observer/bubblingemittermixin.d.ts +166 -0
- package/src/view/observer/bubblingemittermixin.js +36 -25
- package/src/view/observer/bubblingeventinfo.d.ts +47 -0
- package/src/view/observer/bubblingeventinfo.js +3 -29
- package/src/view/observer/clickobserver.d.ts +43 -0
- package/src/view/observer/clickobserver.js +9 -19
- package/src/view/observer/compositionobserver.d.ts +82 -0
- package/src/view/observer/compositionobserver.js +13 -42
- package/src/view/observer/domeventdata.d.ts +50 -0
- package/src/view/observer/domeventdata.js +5 -30
- package/src/view/observer/domeventobserver.d.ts +69 -0
- package/src/view/observer/domeventobserver.js +19 -21
- package/src/view/observer/fakeselectionobserver.d.ts +43 -0
- package/src/view/observer/fakeselectionobserver.js +0 -16
- package/src/view/observer/focusobserver.d.ts +82 -0
- package/src/view/observer/focusobserver.js +14 -40
- package/src/view/observer/inputobserver.d.ts +86 -0
- package/src/view/observer/inputobserver.js +18 -64
- package/src/view/observer/keyobserver.d.ts +66 -0
- package/src/view/observer/keyobserver.js +8 -42
- package/src/view/observer/mouseobserver.d.ts +89 -0
- package/src/view/observer/mouseobserver.js +8 -28
- package/src/view/observer/mutationobserver.d.ts +82 -0
- package/src/view/observer/mutationobserver.js +7 -37
- package/src/view/observer/observer.d.ts +84 -0
- package/src/view/observer/observer.js +12 -25
- package/src/view/observer/selectionobserver.d.ts +144 -0
- package/src/view/observer/selectionobserver.js +17 -107
- package/src/view/observer/tabobserver.d.ts +42 -0
- package/src/view/observer/tabobserver.js +0 -14
- package/src/view/placeholder.d.ts +85 -0
- package/src/view/placeholder.js +26 -43
- package/src/view/position.d.ts +189 -0
- package/src/view/position.js +36 -83
- package/src/view/range.d.ts +279 -0
- package/src/view/range.js +79 -122
- package/src/view/rawelement.d.ts +73 -0
- package/src/view/rawelement.js +34 -48
- package/src/view/renderer.d.ts +265 -0
- package/src/view/renderer.js +105 -193
- package/src/view/rooteditableelement.d.ts +41 -0
- package/src/view/rooteditableelement.js +12 -40
- package/src/view/selection.d.ts +375 -0
- package/src/view/selection.js +79 -153
- package/src/view/styles/background.d.ts +33 -0
- package/src/view/styles/background.js +14 -12
- package/src/view/styles/border.d.ts +43 -0
- package/src/view/styles/border.js +58 -48
- package/src/view/styles/margin.d.ts +29 -0
- package/src/view/styles/margin.js +13 -11
- package/src/view/styles/padding.d.ts +29 -0
- package/src/view/styles/padding.js +13 -11
- package/src/view/styles/utils.d.ts +93 -0
- package/src/view/styles/utils.js +22 -48
- package/src/view/stylesmap.d.ts +675 -0
- package/src/view/stylesmap.js +249 -244
- package/src/view/text.d.ts +74 -0
- package/src/view/text.js +16 -46
- package/src/view/textproxy.d.ts +97 -0
- package/src/view/textproxy.js +10 -59
- package/src/view/treewalker.d.ts +195 -0
- package/src/view/treewalker.js +43 -106
- package/src/view/typecheckable.d.ts +448 -0
- package/src/view/uielement.d.ts +96 -0
- package/src/view/uielement.js +29 -63
- package/src/view/upcastwriter.d.ts +417 -0
- package/src/view/upcastwriter.js +86 -157
- package/src/view/view.d.ts +417 -0
- package/src/view/view.js +47 -175
package/src/conversion/mapper.js
CHANGED
|
@@ -29,7 +29,6 @@ import { CKEditorError, EmitterMixin } from '@ckeditor/ckeditor5-utils';
|
|
|
29
29
|
* and {@link module:engine/conversion/mapper~Mapper#toModelPosition toModelPosition} methods. `Mapper` adds its own default callbacks
|
|
30
30
|
* with `'lowest'` priority. To override default `Mapper` mapping, add custom callback with higher priority and
|
|
31
31
|
* stop the event.
|
|
32
|
-
* @mixes module:utils/emittermixin~EmitterMixin
|
|
33
32
|
*/
|
|
34
33
|
export default class Mapper extends EmitterMixin() {
|
|
35
34
|
/**
|
|
@@ -39,24 +38,15 @@ export default class Mapper extends EmitterMixin() {
|
|
|
39
38
|
super();
|
|
40
39
|
/**
|
|
41
40
|
* Model element to view element mapping.
|
|
42
|
-
*
|
|
43
|
-
* @private
|
|
44
|
-
* @member {WeakMap}
|
|
45
41
|
*/
|
|
46
42
|
this._modelToViewMapping = new WeakMap();
|
|
47
43
|
/**
|
|
48
44
|
* View element to model element mapping.
|
|
49
|
-
*
|
|
50
|
-
* @private
|
|
51
|
-
* @member {WeakMap}
|
|
52
45
|
*/
|
|
53
46
|
this._viewToModelMapping = new WeakMap();
|
|
54
47
|
/**
|
|
55
48
|
* A map containing callbacks between view element names and functions evaluating length of view elements
|
|
56
49
|
* in model.
|
|
57
|
-
*
|
|
58
|
-
* @private
|
|
59
|
-
* @member {Map}
|
|
60
50
|
*/
|
|
61
51
|
this._viewToModelLengthCallbacks = new Map();
|
|
62
52
|
/**
|
|
@@ -64,33 +54,21 @@ export default class Mapper extends EmitterMixin() {
|
|
|
64
54
|
*
|
|
65
55
|
* Keys are `String`s while values are `Set`s with {@link module:engine/view/element~Element view elements}.
|
|
66
56
|
* One marker (name) can be mapped to multiple elements.
|
|
67
|
-
*
|
|
68
|
-
* @private
|
|
69
|
-
* @member {Map}
|
|
70
57
|
*/
|
|
71
58
|
this._markerNameToElements = new Map();
|
|
72
59
|
/**
|
|
73
60
|
* View element to model marker names mapping.
|
|
74
61
|
*
|
|
75
62
|
* This is reverse to {@link ~Mapper#_markerNameToElements} map.
|
|
76
|
-
*
|
|
77
|
-
* @private
|
|
78
|
-
* @member {Map}
|
|
79
63
|
*/
|
|
80
64
|
this._elementToMarkerNames = new Map();
|
|
81
65
|
/**
|
|
82
66
|
* The map of removed view elements with their current root (used for deferred unbinding).
|
|
83
|
-
*
|
|
84
|
-
* @private
|
|
85
|
-
* @member {Map.<module:engine/view/element~Element,module:engine/view/documentfragment~DocumentFragment>}
|
|
86
67
|
*/
|
|
87
68
|
this._deferredBindingRemovals = new Map();
|
|
88
69
|
/**
|
|
89
70
|
* Stores marker names of markers which have changed due to unbinding a view element (so it is assumed that the view element
|
|
90
71
|
* has been removed, moved or renamed).
|
|
91
|
-
*
|
|
92
|
-
* @private
|
|
93
|
-
* @member {Set.<module:engine/model/markercollection~Marker>}
|
|
94
72
|
*/
|
|
95
73
|
this._unboundMarkerNames = new Set();
|
|
96
74
|
// Default mapper algorithm for mapping model position to view position.
|
|
@@ -129,8 +107,8 @@ export default class Mapper extends EmitterMixin() {
|
|
|
129
107
|
* {@link module:engine/conversion/mapper~Mapper#toViewElement toViewElement} methods.
|
|
130
108
|
* The information that elements are bound is also used to translate positions.
|
|
131
109
|
*
|
|
132
|
-
* @param
|
|
133
|
-
* @param
|
|
110
|
+
* @param modelElement Model element.
|
|
111
|
+
* @param viewElement View element.
|
|
134
112
|
*/
|
|
135
113
|
bindElements(modelElement, viewElement) {
|
|
136
114
|
this._modelToViewMapping.set(modelElement, viewElement);
|
|
@@ -145,9 +123,9 @@ export default class Mapper extends EmitterMixin() {
|
|
|
145
123
|
* This behavior allows for re-binding model element to another view element without fear of losing the new binding
|
|
146
124
|
* when the previously bound view element is unbound.
|
|
147
125
|
*
|
|
148
|
-
* @param
|
|
149
|
-
* @param
|
|
150
|
-
* @param
|
|
126
|
+
* @param viewElement View element to unbind.
|
|
127
|
+
* @param options The options object.
|
|
128
|
+
* @param options.defer Controls whether the binding should be removed immediately or deferred until a
|
|
151
129
|
* {@link #flushDeferredBindings `flushDeferredBindings()`} call.
|
|
152
130
|
*/
|
|
153
131
|
unbindViewElement(viewElement, options = {}) {
|
|
@@ -176,7 +154,7 @@ export default class Mapper extends EmitterMixin() {
|
|
|
176
154
|
* This behavior lets for re-binding view element to another model element without fear of losing the new binding
|
|
177
155
|
* when the previously bound model element is unbound.
|
|
178
156
|
*
|
|
179
|
-
* @param
|
|
157
|
+
* @param modelElement Model element to unbind.
|
|
180
158
|
*/
|
|
181
159
|
unbindModelElement(modelElement) {
|
|
182
160
|
const viewElement = this.toViewElement(modelElement);
|
|
@@ -189,8 +167,8 @@ export default class Mapper extends EmitterMixin() {
|
|
|
189
167
|
* Binds the given marker name with the given {@link module:engine/view/element~Element view element}. The element
|
|
190
168
|
* will be added to the current set of elements bound with the given marker name.
|
|
191
169
|
*
|
|
192
|
-
* @param
|
|
193
|
-
* @param
|
|
170
|
+
* @param element Element to bind.
|
|
171
|
+
* @param name Marker name.
|
|
194
172
|
*/
|
|
195
173
|
bindElementToMarker(element, name) {
|
|
196
174
|
const elements = this._markerNameToElements.get(name) || new Set();
|
|
@@ -203,8 +181,8 @@ export default class Mapper extends EmitterMixin() {
|
|
|
203
181
|
/**
|
|
204
182
|
* Unbinds an element from given marker name.
|
|
205
183
|
*
|
|
206
|
-
* @param
|
|
207
|
-
* @param
|
|
184
|
+
* @param element Element to unbind.
|
|
185
|
+
* @param name Marker name.
|
|
208
186
|
*/
|
|
209
187
|
unbindElementFromMarkerName(element, name) {
|
|
210
188
|
const nameToElements = this._markerNameToElements.get(name);
|
|
@@ -225,8 +203,6 @@ export default class Mapper extends EmitterMixin() {
|
|
|
225
203
|
/**
|
|
226
204
|
* Returns all marker names of markers which have changed due to unbinding a view element (so it is assumed that the view element
|
|
227
205
|
* has been removed, moved or renamed) since the last flush. After returning, the marker names list is cleared.
|
|
228
|
-
*
|
|
229
|
-
* @returns {Array.<String>}
|
|
230
206
|
*/
|
|
231
207
|
flushUnboundMarkerNames() {
|
|
232
208
|
const markerNames = Array.from(this._unboundMarkerNames);
|
|
@@ -267,8 +243,8 @@ export default class Mapper extends EmitterMixin() {
|
|
|
267
243
|
/**
|
|
268
244
|
* Gets the corresponding model range.
|
|
269
245
|
*
|
|
270
|
-
* @param
|
|
271
|
-
* @returns
|
|
246
|
+
* @param viewRange View range.
|
|
247
|
+
* @returns Corresponding model range.
|
|
272
248
|
*/
|
|
273
249
|
toModelRange(viewRange) {
|
|
274
250
|
return new ModelRange(this.toModelPosition(viewRange.start), this.toModelPosition(viewRange.end));
|
|
@@ -276,8 +252,8 @@ export default class Mapper extends EmitterMixin() {
|
|
|
276
252
|
/**
|
|
277
253
|
* Gets the corresponding view range.
|
|
278
254
|
*
|
|
279
|
-
* @param
|
|
280
|
-
* @returns
|
|
255
|
+
* @param modelRange Model range.
|
|
256
|
+
* @returns Corresponding view range.
|
|
281
257
|
*/
|
|
282
258
|
toViewRange(modelRange) {
|
|
283
259
|
return new ViewRange(this.toViewPosition(modelRange.start), this.toViewPosition(modelRange.end));
|
|
@@ -286,8 +262,8 @@ export default class Mapper extends EmitterMixin() {
|
|
|
286
262
|
* Gets the corresponding model position.
|
|
287
263
|
*
|
|
288
264
|
* @fires viewToModelPosition
|
|
289
|
-
* @param
|
|
290
|
-
* @returns
|
|
265
|
+
* @param viewPosition View position.
|
|
266
|
+
* @returns Corresponding model position.
|
|
291
267
|
*/
|
|
292
268
|
toModelPosition(viewPosition) {
|
|
293
269
|
const data = {
|
|
@@ -301,11 +277,11 @@ export default class Mapper extends EmitterMixin() {
|
|
|
301
277
|
* Gets the corresponding view position.
|
|
302
278
|
*
|
|
303
279
|
* @fires modelToViewPosition
|
|
304
|
-
* @param
|
|
305
|
-
* @param
|
|
306
|
-
* @param
|
|
280
|
+
* @param modelPosition Model position.
|
|
281
|
+
* @param options Additional options for position mapping process.
|
|
282
|
+
* @param options.isPhantom Should be set to `true` if the model position to map is pointing to a place
|
|
307
283
|
* in model tree which no longer exists. For example, it could be an end of a removed model range.
|
|
308
|
-
* @returns
|
|
284
|
+
* @returns Corresponding view position.
|
|
309
285
|
*/
|
|
310
286
|
toViewPosition(modelPosition, options = {}) {
|
|
311
287
|
const data = {
|
|
@@ -319,8 +295,8 @@ export default class Mapper extends EmitterMixin() {
|
|
|
319
295
|
/**
|
|
320
296
|
* Gets all view elements bound to the given marker name.
|
|
321
297
|
*
|
|
322
|
-
* @param
|
|
323
|
-
* @returns
|
|
298
|
+
* @param name Marker name.
|
|
299
|
+
* @returns View elements bound with the given marker name or `null`
|
|
324
300
|
* if no elements are bound to the given marker name.
|
|
325
301
|
*/
|
|
326
302
|
markerNameToElements(name) {
|
|
@@ -347,28 +323,30 @@ export default class Mapper extends EmitterMixin() {
|
|
|
347
323
|
* The callback is fired with one argument, which is a view element instance. The callback is expected to return
|
|
348
324
|
* a number representing the length of the view element in the model.
|
|
349
325
|
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
326
|
+
* ```ts
|
|
327
|
+
* // List item in view may contain nested list, which have other list items. In model though,
|
|
328
|
+
* // the lists are represented by flat structure. Because of those differences, length of list view element
|
|
329
|
+
* // may be greater than one. In the callback it's checked how many nested list items are in evaluated list item.
|
|
353
330
|
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
331
|
+
* function getViewListItemLength( element ) {
|
|
332
|
+
* let length = 1;
|
|
356
333
|
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
334
|
+
* for ( let child of element.getChildren() ) {
|
|
335
|
+
* if ( child.name == 'ul' || child.name == 'ol' ) {
|
|
336
|
+
* for ( let item of child.getChildren() ) {
|
|
337
|
+
* length += getViewListItemLength( item );
|
|
338
|
+
* }
|
|
339
|
+
* }
|
|
340
|
+
* }
|
|
364
341
|
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
342
|
+
* return length;
|
|
343
|
+
* }
|
|
367
344
|
*
|
|
368
|
-
*
|
|
345
|
+
* mapper.registerViewToModelLength( 'li', getViewListItemLength );
|
|
346
|
+
* ```
|
|
369
347
|
*
|
|
370
|
-
* @param
|
|
371
|
-
* @param
|
|
348
|
+
* @param viewElementName Name of view element for which callback is registered.
|
|
349
|
+
* @param lengthCallback Function return a length of view element instance in model.
|
|
372
350
|
*/
|
|
373
351
|
registerViewToModelLength(viewElementName, lengthCallback) {
|
|
374
352
|
this._viewToModelLengthCallbacks.set(viewElementName, lengthCallback);
|
|
@@ -377,8 +355,7 @@ export default class Mapper extends EmitterMixin() {
|
|
|
377
355
|
* For the given `viewPosition`, finds and returns the closest ancestor of this position that has a mapping to
|
|
378
356
|
* the model.
|
|
379
357
|
*
|
|
380
|
-
* @param
|
|
381
|
-
* @returns {module:engine/view/element~Element}
|
|
358
|
+
* @param viewPosition Position for which a mapped ancestor should be found.
|
|
382
359
|
*/
|
|
383
360
|
findMappedViewAncestor(viewPosition) {
|
|
384
361
|
let parent = viewPosition.parent;
|
|
@@ -392,18 +369,21 @@ export default class Mapper extends EmitterMixin() {
|
|
|
392
369
|
*
|
|
393
370
|
* Example:
|
|
394
371
|
*
|
|
395
|
-
*
|
|
372
|
+
* ```html
|
|
373
|
+
* <p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, p ) -> 5
|
|
374
|
+
* ```
|
|
396
375
|
*
|
|
397
376
|
* Is a sum of:
|
|
398
377
|
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
378
|
+
* ```html
|
|
379
|
+
* <p>foo|<b>bar</b></p> // _toModelOffset( p, 3, p ) -> 3
|
|
380
|
+
* <p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, b ) -> 2
|
|
381
|
+
* ```
|
|
401
382
|
*
|
|
402
|
-
* @
|
|
403
|
-
* @param
|
|
404
|
-
* @param
|
|
405
|
-
* @
|
|
406
|
-
* @returns {Number} Offset in the model.
|
|
383
|
+
* @param viewParent Position parent.
|
|
384
|
+
* @param viewOffset Position offset.
|
|
385
|
+
* @param viewBlock Block used as a base to calculate offset.
|
|
386
|
+
* @returns Offset in the model.
|
|
407
387
|
*/
|
|
408
388
|
_toModelOffset(viewParent, viewOffset, viewBlock) {
|
|
409
389
|
if (viewBlock != viewParent) {
|
|
@@ -438,13 +418,15 @@ export default class Mapper extends EmitterMixin() {
|
|
|
438
418
|
*
|
|
439
419
|
* Examples:
|
|
440
420
|
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
444
|
-
*
|
|
421
|
+
* ```
|
|
422
|
+
* foo -> 3 // Text length is equal to its data length.
|
|
423
|
+
* <p>foo</p> -> 1 // Length of an element which is mapped is by default equal to 1.
|
|
424
|
+
* <b>foo</b> -> 3 // Length of an element which is not mapped is a length of its children.
|
|
425
|
+
* <div><p>x</p><p>y</p></div> -> 2 // Assuming that <div> is not mapped and <p> are mapped.
|
|
426
|
+
* ```
|
|
445
427
|
*
|
|
446
|
-
* @param
|
|
447
|
-
* @returns
|
|
428
|
+
* @param viewNode View node.
|
|
429
|
+
* @returns Length of the node in the tree model.
|
|
448
430
|
*/
|
|
449
431
|
getModelLength(viewNode) {
|
|
450
432
|
if (this._viewToModelLengthCallbacks.get(viewNode.name)) {
|
|
@@ -473,24 +455,26 @@ export default class Mapper extends EmitterMixin() {
|
|
|
473
455
|
*
|
|
474
456
|
* Example:
|
|
475
457
|
*
|
|
476
|
-
*
|
|
458
|
+
* ```
|
|
459
|
+
* <p>fo<b>bar</b>bom</p> -> expected offset: 4
|
|
477
460
|
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
481
|
-
*
|
|
461
|
+
* findPositionIn( p, 4 ):
|
|
462
|
+
* <p>|fo<b>bar</b>bom</p> -> expected offset: 4, actual offset: 0
|
|
463
|
+
* <p>fo|<b>bar</b>bom</p> -> expected offset: 4, actual offset: 2
|
|
464
|
+
* <p>fo<b>bar</b>|bom</p> -> expected offset: 4, actual offset: 5 -> we are too far
|
|
482
465
|
*
|
|
483
|
-
*
|
|
484
|
-
*
|
|
485
|
-
*
|
|
466
|
+
* findPositionIn( b, 4 - ( 5 - 3 ) ):
|
|
467
|
+
* <p>fo<b>|bar</b>bom</p> -> expected offset: 2, actual offset: 0
|
|
468
|
+
* <p>fo<b>bar|</b>bom</p> -> expected offset: 2, actual offset: 3 -> we are too far
|
|
486
469
|
*
|
|
487
|
-
*
|
|
488
|
-
*
|
|
489
|
-
*
|
|
470
|
+
* findPositionIn( bar, 2 - ( 3 - 3 ) ):
|
|
471
|
+
* We are in the text node so we can simple find the offset.
|
|
472
|
+
* <p>fo<b>ba|r</b>bom</p> -> expected offset: 2, actual offset: 2 -> position found
|
|
473
|
+
* ```
|
|
490
474
|
*
|
|
491
|
-
* @param
|
|
492
|
-
* @param
|
|
493
|
-
* @returns
|
|
475
|
+
* @param viewParent Tree view element in which we are looking for the position.
|
|
476
|
+
* @param expectedOffset Expected offset.
|
|
477
|
+
* @returns Found position.
|
|
494
478
|
*/
|
|
495
479
|
findPositionIn(viewParent, expectedOffset) {
|
|
496
480
|
// Last scanned view node.
|
|
@@ -526,13 +510,14 @@ export default class Mapper extends EmitterMixin() {
|
|
|
526
510
|
* Because we prefer positions in the text nodes over positions next to text nodes, if the view position was next to a text node,
|
|
527
511
|
* it moves it into the text node instead.
|
|
528
512
|
*
|
|
529
|
-
*
|
|
530
|
-
*
|
|
531
|
-
*
|
|
513
|
+
* ```
|
|
514
|
+
* <p>[]<b>foo</b></p> -> <p>[]<b>foo</b></p> // do not touch if position is not directly next to text
|
|
515
|
+
* <p>foo[]<b>foo</b></p> -> <p>foo{}<b>foo</b></p> // move to text node
|
|
516
|
+
* <p><b>[]foo</b></p> -> <p><b>{}foo</b></p> // move to text node
|
|
517
|
+
* ```
|
|
532
518
|
*
|
|
533
|
-
* @
|
|
534
|
-
* @
|
|
535
|
-
* @returns {module:engine/view/position~Position} Position in the text node if possible.
|
|
519
|
+
* @param viewPosition Position potentially next to the text node.
|
|
520
|
+
* @returns Position in the text node if possible.
|
|
536
521
|
*/
|
|
537
522
|
_moveViewPositionToTextNode(viewPosition) {
|
|
538
523
|
// If the position is just after a text node, put it at the end of that text node.
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* @module engine/conversion/modelconsumable
|
|
7
|
+
*/
|
|
8
|
+
import TextProxy from '../model/textproxy';
|
|
9
|
+
import type Item from '../model/item';
|
|
10
|
+
import type Selection from '../model/selection';
|
|
11
|
+
import type DocumentSelection from '../model/documentselection';
|
|
12
|
+
import type Range from '../model/range';
|
|
13
|
+
/**
|
|
14
|
+
* Manages a list of consumable values for the {@link module:engine/model/item~Item model items}.
|
|
15
|
+
*
|
|
16
|
+
* Consumables are various aspects of the model. A model item can be broken down into separate, single properties that might be
|
|
17
|
+
* taken into consideration when converting that item.
|
|
18
|
+
*
|
|
19
|
+
* `ModelConsumable` is used by {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} while analyzing the changed
|
|
20
|
+
* parts of {@link module:engine/model/document~Document the document}. The added / changed / removed model items are broken down
|
|
21
|
+
* into singular properties (the item itself and its attributes). All those parts are saved in `ModelConsumable`. Then,
|
|
22
|
+
* during conversion, when the given part of a model item is converted (i.e. the view element has been inserted into the view,
|
|
23
|
+
* but without attributes), the consumable value is removed from `ModelConsumable`.
|
|
24
|
+
*
|
|
25
|
+
* For model items, `ModelConsumable` stores consumable values of one of following types: `insert`, `addattribute:<attributeKey>`,
|
|
26
|
+
* `changeattributes:<attributeKey>`, `removeattributes:<attributeKey>`.
|
|
27
|
+
*
|
|
28
|
+
* In most cases, it is enough to let th {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}
|
|
29
|
+
* gather consumable values, so there is no need to use
|
|
30
|
+
* the {@link module:engine/conversion/modelconsumable~ModelConsumable#add add method} directly.
|
|
31
|
+
* However, it is important to understand how consumable values can be
|
|
32
|
+
* {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed}.
|
|
33
|
+
* See {@link module:engine/conversion/downcasthelpers default downcast converters} for more information.
|
|
34
|
+
*
|
|
35
|
+
* Keep in mind that one conversion event may have multiple callbacks (converters) attached to it. Each of those is
|
|
36
|
+
* able to convert one or more parts of the model. However, when one of those callbacks actually converts
|
|
37
|
+
* something, the others should not, because they would duplicate the results. Using `ModelConsumable` helps to avoid
|
|
38
|
+
* this situation, because callbacks should only convert these values that were not yet consumed from `ModelConsumable`.
|
|
39
|
+
*
|
|
40
|
+
* Consuming multiple values in a single callback:
|
|
41
|
+
*
|
|
42
|
+
* ```ts
|
|
43
|
+
* // Converter for custom `imageBlock` element that might have a `caption` element inside which changes
|
|
44
|
+
* // how the image is displayed in the view:
|
|
45
|
+
* //
|
|
46
|
+
* // Model:
|
|
47
|
+
* //
|
|
48
|
+
* // [imageBlock]
|
|
49
|
+
* // └─ [caption]
|
|
50
|
+
* // └─ foo
|
|
51
|
+
* //
|
|
52
|
+
* // View:
|
|
53
|
+
* //
|
|
54
|
+
* // <figure>
|
|
55
|
+
* // ├─ <img />
|
|
56
|
+
* // └─ <caption>
|
|
57
|
+
* // └─ foo
|
|
58
|
+
* modelConversionDispatcher.on( 'insert:imageBlock', ( evt, data, conversionApi ) => {
|
|
59
|
+
* // First, consume the `imageBlock` element.
|
|
60
|
+
* conversionApi.consumable.consume( data.item, 'insert' );
|
|
61
|
+
*
|
|
62
|
+
* // Just create normal image element for the view.
|
|
63
|
+
* // Maybe it will be "decorated" later.
|
|
64
|
+
* const viewImage = new ViewElement( 'img' );
|
|
65
|
+
* const insertPosition = conversionApi.mapper.toViewPosition( data.range.start );
|
|
66
|
+
* const viewWriter = conversionApi.writer;
|
|
67
|
+
*
|
|
68
|
+
* // Check if the `imageBlock` element has children.
|
|
69
|
+
* if ( data.item.childCount > 0 ) {
|
|
70
|
+
* const modelCaption = data.item.getChild( 0 );
|
|
71
|
+
*
|
|
72
|
+
* // `modelCaption` insertion change is consumed from consumable values.
|
|
73
|
+
* // It will not be converted by other converters, but it's children (probably some text) will be.
|
|
74
|
+
* // Through mapping, converters for text will know where to insert contents of `modelCaption`.
|
|
75
|
+
* if ( conversionApi.consumable.consume( modelCaption, 'insert' ) ) {
|
|
76
|
+
* const viewCaption = new ViewElement( 'figcaption' );
|
|
77
|
+
*
|
|
78
|
+
* const viewImageHolder = new ViewElement( 'figure', null, [ viewImage, viewCaption ] );
|
|
79
|
+
*
|
|
80
|
+
* conversionApi.mapper.bindElements( modelCaption, viewCaption );
|
|
81
|
+
* conversionApi.mapper.bindElements( data.item, viewImageHolder );
|
|
82
|
+
* viewWriter.insert( insertPosition, viewImageHolder );
|
|
83
|
+
* }
|
|
84
|
+
* } else {
|
|
85
|
+
* conversionApi.mapper.bindElements( data.item, viewImage );
|
|
86
|
+
* viewWriter.insert( insertPosition, viewImage );
|
|
87
|
+
* }
|
|
88
|
+
*
|
|
89
|
+
* evt.stop();
|
|
90
|
+
* } );
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export default class ModelConsumable {
|
|
94
|
+
/**
|
|
95
|
+
* Contains list of consumable values.
|
|
96
|
+
*/
|
|
97
|
+
private _consumable;
|
|
98
|
+
/**
|
|
99
|
+
* For each {@link module:engine/model/textproxy~TextProxy} added to `ModelConsumable`, this registry holds a parent
|
|
100
|
+
* of that `TextProxy` and the start and end indices of that `TextProxy`. This allows identification of the `TextProxy`
|
|
101
|
+
* instances that point to the same part of the model but are different instances. Each distinct `TextProxy`
|
|
102
|
+
* is given a unique `Symbol` which is then registered as consumable. This process is transparent for the `ModelConsumable`
|
|
103
|
+
* API user because whenever `TextProxy` is added, tested, consumed or reverted, the internal mechanisms of
|
|
104
|
+
* `ModelConsumable` translate `TextProxy` to that unique `Symbol`.
|
|
105
|
+
*/
|
|
106
|
+
private _textProxyRegistry;
|
|
107
|
+
/**
|
|
108
|
+
* Adds a consumable value to the consumables list and links it with a given model item.
|
|
109
|
+
*
|
|
110
|
+
* ```ts
|
|
111
|
+
* modelConsumable.add( modelElement, 'insert' ); // Add `modelElement` insertion change to consumable values.
|
|
112
|
+
* modelConsumable.add( modelElement, 'addAttribute:bold' ); // Add `bold` attribute insertion on `modelElement` change.
|
|
113
|
+
* modelConsumable.add( modelElement, 'removeAttribute:bold' ); // Add `bold` attribute removal on `modelElement` change.
|
|
114
|
+
* modelConsumable.add( modelSelection, 'selection' ); // Add `modelSelection` to consumable values.
|
|
115
|
+
* modelConsumable.add( modelRange, 'range' ); // Add `modelRange` to consumable values.
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
* @param item Model item, range or selection that has the consumable.
|
|
119
|
+
* @param type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.
|
|
120
|
+
* Second colon and everything after will be cut. Passing event name is a safe and good practice.
|
|
121
|
+
*/
|
|
122
|
+
add(item: Item | Selection | DocumentSelection | Range, type: string): void;
|
|
123
|
+
/**
|
|
124
|
+
* Removes a given consumable value from a given model item.
|
|
125
|
+
*
|
|
126
|
+
* ```ts
|
|
127
|
+
* modelConsumable.consume( modelElement, 'insert' ); // Remove `modelElement` insertion change from consumable values.
|
|
128
|
+
* modelConsumable.consume( modelElement, 'addAttribute:bold' ); // Remove `bold` attribute insertion on `modelElement` change.
|
|
129
|
+
* modelConsumable.consume( modelElement, 'removeAttribute:bold' ); // Remove `bold` attribute removal on `modelElement` change.
|
|
130
|
+
* modelConsumable.consume( modelSelection, 'selection' ); // Remove `modelSelection` from consumable values.
|
|
131
|
+
* modelConsumable.consume( modelRange, 'range' ); // Remove 'modelRange' from consumable values.
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
* @param item Model item, range or selection from which consumable will be consumed.
|
|
135
|
+
* @param type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.
|
|
136
|
+
* Second colon and everything after will be cut. Passing event name is a safe and good practice.
|
|
137
|
+
* @returns `true` if consumable value was available and was consumed, `false` otherwise.
|
|
138
|
+
*/
|
|
139
|
+
consume(item: Item | Selection | DocumentSelection | Range, type: string): boolean;
|
|
140
|
+
/**
|
|
141
|
+
* Tests whether there is a consumable value of a given type connected with a given model item.
|
|
142
|
+
*
|
|
143
|
+
* ```ts
|
|
144
|
+
* modelConsumable.test( modelElement, 'insert' ); // Check for `modelElement` insertion change.
|
|
145
|
+
* modelConsumable.test( modelElement, 'addAttribute:bold' ); // Check for `bold` attribute insertion on `modelElement` change.
|
|
146
|
+
* modelConsumable.test( modelElement, 'removeAttribute:bold' ); // Check for `bold` attribute removal on `modelElement` change.
|
|
147
|
+
* modelConsumable.test( modelSelection, 'selection' ); // Check if `modelSelection` is consumable.
|
|
148
|
+
* modelConsumable.test( modelRange, 'range' ); // Check if `modelRange` is consumable.
|
|
149
|
+
* ```
|
|
150
|
+
*
|
|
151
|
+
* @param item Model item, range or selection to be tested.
|
|
152
|
+
* @param type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.
|
|
153
|
+
* Second colon and everything after will be cut. Passing event name is a safe and good practice.
|
|
154
|
+
* @returns `null` if such consumable was never added, `false` if the consumable values was
|
|
155
|
+
* already consumed or `true` if it was added and not consumed yet.
|
|
156
|
+
*/
|
|
157
|
+
test(item: Item | Selection | DocumentSelection | Range, type: string): boolean | null;
|
|
158
|
+
/**
|
|
159
|
+
* Reverts consuming of a consumable value.
|
|
160
|
+
*
|
|
161
|
+
* ```ts
|
|
162
|
+
* modelConsumable.revert( modelElement, 'insert' ); // Revert consuming `modelElement` insertion change.
|
|
163
|
+
* modelConsumable.revert( modelElement, 'addAttribute:bold' ); // Revert consuming `bold` attribute insert from `modelElement`.
|
|
164
|
+
* modelConsumable.revert( modelElement, 'removeAttribute:bold' ); // Revert consuming `bold` attribute remove from `modelElement`.
|
|
165
|
+
* modelConsumable.revert( modelSelection, 'selection' ); // Revert consuming `modelSelection`.
|
|
166
|
+
* modelConsumable.revert( modelRange, 'range' ); // Revert consuming `modelRange`.
|
|
167
|
+
* ```
|
|
168
|
+
*
|
|
169
|
+
* @param item Model item, range or selection to be reverted.
|
|
170
|
+
* @param type Consumable type.
|
|
171
|
+
* @returns `true` if consumable has been reversed, `false` otherwise. `null` if the consumable has
|
|
172
|
+
* never been added.
|
|
173
|
+
*/
|
|
174
|
+
revert(item: Item | Selection | DocumentSelection | Range, type: string): boolean | null;
|
|
175
|
+
/**
|
|
176
|
+
* Verifies if all events from the specified group were consumed.
|
|
177
|
+
*
|
|
178
|
+
* @param eventGroup The events group to verify.
|
|
179
|
+
*/
|
|
180
|
+
verifyAllConsumed(eventGroup: string): void;
|
|
181
|
+
/**
|
|
182
|
+
* Gets a unique symbol for the passed {@link module:engine/model/textproxy~TextProxy} instance. All `TextProxy` instances that
|
|
183
|
+
* have same parent, same start index and same end index will get the same symbol.
|
|
184
|
+
*
|
|
185
|
+
* Used internally to correctly consume `TextProxy` instances.
|
|
186
|
+
*
|
|
187
|
+
* @internal
|
|
188
|
+
* @param textProxy `TextProxy` instance to get a symbol for.
|
|
189
|
+
* @returns Symbol representing all equal instances of `TextProxy`.
|
|
190
|
+
*/
|
|
191
|
+
_getSymbolForTextProxy(textProxy: TextProxy): symbol;
|
|
192
|
+
/**
|
|
193
|
+
* Adds a symbol for the given {@link module:engine/model/textproxy~TextProxy} instance.
|
|
194
|
+
*
|
|
195
|
+
* Used internally to correctly consume `TextProxy` instances.
|
|
196
|
+
*
|
|
197
|
+
* @param textProxy Text proxy instance.
|
|
198
|
+
* @returns Symbol generated for given `TextProxy`.
|
|
199
|
+
*/
|
|
200
|
+
private _addSymbolForTextProxy;
|
|
201
|
+
}
|