@ckeditor/ckeditor5-engine 35.3.2 → 36.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.
Files changed (123) hide show
  1. package/LICENSE.md +1 -1
  2. package/package.json +22 -22
  3. package/src/controller/datacontroller.js +10 -8
  4. package/src/controller/editingcontroller.js +3 -4
  5. package/src/conversion/conversion.js +2 -3
  6. package/src/conversion/conversionhelpers.js +1 -1
  7. package/src/conversion/downcastdispatcher.js +3 -3
  8. package/src/conversion/downcasthelpers.js +2 -3
  9. package/src/conversion/mapper.js +3 -4
  10. package/src/conversion/modelconsumable.js +2 -2
  11. package/src/conversion/upcastdispatcher.js +3 -4
  12. package/src/conversion/upcasthelpers.js +10 -3
  13. package/src/conversion/viewconsumable.js +2 -2
  14. package/src/dataprocessor/basichtmlwriter.js +1 -1
  15. package/src/dataprocessor/dataprocessor.js +1 -1
  16. package/src/dataprocessor/htmldataprocessor.js +3 -3
  17. package/src/dataprocessor/htmlwriter.js +1 -1
  18. package/src/dataprocessor/xmldataprocessor.js +6 -2
  19. package/src/dev-utils/model.js +3 -3
  20. package/src/dev-utils/operationreplayer.js +1 -1
  21. package/src/dev-utils/utils.js +1 -1
  22. package/src/dev-utils/view.js +1 -1
  23. package/src/index.js +13 -3
  24. package/src/model/batch.js +10 -47
  25. package/src/model/differ.js +81 -174
  26. package/src/model/document.js +38 -97
  27. package/src/model/documentfragment.js +44 -97
  28. package/src/model/documentselection.js +152 -251
  29. package/src/model/element.js +48 -101
  30. package/src/model/history.js +15 -46
  31. package/src/model/item.js +1 -1
  32. package/src/model/liveposition.js +11 -39
  33. package/src/model/liverange.js +14 -38
  34. package/src/model/markercollection.js +42 -115
  35. package/src/model/model.js +214 -292
  36. package/src/model/node.js +36 -128
  37. package/src/model/nodelist.js +12 -41
  38. package/src/model/operation/attributeoperation.js +14 -45
  39. package/src/model/operation/detachoperation.js +4 -17
  40. package/src/model/operation/insertoperation.js +7 -35
  41. package/src/model/operation/markeroperation.js +9 -48
  42. package/src/model/operation/mergeoperation.js +9 -42
  43. package/src/model/operation/moveoperation.js +15 -39
  44. package/src/model/operation/nooperation.js +1 -7
  45. package/src/model/operation/operation.js +5 -63
  46. package/src/model/operation/operationfactory.js +3 -6
  47. package/src/model/operation/renameoperation.js +9 -29
  48. package/src/model/operation/rootattributeoperation.js +19 -48
  49. package/src/model/operation/splitoperation.js +10 -48
  50. package/src/model/operation/transform.js +110 -151
  51. package/src/model/operation/utils.js +37 -52
  52. package/src/model/position.js +118 -230
  53. package/src/model/range.js +146 -202
  54. package/src/model/rootelement.js +8 -47
  55. package/src/model/schema.js +245 -282
  56. package/src/model/selection.js +135 -196
  57. package/src/model/text.js +10 -37
  58. package/src/model/textproxy.js +16 -70
  59. package/src/model/treewalker.js +11 -102
  60. package/src/model/typecheckable.js +1 -1
  61. package/src/model/utils/autoparagraphing.js +11 -12
  62. package/src/model/utils/deletecontent.js +93 -62
  63. package/src/model/utils/findoptimalinsertionrange.js +25 -25
  64. package/src/model/utils/getselectedcontent.js +3 -6
  65. package/src/model/utils/insertcontent.js +37 -130
  66. package/src/model/utils/insertobject.js +40 -40
  67. package/src/model/utils/modifyselection.js +24 -34
  68. package/src/model/utils/selection-post-fixer.js +53 -59
  69. package/src/model/writer.js +209 -316
  70. package/src/view/attributeelement.js +2 -2
  71. package/src/view/containerelement.js +1 -1
  72. package/src/view/datatransfer.js +1 -1
  73. package/src/view/document.js +3 -5
  74. package/src/view/documentfragment.js +50 -4
  75. package/src/view/documentselection.js +2 -3
  76. package/src/view/domconverter.js +4 -8
  77. package/src/view/downcastwriter.js +2 -3
  78. package/src/view/editableelement.js +2 -3
  79. package/src/view/element.js +6 -8
  80. package/src/view/elementdefinition.js +1 -1
  81. package/src/view/emptyelement.js +2 -2
  82. package/src/view/filler.js +2 -3
  83. package/src/view/item.js +1 -1
  84. package/src/view/matcher.js +2 -2
  85. package/src/view/node.js +2 -5
  86. package/src/view/observer/arrowkeysobserver.js +1 -1
  87. package/src/view/observer/bubblingemittermixin.js +3 -6
  88. package/src/view/observer/bubblingeventinfo.js +2 -2
  89. package/src/view/observer/clickobserver.js +1 -1
  90. package/src/view/observer/compositionobserver.js +1 -1
  91. package/src/view/observer/domeventdata.js +1 -1
  92. package/src/view/observer/domeventobserver.js +1 -1
  93. package/src/view/observer/fakeselectionobserver.js +2 -2
  94. package/src/view/observer/focusobserver.js +25 -3
  95. package/src/view/observer/inputobserver.js +2 -2
  96. package/src/view/observer/keyobserver.js +2 -2
  97. package/src/view/observer/mouseobserver.js +1 -1
  98. package/src/view/observer/mutationobserver.js +1 -1
  99. package/src/view/observer/observer.js +3 -3
  100. package/src/view/observer/selectionobserver.js +21 -3
  101. package/src/view/observer/tabobserver.js +2 -2
  102. package/src/view/placeholder.js +1 -1
  103. package/src/view/position.js +2 -3
  104. package/src/view/range.js +1 -1
  105. package/src/view/rawelement.js +2 -2
  106. package/src/view/renderer.js +3 -12
  107. package/src/view/rooteditableelement.js +1 -1
  108. package/src/view/selection.js +2 -6
  109. package/src/view/styles/background.js +1 -1
  110. package/src/view/styles/border.js +1 -1
  111. package/src/view/styles/margin.js +1 -1
  112. package/src/view/styles/padding.js +1 -1
  113. package/src/view/styles/utils.js +1 -1
  114. package/src/view/stylesmap.js +1 -1
  115. package/src/view/text.js +1 -1
  116. package/src/view/textproxy.js +2 -2
  117. package/src/view/treewalker.js +2 -2
  118. package/src/view/typecheckable.js +1 -1
  119. package/src/view/uielement.js +2 -3
  120. package/src/view/upcastwriter.js +1 -1
  121. package/src/view/view.js +7 -7
  122. package/theme/placeholder.css +1 -1
  123. package/theme/renderer.css +1 -1
@@ -1,8 +1,7 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
- /* eslint-disable new-cap */
6
5
  /**
7
6
  * @module engine/model/documentselection
8
7
  */
@@ -11,11 +10,7 @@ import LiveRange from './liverange';
11
10
  import Selection from './selection';
12
11
  import Text from './text';
13
12
  import TextProxy from './textproxy';
14
- import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
15
- import Collection from '@ckeditor/ckeditor5-utils/src/collection';
16
- import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
17
- import toMap from '@ckeditor/ckeditor5-utils/src/tomap';
18
- import uid from '@ckeditor/ckeditor5-utils/src/uid';
13
+ import { CKEditorError, Collection, EmitterMixin, toMap, uid } from '@ckeditor/ckeditor5-utils';
19
14
  const storePrefix = 'selection:';
20
15
  /**
21
16
  * `DocumentSelection` is a special selection which is used as the
@@ -40,33 +35,23 @@ const storePrefix = 'selection:';
40
35
  * that are inside {@link module:engine/model/documentfragment~DocumentFragment document fragment}.
41
36
  * If you need to represent a selection in document fragment,
42
37
  * use {@link module:engine/model/selection~Selection Selection class} instead.
43
- *
44
- * @mixes module:utils/emittermixin~EmitterMixin
45
38
  */
46
39
  export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
47
40
  /**
48
41
  * Creates an empty live selection for given {@link module:engine/model/document~Document}.
49
42
  *
50
- * @param {module:engine/model/document~Document} doc Document which owns this selection.
43
+ * @param doc Document which owns this selection.
51
44
  */
52
45
  constructor(doc) {
53
46
  super();
54
- /**
55
- * Selection used internally by that class (`DocumentSelection` is a proxy to that selection).
56
- *
57
- * @protected
58
- */
59
47
  this._selection = new LiveSelection(doc);
60
48
  this._selection.delegate('change:range').to(this);
61
49
  this._selection.delegate('change:attribute').to(this);
62
50
  this._selection.delegate('change:marker').to(this);
63
51
  }
64
52
  /**
65
- * Returns whether the selection is collapsed. Selection is collapsed when there is exactly one range which is
53
+ * Describes whether the selection is collapsed. Selection is collapsed when there is exactly one range which is
66
54
  * collapsed.
67
- *
68
- * @readonly
69
- * @type {Boolean}
70
55
  */
71
56
  get isCollapsed() {
72
57
  return this._selection.isCollapsed;
@@ -80,8 +65,6 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
80
65
  * Is set to `null` if there are no ranges in selection.
81
66
  *
82
67
  * @see #focus
83
- * @readonly
84
- * @type {module:engine/model/position~Position|null}
85
68
  */
86
69
  get anchor() {
87
70
  return this._selection.anchor;
@@ -92,17 +75,12 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
92
75
  * Is set to `null` if there are no ranges in selection.
93
76
  *
94
77
  * @see #anchor
95
- * @readonly
96
- * @type {module:engine/model/position~Position|null}
97
78
  */
98
79
  get focus() {
99
80
  return this._selection.focus;
100
81
  }
101
82
  /**
102
- * Returns number of ranges in selection.
103
- *
104
- * @readonly
105
- * @type {Number}
83
+ * Number of ranges in selection.
106
84
  */
107
85
  get rangeCount() {
108
86
  return this._selection.rangeCount;
@@ -110,9 +88,6 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
110
88
  /**
111
89
  * Describes whether `Documentselection` has own range(s) set, or if it is defaulted to
112
90
  * {@link module:engine/model/document~Document#_getDefaultRange document's default range}.
113
- *
114
- * @readonly
115
- * @type {Boolean}
116
91
  */
117
92
  get hasOwnRange() {
118
93
  return this._selection.hasOwnRange;
@@ -131,9 +106,6 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
131
106
  * Describes whether the gravity is overridden (using {@link module:engine/model/writer~Writer#overrideSelectionGravity}) or not.
132
107
  *
133
108
  * Note that the gravity remains overridden as long as will not be restored the same number of times as it was overridden.
134
- *
135
- * @readonly
136
- * @returns {Boolean}
137
109
  */
138
110
  get isGravityOverridden() {
139
111
  return this._selection.isGravityOverridden;
@@ -143,9 +115,6 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
143
115
  * Marker is a selection marker when selection range is inside the marker range.
144
116
  *
145
117
  * **Note**: Only markers from {@link ~DocumentSelection#observeMarkers observed markers groups} are collected.
146
- *
147
- * @readonly
148
- * @type {module:utils/collection~Collection}
149
118
  */
150
119
  get markers() {
151
120
  return this._selection.markers;
@@ -154,15 +123,12 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
154
123
  * Used for the compatibility with the {@link module:engine/model/selection~Selection#isEqual} method.
155
124
  *
156
125
  * @internal
157
- * @protected
158
126
  */
159
127
  get _ranges() {
160
128
  return this._selection._ranges;
161
129
  }
162
130
  /**
163
131
  * Returns an iterable that iterates over copies of selection ranges.
164
- *
165
- * @returns {Iterable.<module:engine/model/range~Range>}
166
132
  */
167
133
  getRanges() {
168
134
  return this._selection.getRanges();
@@ -173,8 +139,6 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
173
139
  * any other position in the selection.
174
140
  *
175
141
  * Returns `null` if there are no ranges in selection.
176
- *
177
- * @returns {module:engine/model/position~Position|null}
178
142
  */
179
143
  getFirstPosition() {
180
144
  return this._selection.getFirstPosition();
@@ -185,8 +149,6 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
185
149
  * any other position in the selection.
186
150
  *
187
151
  * Returns `null` if there are no ranges in selection.
188
- *
189
- * @returns {module:engine/model/position~Position|null}
190
152
  */
191
153
  getLastPosition() {
192
154
  return this._selection.getLastPosition();
@@ -198,8 +160,6 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
198
160
  * (not to confuse with the first range added to the selection).
199
161
  *
200
162
  * Returns `null` if there are no ranges in selection.
201
- *
202
- * @returns {module:engine/model/range~Range|null}
203
163
  */
204
164
  getFirstRange() {
205
165
  return this._selection.getFirstRange();
@@ -211,8 +171,6 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
211
171
  * recently added to the selection).
212
172
  *
213
173
  * Returns `null` if there are no ranges in selection.
214
- *
215
- * @returns {module:engine/model/range~Range|null}
216
174
  */
217
175
  getLastRange() {
218
176
  return this._selection.getLastRange();
@@ -227,40 +185,48 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
227
185
  *
228
186
  * In this case the function will return exactly all 3 paragraphs (note: `<blockQuote>` is not a block itself):
229
187
  *
230
- * <paragraph>[a</paragraph>
231
- * <blockQuote>
232
- * <paragraph>b</paragraph>
233
- * </blockQuote>
234
- * <paragraph>c]d</paragraph>
188
+ * ```
189
+ * <paragraph>[a</paragraph>
190
+ * <blockQuote>
191
+ * <paragraph>b</paragraph>
192
+ * </blockQuote>
193
+ * <paragraph>c]d</paragraph>
194
+ * ```
235
195
  *
236
196
  * In this case the paragraph will also be returned, despite the collapsed selection:
237
197
  *
238
- * <paragraph>[]a</paragraph>
198
+ * ```
199
+ * <paragraph>[]a</paragraph>
200
+ * ```
239
201
  *
240
202
  * In such a scenario, however, only blocks A, B & E will be returned as blocks C & D are nested in block B:
241
203
  *
242
- * [<blockA></blockA>
243
- * <blockB>
244
- * <blockC></blockC>
245
- * <blockD></blockD>
246
- * </blockB>
247
- * <blockE></blockE>]
204
+ * ```
205
+ * [<blockA></blockA>
206
+ * <blockB>
207
+ * <blockC></blockC>
208
+ * <blockD></blockD>
209
+ * </blockB>
210
+ * <blockE></blockE>]
211
+ * ```
248
212
  *
249
213
  * If the selection is inside a block all the inner blocks (A & B) are returned:
250
214
  *
251
- * <block>
252
- * <blockA>[a</blockA>
253
- * <blockB>b]</blockB>
254
- * </block>
215
+ * ```
216
+ * <block>
217
+ * <blockA>[a</blockA>
218
+ * <blockB>b]</blockB>
219
+ * </block>
220
+ * ```
255
221
  *
256
222
  * **Special case**: If a selection ends at the beginning of a block, that block is not returned as from user perspective
257
223
  * this block wasn't selected. See [#984](https://github.com/ckeditor/ckeditor5-engine/issues/984) for more details.
258
224
  *
259
- * <paragraph>[a</paragraph>
260
- * <paragraph>b</paragraph>
261
- * <paragraph>]c</paragraph> // this block will not be returned
262
- *
263
- * @returns {Iterable.<module:engine/model/element~Element>}
225
+ * ```
226
+ * <paragraph>[a</paragraph>
227
+ * <paragraph>b</paragraph>
228
+ * <paragraph>]c</paragraph> // this block will not be returned
229
+ * ```
264
230
  */
265
231
  getSelectedBlocks() {
266
232
  return this._selection.getSelectedBlocks();
@@ -269,8 +235,6 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
269
235
  * Returns the selected element. {@link module:engine/model/element~Element Element} is considered as selected if there is only
270
236
  * one range in the selection, and that range contains exactly one element.
271
237
  * Returns `null` if there is no selected element.
272
- *
273
- * @returns {module:engine/model/element~Element|null}
274
238
  */
275
239
  getSelectedElement() {
276
240
  return this._selection.getSelectedElement();
@@ -282,9 +246,6 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
282
246
  *
283
247
  * By default, this method will check whether the entire content of the selection's current root is selected.
284
248
  * Useful to check if e.g. the user has just pressed <kbd>Ctrl</kbd> + <kbd>A</kbd>.
285
- *
286
- * @param {module:engine/model/element~Element} [element=this.anchor.root]
287
- * @returns {Boolean}
288
249
  */
289
250
  containsEntireContent(element) {
290
251
  return this._selection.containsEntireContent(element);
@@ -297,8 +258,6 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
297
258
  }
298
259
  /**
299
260
  * Returns iterable that iterates over this selection's attribute keys.
300
- *
301
- * @returns {Iterable.<String>}
302
261
  */
303
262
  getAttributeKeys() {
304
263
  return this._selection.getAttributeKeys();
@@ -308,8 +267,6 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
308
267
  *
309
268
  * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.
310
269
  * This format is accepted by native `Map` object and also can be passed in `Node` constructor.
311
- *
312
- * @returns {Iterable.<*>}
313
270
  */
314
271
  getAttributes() {
315
272
  return this._selection.getAttributes();
@@ -317,8 +274,8 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
317
274
  /**
318
275
  * Gets an attribute value for given key or `undefined` if that attribute is not set on the selection.
319
276
  *
320
- * @param {String} key Key of attribute to look for.
321
- * @returns {*} Attribute value or `undefined`.
277
+ * @param key Key of attribute to look for.
278
+ * @returns Attribute value or `undefined`.
322
279
  */
323
280
  getAttribute(key) {
324
281
  return this._selection.getAttribute(key);
@@ -326,8 +283,8 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
326
283
  /**
327
284
  * Checks if the selection has an attribute for given key.
328
285
  *
329
- * @param {String} key Key of attribute to check.
330
- * @returns {Boolean} `true` if attribute with given key is set on selection, `false` otherwise.
286
+ * @param key Key of attribute to check.
287
+ * @returns `true` if attribute with given key is set on selection, `false` otherwise.
331
288
  */
332
289
  hasAttribute(key) {
333
290
  return this._selection.hasAttribute(key);
@@ -345,7 +302,7 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
345
302
  *
346
303
  * See also {@link module:engine/model/markercollection~MarkerCollection#getMarkersGroup `MarkerCollection#getMarkersGroup()`}.
347
304
  *
348
- * @param {String} prefixOrName The marker group prefix or marker name.
305
+ * @param prefixOrName The marker group prefix or marker name.
349
306
  */
350
307
  observeMarkers(prefixOrName) {
351
308
  this._selection.observeMarkers(prefixOrName);
@@ -359,9 +316,7 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
359
316
  *
360
317
  * @see module:engine/model/writer~Writer#setSelectionFocus
361
318
  * @internal
362
- * @protected
363
- * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition
364
- * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when
319
+ * @param offset Offset or one of the flags. Used only when
365
320
  * first parameter is a {@link module:engine/model/item~Item model item}.
366
321
  */
367
322
  _setFocus(itemOrPosition, offset) {
@@ -374,11 +329,6 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
374
329
  *
375
330
  * @see module:engine/model/writer~Writer#setSelection
376
331
  * @internal
377
- * @protected
378
- * @param {module:engine/model/selection~Selectable} selectable
379
- * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.
380
- * @param {Object} [options]
381
- * @param {Boolean} [options.backward] Sets this selection instance to be backward.
382
332
  */
383
333
  _setTo(...args) {
384
334
  this._selection.setTo(...args);
@@ -389,9 +339,8 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
389
339
  *
390
340
  * @see module:engine/model/writer~Writer#setSelectionAttribute
391
341
  * @internal
392
- * @protected
393
- * @param {String} key Key of the attribute to set.
394
- * @param {*} value Attribute value.
342
+ * @param key Key of the attribute to set.
343
+ * @param value Attribute value.
395
344
  */
396
345
  _setAttribute(key, value) {
397
346
  this._selection.setAttribute(key, value);
@@ -404,8 +353,7 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
404
353
  *
405
354
  * @see module:engine/model/writer~Writer#removeSelectionAttribute
406
355
  * @internal
407
- * @protected
408
- * @param {String} key Key of the attribute to remove.
356
+ * @param key Key of the attribute to remove.
409
357
  */
410
358
  _removeAttribute(key) {
411
359
  this._selection.removeAttribute(key);
@@ -413,8 +361,7 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
413
361
  /**
414
362
  * Returns an iterable that iterates through all selection attributes stored in current selection's parent.
415
363
  *
416
- * @protected
417
- * @returns {Iterable.<*>}
364
+ * @internal
418
365
  */
419
366
  _getStoredAttributes() {
420
367
  return this._selection.getStoredAttributes();
@@ -431,8 +378,7 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
431
378
  *
432
379
  * @see module:engine/model/writer~Writer#overrideSelectionGravity
433
380
  * @internal
434
- * @protected
435
- * @returns {String} The unique id which allows restoring the gravity.
381
+ * @returns The unique id which allows restoring the gravity.
436
382
  */
437
383
  _overrideGravity() {
438
384
  return this._selection.overrideGravity();
@@ -446,8 +392,7 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
446
392
  *
447
393
  * @see module:engine/model/writer~Writer#restoreSelectionGravity
448
394
  * @internal
449
- * @protected
450
- * @param {String} uid The unique id returned by {@link #_overrideGravity}.
395
+ * @param uid The unique id returned by {@link #_overrideGravity}.
451
396
  */
452
397
  _restoreGravity(uid) {
453
398
  this._selection.restoreGravity(uid);
@@ -456,9 +401,8 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
456
401
  * Generates and returns an attribute key for selection attributes store, basing on original attribute key.
457
402
  *
458
403
  * @internal
459
- * @protected
460
- * @param {String} key Attribute key to convert.
461
- * @returns {String} Converted attribute key, applicable for selection store.
404
+ * @param key Attribute key to convert.
405
+ * @returns Converted attribute key, applicable for selection store.
462
406
  */
463
407
  static _getStoreAttributeKey(key) {
464
408
  return storePrefix + key;
@@ -466,98 +410,74 @@ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
466
410
  /**
467
411
  * Checks whether the given attribute key is an attribute stored on an element.
468
412
  *
469
- * @protected
470
- * @param {String} key
471
- * @returns {Boolean}
413
+ * @internal
472
414
  */
473
415
  static _isStoreAttributeKey(key) {
474
416
  return key.startsWith(storePrefix);
475
417
  }
476
418
  }
477
- /**
478
- * Checks whether this object is of the given type.
479
- *
480
- * selection.is( 'selection' ); // -> true
481
- * selection.is( 'documentSelection' ); // -> true
482
- * selection.is( 'model:selection' ); // -> true
483
- * selection.is( 'model:documentSelection' ); // -> true
484
- *
485
- * selection.is( 'view:selection' ); // -> false
486
- * selection.is( 'element' ); // -> false
487
- * selection.is( 'node' ); // -> false
488
- *
489
- * {@link module:engine/model/node~Node#is Check the entire list of model objects} which implement the `is()` method.
490
- *
491
- * @param {String} type
492
- * @returns {Boolean}
493
- */
419
+ // The magic of type inference using `is` method is centralized in `TypeCheckable` class.
420
+ // Proper overload would interfere with that.
494
421
  DocumentSelection.prototype.is = function (type) {
495
422
  return type === 'selection' ||
496
423
  type == 'model:selection' ||
497
424
  type == 'documentSelection' ||
498
425
  type == 'model:documentSelection';
499
426
  };
500
- // `LiveSelection` is used internally by {@link module:engine/model/documentselection~DocumentSelection} and shouldn't be used directly.
501
- //
502
- // LiveSelection` is automatically updated upon changes in the {@link module:engine/model/document~Document document}
503
- // to always contain valid ranges. Its attributes are inherited from the text unless set explicitly.
504
- //
505
- // Differences between {@link module:engine/model/selection~Selection} and `LiveSelection` are:
506
- // * there is always a range in `LiveSelection` - even if no ranges were added there is a "default range"
507
- // present in the selection,
508
- // * ranges added to this selection updates automatically when the document changes,
509
- // * attributes of `LiveSelection` are updated automatically according to selection ranges.
510
- //
511
- // @extends module:engine/model/selection~Selection
512
- //
427
+ /**
428
+ * `LiveSelection` is used internally by {@link module:engine/model/documentselection~DocumentSelection} and shouldn't be used directly.
429
+ *
430
+ * LiveSelection` is automatically updated upon changes in the {@link module:engine/model/document~Document document}
431
+ * to always contain valid ranges. Its attributes are inherited from the text unless set explicitly.
432
+ *
433
+ * Differences between {@link module:engine/model/selection~Selection} and `LiveSelection` are:
434
+ * * there is always a range in `LiveSelection` - even if no ranges were added there is a "default range"
435
+ * present in the selection,
436
+ * * ranges added to this selection updates automatically when the document changes,
437
+ * * attributes of `LiveSelection` are updated automatically according to selection ranges.
438
+ */
513
439
  class LiveSelection extends Selection {
514
- // Creates an empty live selection for given {@link module:engine/model/document~Document}.
515
- // @param {module:engine/model/document~Document} doc Document which owns this selection.
440
+ /**
441
+ * Creates an empty live selection for given {@link module:engine/model/document~Document}.
442
+ *
443
+ * @param doc Document which owns this selection.
444
+ */
516
445
  constructor(doc) {
517
446
  super();
518
- // List of selection markers.
519
- // Marker is a selection marker when selection range is inside the marker range.
520
- //
521
- // @type {module:utils/collection~Collection}
447
+ /**
448
+ * List of selection markers.
449
+ * Marker is a selection marker when selection range is inside the marker range.
450
+ */
522
451
  this.markers = new Collection({ idProperty: 'name' });
523
- // Document which owns this selection.
524
- //
525
- // @protected
526
- // @member {module:engine/model/model~Model}
527
- this._model = doc.model;
528
- // Document which owns this selection.
529
- //
530
- // @protected
531
- // @member {module:engine/model/document~Document}
532
- this._document = doc;
533
- // Keeps mapping of attribute name to priority with which the attribute got modified (added/changed/removed)
534
- // last time. Possible values of priority are: `'low'` and `'normal'`.
535
- //
536
- // Priorities are used by internal `LiveSelection` mechanisms. All attributes set using `LiveSelection`
537
- // attributes API are set with `'normal'` priority.
538
- //
539
- // @private
540
- // @member {Map} module:engine/model/liveselection~LiveSelection#_attributePriority
452
+ /**
453
+ * Keeps mapping of attribute name to priority with which the attribute got modified (added/changed/removed)
454
+ * last time. Possible values of priority are: `'low'` and `'normal'`.
455
+ *
456
+ * Priorities are used by internal `LiveSelection` mechanisms. All attributes set using `LiveSelection`
457
+ * attributes API are set with `'normal'` priority.
458
+ */
541
459
  this._attributePriority = new Map();
542
- // Position to which the selection should be set if the last selection range was moved to the graveyard.
543
- // @private
544
- // @member {module:engine/model/position~Position} module:engine/model/liveselection~LiveSelection#_selectionRestorePosition
460
+ /**
461
+ * Position to which the selection should be set if the last selection range was moved to the graveyard.
462
+ */
545
463
  this._selectionRestorePosition = null;
546
- // Flag that informs whether the selection ranges have changed. It is changed on true when `LiveRange#change:range` event is fired.
547
- // @private
548
- // @member {Array} module:engine/model/liveselection~LiveSelection#_hasChangedRange
464
+ /**
465
+ * Flag that informs whether the selection ranges have changed. It is changed on true when `LiveRange#change:range` event is fired.
466
+ */
549
467
  this._hasChangedRange = false;
550
- // Each overriding gravity adds an UID to the set and each removal removes it.
551
- // Gravity is overridden when there's at least one UID in the set.
552
- // Gravity is restored when the set is empty.
553
- // This is to prevent conflicts when gravity is overridden by more than one feature at the same time.
554
- // @private
555
- // @type {Set}
468
+ /**
469
+ * Each overriding gravity adds an UID to the set and each removal removes it.
470
+ * Gravity is overridden when there's at least one UID in the set.
471
+ * Gravity is restored when the set is empty.
472
+ * This is to prevent conflicts when gravity is overridden by more than one feature at the same time.
473
+ */
556
474
  this._overriddenGravityRegister = new Set();
557
- // Prefixes of marker names that should affect `LiveSelection#markers` collection.
558
- // @private
559
- // @type {Set}
475
+ /**
476
+ * Prefixes of marker names that should affect `LiveSelection#markers` collection.
477
+ */
560
478
  this._observedMarkers = new Set();
479
+ this._model = doc.model;
480
+ this._document = doc;
561
481
  // Ensure selection is correct after each operation.
562
482
  this.listenTo(this._model, 'applyOperation', (evt, args) => {
563
483
  const operation = args[0];
@@ -602,23 +522,23 @@ class LiveSelection extends Selection {
602
522
  get rangeCount() {
603
523
  return this._ranges.length ? this._ranges.length : 1;
604
524
  }
605
- // Describes whether `LiveSelection` has own range(s) set, or if it is defaulted to
606
- // {@link module:engine/model/document~Document#_getDefaultRange document's default range}.
607
- //
608
- // @readonly
609
- // @type {Boolean}
525
+ /**
526
+ * Describes whether `LiveSelection` has own range(s) set, or if it is defaulted to
527
+ * {@link module:engine/model/document~Document#_getDefaultRange document's default range}.
528
+ */
610
529
  get hasOwnRange() {
611
530
  return this._ranges.length > 0;
612
531
  }
613
- // When set to `true` then selection attributes on node before the caret won't be taken
614
- // into consideration while updating selection attributes.
615
- //
616
- // @protected
617
- // @type {Boolean}
532
+ /**
533
+ * When set to `true` then selection attributes on node before the caret won't be taken
534
+ * into consideration while updating selection attributes.
535
+ */
618
536
  get isGravityOverridden() {
619
537
  return !!this._overriddenGravityRegister.size;
620
538
  }
621
- // Unbinds all events previously bound by live selection.
539
+ /**
540
+ * Unbinds all events previously bound by live selection.
541
+ */
622
542
  destroy() {
623
543
  for (let i = 0; i < this._ranges.length; i++) {
624
544
  this._ranges[i].detach();
@@ -680,7 +600,7 @@ class LiveSelection extends Selection {
680
600
  * UID obtained from the {@link module:engine/model/writer~Writer#overrideSelectionGravity} to restore.
681
601
  *
682
602
  * @error document-selection-gravity-wrong-restore
683
- * @param {String} uid The unique identifier returned by
603
+ * @param uid The unique identifier returned by
684
604
  * {@link module:engine/model/documentselection~DocumentSelection#_overrideGravity}.
685
605
  */
686
606
  throw new CKEditorError('document-selection-gravity-wrong-restore', this, { uid });
@@ -717,18 +637,17 @@ class LiveSelection extends Selection {
717
637
  * starts or ends at incorrect position.
718
638
  *
719
639
  * @error document-selection-wrong-position
720
- * @param {module:engine/model/range~Range} range
640
+ * @param range
721
641
  */
722
642
  throw new CKEditorError('document-selection-wrong-position', this, { range });
723
643
  }
724
644
  }
725
645
  }
726
- // Prepares given range to be added to selection. Checks if it is correct,
727
- // converts it to {@link module:engine/model/liverange~LiveRange LiveRange}
728
- // and sets listeners listening to the range's change event.
729
- //
730
- // @private
731
- // @param {module:engine/model/range~Range} range
646
+ /**
647
+ * Prepares given range to be added to selection. Checks if it is correct,
648
+ * converts it to {@link module:engine/model/liverange~LiveRange LiveRange}
649
+ * and sets listeners listening to the range's change event.
650
+ */
732
651
  _prepareRange(range) {
733
652
  this._checkRange(range);
734
653
  if (range.root == this._document.graveyard) {
@@ -819,11 +738,9 @@ class LiveSelection extends Selection {
819
738
  this.fire('change:marker', { oldMarkers, directChange: false });
820
739
  }
821
740
  }
822
- // Updates this selection attributes according to its ranges and the {@link module:engine/model/document~Document model document}.
823
- //
824
- // @protected
825
- // @param {Boolean} clearAll
826
- // @fires change:attribute
741
+ /**
742
+ * Updates this selection attributes according to its ranges and the {@link module:engine/model/document~Document model document}.
743
+ */
827
744
  _updateAttributes(clearAll) {
828
745
  const newAttributes = toMap(this._getSurroundingAttributes());
829
746
  const oldAttributes = toMap(this.getAttributes());
@@ -862,15 +779,10 @@ class LiveSelection extends Selection {
862
779
  this.fire('change:attribute', { attributeKeys: changed, directChange: false });
863
780
  }
864
781
  }
865
- // Internal method for setting `LiveSelection` attribute. Supports attribute priorities (through `directChange`
866
- // parameter).
867
- //
868
- // @private
869
- // @param {String} key Attribute key.
870
- // @param {*} value Attribute value.
871
- // @param {Boolean} [directChange=true] `true` if the change is caused by `Selection` API, `false` if change
872
- // is caused by `Batch` API.
873
- // @returns {Boolean} Whether value has changed.
782
+ /**
783
+ * Internal method for setting `LiveSelection` attribute. Supports attribute priorities (through `directChange`
784
+ * parameter).
785
+ */
874
786
  _setAttribute(key, value, directChange = true) {
875
787
  const priority = directChange ? 'normal' : 'low';
876
788
  if (priority == 'low' && this._attributePriority.get(key) == 'normal') {
@@ -887,18 +799,13 @@ class LiveSelection extends Selection {
887
799
  this._attributePriority.set(key, priority);
888
800
  return true;
889
801
  }
890
- // Internal method for removing `LiveSelection` attribute. Supports attribute priorities (through `directChange`
891
- // parameter).
892
- //
893
- // NOTE: Even if attribute is not present in the selection but is provided to this method, it's priority will
894
- // be changed according to `directChange` parameter.
895
- //
896
- // @private
897
- // @param {String} key Attribute key.
898
- // @param {Boolean} [directChange=true] `true` if the change is caused by `Selection` API, `false` if change
899
- // is caused by `Batch` API.
900
- // @returns {Boolean} Whether attribute was removed. May not be true if such attributes didn't exist or the
901
- // existing attribute had higher priority.
802
+ /**
803
+ * Internal method for removing `LiveSelection` attribute. Supports attribute priorities (through `directChange`
804
+ * parameter).
805
+ *
806
+ * NOTE: Even if attribute is not present in the selection but is provided to this method, it's priority will
807
+ * be changed according to `directChange` parameter.
808
+ */
902
809
  _removeAttribute(key, directChange = true) {
903
810
  const priority = directChange ? 'normal' : 'low';
904
811
  if (priority == 'low' && this._attributePriority.get(key) == 'normal') {
@@ -914,12 +821,10 @@ class LiveSelection extends Selection {
914
821
  this._attrs.delete(key);
915
822
  return true;
916
823
  }
917
- // Internal method for setting multiple `LiveSelection` attributes. Supports attribute priorities (through
918
- // `directChange` parameter).
919
- //
920
- // @private
921
- // @param {Map.<String,*>} attrs Iterable object containing attributes to be set.
922
- // @returns {Set.<String>} Changed attribute keys.
824
+ /**
825
+ * Internal method for setting multiple `LiveSelection` attributes. Supports attribute priorities (through
826
+ * `directChange` parameter).
827
+ */
923
828
  _setAttributesTo(attrs) {
924
829
  const changed = new Set();
925
830
  for (const [oldKey, oldValue] of this.getAttributes()) {
@@ -939,10 +844,9 @@ class LiveSelection extends Selection {
939
844
  }
940
845
  return changed;
941
846
  }
942
- // Returns an iterable that iterates through all selection attributes stored in current selection's parent.
943
- //
944
- // @public
945
- // @returns {Iterable.<*>}
847
+ /**
848
+ * Returns an iterable that iterates through all selection attributes stored in current selection's parent.
849
+ */
946
850
  *getStoredAttributes() {
947
851
  const selectionParent = this.getFirstPosition().parent;
948
852
  if (this.isCollapsed && selectionParent.isEmpty) {
@@ -954,12 +858,11 @@ class LiveSelection extends Selection {
954
858
  }
955
859
  }
956
860
  }
957
- // Checks model text nodes that are closest to the selection's first position and returns attributes of first
958
- // found element. If there are no text nodes in selection's first position parent, it returns selection
959
- // attributes stored in that parent.
960
- //
961
- // @private
962
- // @returns {Iterable.<*>} Collection of attributes.
861
+ /**
862
+ * Checks model text nodes that are closest to the selection's first position and returns attributes of first
863
+ * found element. If there are no text nodes in selection's first position parent, it returns selection
864
+ * attributes stored in that parent.
865
+ */
963
866
  _getSurroundingAttributes() {
964
867
  const position = this.getFirstPosition();
965
868
  const schema = this._model.schema;
@@ -1016,10 +919,10 @@ class LiveSelection extends Selection {
1016
919
  }
1017
920
  return attrs;
1018
921
  }
1019
- // Fixes the selection after all its ranges got removed.
1020
- //
1021
- // @private
1022
- // @param {module:engine/model/position~Position} deletionPosition Position where the deletion happened.
922
+ /**
923
+ * Fixes the selection after all its ranges got removed.
924
+ * @param deletionPosition Position where the deletion happened.
925
+ */
1023
926
  _fixGraveyardSelection(deletionPosition) {
1024
927
  // Find a range that is a correct selection range and is closest to the position where the deletion happened.
1025
928
  const selectionRange = this._model.schema.getNearestSelectionRange(deletionPosition);
@@ -1031,22 +934,20 @@ class LiveSelection extends Selection {
1031
934
  // If nearest valid selection range cannot be found don't add any range. Selection will be set to the default range.
1032
935
  }
1033
936
  }
1034
- // Helper function for {@link module:engine/model/liveselection~LiveSelection#_updateAttributes}.
1035
- //
1036
- // It takes model item, checks whether it is a text node (or text proxy) and, if so, returns it's attributes. If not, returns `null`.
1037
- //
1038
- // @param {module:engine/model/item~Item|null} node
1039
- // @returns {Boolean}
937
+ /**
938
+ * Helper function for {@link module:engine/model/liveselection~LiveSelection#_updateAttributes}.
939
+ *
940
+ * It takes model item, checks whether it is a text node (or text proxy) and, if so, returns it's attributes. If not, returns `null`.
941
+ */
1040
942
  function getAttrsIfCharacter(node) {
1041
943
  if (node instanceof TextProxy || node instanceof Text) {
1042
944
  return node.getAttributes();
1043
945
  }
1044
946
  return null;
1045
947
  }
1046
- // Removes selection attributes from element which is not empty anymore.
1047
- //
1048
- // @param {module:engine/model/model~Model} model
1049
- // @param {module:engine/model/batch~Batch} batch
948
+ /**
949
+ * Removes selection attributes from element which is not empty anymore.
950
+ */
1050
951
  function clearAttributesStoredInElement(model, batch) {
1051
952
  const differ = model.document.differ;
1052
953
  for (const entry of differ.getChanges()) {