@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/selection
8
7
  */
@@ -10,93 +9,79 @@ import TypeCheckable from './typecheckable';
10
9
  import Node from './node';
11
10
  import Position from './position';
12
11
  import Range from './range';
13
- import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
14
- import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
15
- import isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';
12
+ import { CKEditorError, EmitterMixin, isIterable } from '@ckeditor/ckeditor5-utils';
16
13
  /**
17
14
  * Selection is a set of {@link module:engine/model/range~Range ranges}. It has a direction specified by its
18
15
  * {@link module:engine/model/selection~Selection#anchor anchor} and {@link module:engine/model/selection~Selection#focus focus}
19
16
  * (it can be {@link module:engine/model/selection~Selection#isBackward forward or backward}).
20
17
  * Additionally, selection may have its own attributes (think – whether text typed in in this selection
21
18
  * should have those attributes – e.g. whether you type a bolded text).
22
- *
23
- * @mixes module:utils/emittermixin~EmitterMixin
24
19
  */
25
20
  export default class Selection extends EmitterMixin(TypeCheckable) {
26
21
  /**
27
22
  * Creates a new selection instance based on the given {@link module:engine/model/selection~Selectable selectable}
28
23
  * or creates an empty selection if no arguments were passed.
29
24
  *
30
- * // Creates empty selection without ranges.
31
- * const selection = writer.createSelection();
25
+ * ```ts
26
+ * // Creates empty selection without ranges.
27
+ * const selection = writer.createSelection();
32
28
  *
33
- * // Creates selection at the given range.
34
- * const range = writer.createRange( start, end );
35
- * const selection = writer.createSelection( range );
29
+ * // Creates selection at the given range.
30
+ * const range = writer.createRange( start, end );
31
+ * const selection = writer.createSelection( range );
36
32
  *
37
- * // Creates selection at the given ranges
38
- * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];
39
- * const selection = writer.createSelection( ranges );
33
+ * // Creates selection at the given ranges
34
+ * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];
35
+ * const selection = writer.createSelection( ranges );
40
36
  *
41
- * // Creates selection from the other selection.
42
- * // Note: It doesn't copies selection attributes.
43
- * const otherSelection = writer.createSelection();
44
- * const selection = writer.createSelection( otherSelection );
37
+ * // Creates selection from the other selection.
38
+ * // Note: It doesn't copy selection attributes.
39
+ * const otherSelection = writer.createSelection();
40
+ * const selection = writer.createSelection( otherSelection );
45
41
  *
46
- * // Creates selection from the given document selection.
47
- * // Note: It doesn't copies selection attributes.
48
- * const documentSelection = model.document.selection;
49
- * const selection = writer.createSelection( documentSelection );
42
+ * // Creates selection from the given document selection.
43
+ * // Note: It doesn't copy selection attributes.
44
+ * const documentSelection = model.document.selection;
45
+ * const selection = writer.createSelection( documentSelection );
50
46
  *
51
- * // Creates selection at the given position.
52
- * const position = writer.createPositionFromPath( root, path );
53
- * const selection = writer.createSelection( position );
47
+ * // Creates selection at the given position.
48
+ * const position = writer.createPositionFromPath( root, path );
49
+ * const selection = writer.createSelection( position );
54
50
  *
55
- * // Creates selection at the given offset in the given element.
56
- * const paragraph = writer.createElement( 'paragraph' );
57
- * const selection = writer.createSelection( paragraph, offset );
51
+ * // Creates selection at the given offset in the given element.
52
+ * const paragraph = writer.createElement( 'paragraph' );
53
+ * const selection = writer.createSelection( paragraph, offset );
58
54
  *
59
- * // Creates a range inside an {@link module:engine/model/element~Element element} which starts before the
60
- * // first child of that element and ends after the last child of that element.
61
- * const selection = writer.createSelection( paragraph, 'in' );
55
+ * // Creates a range inside an {@link module:engine/model/element~Element element} which starts before the
56
+ * // first child of that element and ends after the last child of that element.
57
+ * const selection = writer.createSelection( paragraph, 'in' );
62
58
  *
63
- * // Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends
64
- * // just after the item.
65
- * const selection = writer.createSelection( paragraph, 'on' );
59
+ * // Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends
60
+ * // just after the item.
61
+ * const selection = writer.createSelection( paragraph, 'on' );
62
+ * ```
66
63
  *
67
64
  * Selection's constructor allow passing additional options (`'backward'`) as the last argument.
68
65
  *
69
- * // Creates backward selection.
70
- * const selection = writer.createSelection( range, { backward: true } );
66
+ * ```ts
67
+ * // Creates backward selection.
68
+ * const selection = writer.createSelection( range, { backward: true } );
69
+ * ```
71
70
  *
72
- * @param {module:engine/model/selection~Selectable} [selectable]
73
- * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.
74
- * @param {Object} [options]
75
- * @param {Boolean} [options.backward] Sets this selection instance to be backward.
71
+ * @internal
76
72
  */
77
73
  constructor(...args) {
78
74
  super();
79
75
  /**
80
76
  * Specifies whether the last added range was added as a backward or forward range.
81
- *
82
- * @private
83
- * @type {Boolean}
84
77
  */
85
78
  this._lastRangeBackward = false;
86
- /**
87
- * Stores selection ranges.
88
- *
89
- * @protected
90
- * @type {Array.<module:engine/model/range~Range>}
91
- */
92
- this._ranges = [];
93
79
  /**
94
80
  * List of attributes set on current selection.
95
- *
96
- * @protected
97
- * @type {Map.<String,*>}
98
81
  */
99
82
  this._attrs = new Map();
83
+ /** @internal */
84
+ this._ranges = [];
100
85
  if (args.length) {
101
86
  this.setTo(...args);
102
87
  }
@@ -115,8 +100,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
115
100
  * May be set to `null` if there are no ranges in the selection.
116
101
  *
117
102
  * @see #focus
118
- * @readonly
119
- * @type {module:engine/model/position~Position|null}
120
103
  */
121
104
  get anchor() {
122
105
  if (this._ranges.length > 0) {
@@ -132,8 +115,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
132
115
  * May be set to `null` if there are no ranges in the selection.
133
116
  *
134
117
  * @see #anchor
135
- * @readonly
136
- * @type {module:engine/model/position~Position|null}
137
118
  */
138
119
  get focus() {
139
120
  if (this._ranges.length > 0) {
@@ -145,9 +126,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
145
126
  /**
146
127
  * Whether the selection is collapsed. Selection is collapsed when there is exactly one range in it
147
128
  * and it is collapsed.
148
- *
149
- * @readonly
150
- * @type {Boolean}
151
129
  */
152
130
  get isCollapsed() {
153
131
  const length = this._ranges.length;
@@ -160,18 +138,12 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
160
138
  }
161
139
  /**
162
140
  * Returns the number of ranges in the selection.
163
- *
164
- * @readonly
165
- * @type {Number}
166
141
  */
167
142
  get rangeCount() {
168
143
  return this._ranges.length;
169
144
  }
170
145
  /**
171
146
  * Specifies whether the selection's {@link #focus} precedes the selection's {@link #anchor}.
172
- *
173
- * @readonly
174
- * @type {Boolean}
175
147
  */
176
148
  get isBackward() {
177
149
  return !this.isCollapsed && this._lastRangeBackward;
@@ -180,9 +152,8 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
180
152
  * Checks whether this selection is equal to the given selection. Selections are equal if they have the same directions,
181
153
  * the same number of ranges and all ranges from one selection equal to ranges from the another selection.
182
154
  *
183
- * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} otherSelection
184
- * Selection to compare with.
185
- * @returns {Boolean} `true` if selections are equal, `false` otherwise.
155
+ * @param otherSelection Selection to compare with.
156
+ * @returns `true` if selections are equal, `false` otherwise.
186
157
  */
187
158
  isEqual(otherSelection) {
188
159
  if (this.rangeCount != otherSelection.rangeCount) {
@@ -210,8 +181,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
210
181
  }
211
182
  /**
212
183
  * Returns an iterable object that iterates over copies of selection ranges.
213
- *
214
- * @returns {Iterable.<module:engine/model/range~Range>}
215
184
  */
216
185
  *getRanges() {
217
186
  for (const range of this._ranges) {
@@ -225,8 +194,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
225
194
  * (not to confuse with the first range added to the selection).
226
195
  *
227
196
  * Returns `null` if there are no ranges in selection.
228
- *
229
- * @returns {module:engine/model/range~Range|null}
230
197
  */
231
198
  getFirstRange() {
232
199
  let first = null;
@@ -244,8 +211,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
244
211
  * recently added to the selection).
245
212
  *
246
213
  * Returns `null` if there are no ranges in selection.
247
- *
248
- * @returns {module:engine/model/range~Range|null}
249
214
  */
250
215
  getLastRange() {
251
216
  let last = null;
@@ -262,8 +227,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
262
227
  * any other position in the selection.
263
228
  *
264
229
  * Returns `null` if there are no ranges in selection.
265
- *
266
- * @returns {module:engine/model/position~Position|null}
267
230
  */
268
231
  getFirstPosition() {
269
232
  const first = this.getFirstRange();
@@ -275,8 +238,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
275
238
  * any other position in the selection.
276
239
  *
277
240
  * Returns `null` if there are no ranges in selection.
278
- *
279
- * @returns {module:engine/model/position~Position|null}
280
241
  */
281
242
  getLastPosition() {
282
243
  const lastRange = this.getLastRange();
@@ -286,52 +247,55 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
286
247
  * Sets this selection's ranges and direction to the specified location based on the given
287
248
  * {@link module:engine/model/selection~Selectable selectable}.
288
249
  *
289
- * // Removes all selection's ranges.
290
- * selection.setTo( null );
250
+ * ```ts
251
+ * // Removes all selection's ranges.
252
+ * selection.setTo( null );
291
253
  *
292
- * // Sets selection to the given range.
293
- * const range = writer.createRange( start, end );
294
- * selection.setTo( range );
254
+ * // Sets selection to the given range.
255
+ * const range = writer.createRange( start, end );
256
+ * selection.setTo( range );
295
257
  *
296
- * // Sets selection to given ranges.
297
- * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];
298
- * selection.setTo( ranges );
258
+ * // Sets selection to given ranges.
259
+ * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];
260
+ * selection.setTo( ranges );
299
261
  *
300
- * // Sets selection to other selection.
301
- * // Note: It doesn't copies selection attributes.
302
- * const otherSelection = writer.createSelection();
303
- * selection.setTo( otherSelection );
262
+ * // Sets selection to other selection.
263
+ * // Note: It doesn't copy selection attributes.
264
+ * const otherSelection = writer.createSelection();
265
+ * selection.setTo( otherSelection );
304
266
  *
305
- * // Sets selection to the given document selection.
306
- * // Note: It doesn't copies selection attributes.
307
- * const documentSelection = new DocumentSelection( doc );
308
- * selection.setTo( documentSelection );
267
+ * // Sets selection to the given document selection.
268
+ * // Note: It doesn't copy selection attributes.
269
+ * const documentSelection = new DocumentSelection( doc );
270
+ * selection.setTo( documentSelection );
309
271
  *
310
- * // Sets collapsed selection at the given position.
311
- * const position = writer.createPositionFromPath( root, path );
312
- * selection.setTo( position );
272
+ * // Sets collapsed selection at the given position.
273
+ * const position = writer.createPositionFromPath( root, path );
274
+ * selection.setTo( position );
313
275
  *
314
- * // Sets collapsed selection at the position of the given node and an offset.
315
- * selection.setTo( paragraph, offset );
276
+ * // Sets collapsed selection at the position of the given node and an offset.
277
+ * selection.setTo( paragraph, offset );
278
+ * ```
316
279
  *
317
280
  * Creates a range inside an {@link module:engine/model/element~Element element} which starts before the first child of
318
281
  * that element and ends after the last child of that element.
319
282
  *
320
- * selection.setTo( paragraph, 'in' );
283
+ * ```ts
284
+ * selection.setTo( paragraph, 'in' );
285
+ * ```
321
286
  *
322
287
  * Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends just after the item.
323
288
  *
324
- * selection.setTo( paragraph, 'on' );
289
+ * ```ts
290
+ * selection.setTo( paragraph, 'on' );
291
+ * ```
325
292
  *
326
293
  * `Selection#setTo()`' method allow passing additional options (`backward`) as the last argument.
327
294
  *
328
- * // Sets backward selection.
329
- * const selection = writer.createSelection( range, { backward: true } );
330
- *
331
- * @param {module:engine/model/selection~Selectable} selectable
332
- * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.
333
- * @param {Object} [options]
334
- * @param {Boolean} [options.backward] Sets this selection instance to be backward.
295
+ * ```ts
296
+ * // Sets backward selection.
297
+ * const selection = writer.createSelection( range, { backward: true } );
298
+ * ```
335
299
  */
336
300
  setTo(...args) {
337
301
  let [selectable, placeOrOffset, options] = args;
@@ -403,10 +367,9 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
403
367
  * is treated like the last added range and is used to set {@link module:engine/model/selection~Selection#anchor} and
404
368
  * {@link module:engine/model/selection~Selection#focus}. Accepts a flag describing in which direction the selection is made.
405
369
  *
406
- * @protected
407
370
  * @fires change:range
408
- * @param {Iterable.<module:engine/model/range~Range>} newRanges Ranges to set.
409
- * @param {Boolean} [isLastBackward=false] Flag describing if last added range was selected forward - from start to end (`false`)
371
+ * @param newRanges Ranges to set.
372
+ * @param isLastBackward Flag describing if last added range was selected forward - from start to end (`false`)
410
373
  * or backward - from end to start (`true`).
411
374
  */
412
375
  _setRanges(newRanges, isLastBackward = false) {
@@ -446,9 +409,7 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
446
409
  * {@link module:engine/model/writer~Writer#createPositionAt writer.createPositionAt()} parameters.
447
410
  *
448
411
  * @fires change:range
449
- * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition
450
- * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when
451
- * first parameter is a {@link module:engine/model/item~Item model item}.
412
+ * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~Item model item}.
452
413
  */
453
414
  setFocus(itemOrPosition, offset) {
454
415
  if (this.anchor === null) {
@@ -480,8 +441,8 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
480
441
  /**
481
442
  * Gets an attribute value for given key or `undefined` if that attribute is not set on the selection.
482
443
  *
483
- * @param {String} key Key of attribute to look for.
484
- * @returns {*} Attribute value or `undefined`.
444
+ * @param key Key of attribute to look for.
445
+ * @returns Attribute value or `undefined`.
485
446
  */
486
447
  getAttribute(key) {
487
448
  return this._attrs.get(key);
@@ -491,16 +452,12 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
491
452
  *
492
453
  * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.
493
454
  * This format is accepted by native `Map` object and also can be passed in `Node` constructor.
494
- *
495
- * @returns {Iterable.<*>}
496
455
  */
497
456
  getAttributes() {
498
457
  return this._attrs.entries();
499
458
  }
500
459
  /**
501
460
  * Returns iterable that iterates over this selection's attribute keys.
502
- *
503
- * @returns {Iterable.<String>}
504
461
  */
505
462
  getAttributeKeys() {
506
463
  return this._attrs.keys();
@@ -508,8 +465,8 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
508
465
  /**
509
466
  * Checks if the selection has an attribute for given key.
510
467
  *
511
- * @param {String} key Key of attribute to check.
512
- * @returns {Boolean} `true` if attribute with given key is set on selection, `false` otherwise.
468
+ * @param key Key of attribute to check.
469
+ * @returns `true` if attribute with given key is set on selection, `false` otherwise.
513
470
  */
514
471
  hasAttribute(key) {
515
472
  return this._attrs.has(key);
@@ -521,7 +478,7 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
521
478
  * removed attribute key.
522
479
  *
523
480
  * @fires change:attribute
524
- * @param {String} key Key of attribute to remove.
481
+ * @param key Key of attribute to remove.
525
482
  */
526
483
  removeAttribute(key) {
527
484
  if (this.hasAttribute(key)) {
@@ -536,8 +493,8 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
536
493
  * the attribute key.
537
494
  *
538
495
  * @fires change:attribute
539
- * @param {String} key Key of attribute to set.
540
- * @param {*} value Attribute value.
496
+ * @param key Key of attribute to set.
497
+ * @param value Attribute value.
541
498
  */
542
499
  setAttribute(key, value) {
543
500
  if (this.getAttribute(key) !== value) {
@@ -549,8 +506,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
549
506
  * Returns the selected element. {@link module:engine/model/element~Element Element} is considered as selected if there is only
550
507
  * one range in the selection, and that range contains exactly one element.
551
508
  * Returns `null` if there is no selected element.
552
- *
553
- * @returns {module:engine/model/element~Element|null}
554
509
  */
555
510
  getSelectedElement() {
556
511
  if (this.rangeCount !== 1) {
@@ -568,40 +523,48 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
568
523
  *
569
524
  * In this case the function will return exactly all 3 paragraphs (note: `<blockQuote>` is not a block itself):
570
525
  *
571
- * <paragraph>[a</paragraph>
572
- * <blockQuote>
573
- * <paragraph>b</paragraph>
574
- * </blockQuote>
575
- * <paragraph>c]d</paragraph>
526
+ * ```xml
527
+ * <paragraph>[a</paragraph>
528
+ * <blockQuote>
529
+ * <paragraph>b</paragraph>
530
+ * </blockQuote>
531
+ * <paragraph>c]d</paragraph>
532
+ * ```
576
533
  *
577
534
  * In this case the paragraph will also be returned, despite the collapsed selection:
578
535
  *
579
- * <paragraph>[]a</paragraph>
536
+ * ```xml
537
+ * <paragraph>[]a</paragraph>
538
+ * ```
580
539
  *
581
540
  * In such a scenario, however, only blocks A, B & E will be returned as blocks C & D are nested in block B:
582
541
  *
583
- * [<blockA></blockA>
584
- * <blockB>
585
- * <blockC></blockC>
586
- * <blockD></blockD>
587
- * </blockB>
588
- * <blockE></blockE>]
542
+ * ```xml
543
+ * [<blockA></blockA>
544
+ * <blockB>
545
+ * <blockC></blockC>
546
+ * <blockD></blockD>
547
+ * </blockB>
548
+ * <blockE></blockE>]
549
+ * ```
589
550
  *
590
551
  * If the selection is inside a block all the inner blocks (A & B) are returned:
591
552
  *
592
- * <block>
593
- * <blockA>[a</blockA>
594
- * <blockB>b]</blockB>
595
- * </block>
553
+ * ```xml
554
+ * <block>
555
+ * <blockA>[a</blockA>
556
+ * <blockB>b]</blockB>
557
+ * </block>
558
+ * ```
596
559
  *
597
560
  * **Special case**: If a selection ends at the beginning of a block, that block is not returned as from user perspective
598
561
  * this block wasn't selected. See [#984](https://github.com/ckeditor/ckeditor5-engine/issues/984) for more details.
599
562
  *
600
- * <paragraph>[a</paragraph>
601
- * <paragraph>b</paragraph>
602
- * <paragraph>]c</paragraph> // this block will not be returned
603
- *
604
- * @returns {Iterable.<module:engine/model/element~Element>}
563
+ * ```xml
564
+ * <paragraph>[a</paragraph>
565
+ * <paragraph>b</paragraph>
566
+ * <paragraph>]c</paragraph> // this block will not be returned
567
+ * ```
605
568
  */
606
569
  *getSelectedBlocks() {
607
570
  const visited = new WeakSet();
@@ -631,9 +594,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
631
594
  *
632
595
  * By default, this method will check whether the entire content of the selection's current root is selected.
633
596
  * Useful to check if e.g. the user has just pressed <kbd>Ctrl</kbd> + <kbd>A</kbd>.
634
- *
635
- * @param {module:engine/model/element~Element} [element=this.anchor.root]
636
- * @returns {Boolean}
637
597
  */
638
598
  containsEntireContent(element = this.anchor.root) {
639
599
  const limitStartPosition = Position._createAt(element, 0);
@@ -644,9 +604,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
644
604
  /**
645
605
  * Adds given range to internal {@link #_ranges ranges array}. Throws an error
646
606
  * if given range is intersecting with any range that is already stored in this selection.
647
- *
648
- * @protected
649
- * @param {module:engine/model/range~Range} range Range to add.
650
607
  */
651
608
  _pushRange(range) {
652
609
  this._checkRange(range);
@@ -654,9 +611,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
654
611
  }
655
612
  /**
656
613
  * Checks if given range intersects with ranges that are already in the selection. Throws an error if it does.
657
- *
658
- * @protected
659
- * @param {module:engine/model/range~Range} range Range to check.
660
614
  */
661
615
  _checkRange(range) {
662
616
  for (let i = 0; i < this._ranges.length; i++) {
@@ -665,8 +619,8 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
665
619
  * Trying to add a range that intersects with another range in the selection.
666
620
  *
667
621
  * @error model-selection-range-intersects
668
- * @param {module:engine/model/range~Range} addedRange Range that was added to the selection.
669
- * @param {module:engine/model/range~Range} intersectingRange Range in the selection that intersects with `addedRange`.
622
+ * @param addedRange Range that was added to the selection.
623
+ * @param intersectingRange Range in the selection that intersects with `addedRange`.
670
624
  */
671
625
  throw new CKEditorError('model-selection-range-intersects', [this, range], { addedRange: range, intersectingRange: this._ranges[i] });
672
626
  }
@@ -675,9 +629,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
675
629
  /**
676
630
  * Replaces all the ranges by the given ones.
677
631
  * Uses {@link #_popRange _popRange} and {@link #_pushRange _pushRange} to ensure proper ranges removal and addition.
678
- *
679
- * @param {Array.<module:engine/model/range~Range>} ranges
680
- * @protected
681
632
  */
682
633
  _replaceAllRanges(ranges) {
683
634
  this._removeAllRanges();
@@ -688,8 +639,6 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
688
639
  /**
689
640
  * Deletes ranges from internal range array. Uses {@link #_popRange _popRange} to
690
641
  * ensure proper ranges removal.
691
- *
692
- * @protected
693
642
  */
694
643
  _removeAllRanges() {
695
644
  while (this._ranges.length > 0) {
@@ -698,32 +647,20 @@ export default class Selection extends EmitterMixin(TypeCheckable) {
698
647
  }
699
648
  /**
700
649
  * Removes most recently added range from the selection.
701
- *
702
- * @protected
703
650
  */
704
651
  _popRange() {
705
652
  this._ranges.pop();
706
653
  }
707
654
  }
708
- /**
709
- * Checks whether this object is of the given.
710
- *
711
- * selection.is( 'selection' ); // -> true
712
- * selection.is( 'model:selection' ); // -> true
713
- *
714
- * selection.is( 'view:selection' ); // -> false
715
- * selection.is( 'range' ); // -> false
716
- *
717
- * {@link module:engine/model/node~Node#is Check the entire list of model objects} which implement the `is()` method.
718
- *
719
- * @param {String} type
720
- * @returns {Boolean}
721
- */
655
+ // The magic of type inference using `is` method is centralized in `TypeCheckable` class.
656
+ // Proper overload would interfere with that.
722
657
  Selection.prototype.is = function (type) {
723
658
  return type === 'selection' || type === 'model:selection';
724
659
  };
725
- // Checks whether the given element extends $block in the schema and has a parent (is not a root).
726
- // Marks it as already visited.
660
+ /**
661
+ * Checks whether the given element extends $block in the schema and has a parent (is not a root).
662
+ * Marks it as already visited.
663
+ */
727
664
  function isUnvisitedBlock(element, visited) {
728
665
  if (visited.has(element)) {
729
666
  return false;
@@ -731,13 +668,17 @@ function isUnvisitedBlock(element, visited) {
731
668
  visited.add(element);
732
669
  return element.root.document.model.schema.isBlock(element) && !!element.parent;
733
670
  }
734
- // Checks if the given element is a $block was not previously visited and is a top block in a range.
671
+ /**
672
+ * Checks if the given element is a $block was not previously visited and is a top block in a range.
673
+ */
735
674
  function isUnvisitedTopBlock(element, visited, range) {
736
675
  return isUnvisitedBlock(element, visited) && isTopBlockInRange(element, range);
737
676
  }
738
- // Finds the lowest element in position's ancestors which is a block.
739
- // It will search until first ancestor that is a limit element.
740
- // Marks all ancestors as already visited to not include any of them later on.
677
+ /**
678
+ * Finds the lowest element in position's ancestors which is a block.
679
+ * It will search until first ancestor that is a limit element.
680
+ * Marks all ancestors as already visited to not include any of them later on.
681
+ */
741
682
  function getParentBlock(position, visited) {
742
683
  const element = position.parent;
743
684
  const schema = element.root.document.model.schema;
@@ -756,10 +697,9 @@ function getParentBlock(position, visited) {
756
697
  ancestors.forEach(element => visited.add(element));
757
698
  return block;
758
699
  }
759
- // Checks if the blocks is not nested in other block inside a range.
760
- //
761
- // @param {module:engine/model/element~Element} block Block to check.
762
- // @param {module:engine/model/range~Range} range Range to check.
700
+ /**
701
+ * Checks if the blocks is not nested in other block inside a range.
702
+ */
763
703
  function isTopBlockInRange(block, range) {
764
704
  const parentBlock = findAncestorBlock(block);
765
705
  if (!parentBlock) {
@@ -769,10 +709,9 @@ function isTopBlockInRange(block, range) {
769
709
  const isParentInRange = range.containsRange(Range._createOn(parentBlock), true);
770
710
  return !isParentInRange;
771
711
  }
772
- // Returns first ancestor block of a node.
773
- //
774
- // @param {module:engine/model/node~Node} node
775
- // @returns {module:engine/model/node~Node|undefined}
712
+ /**
713
+ * Returns first ancestor block of a node.
714
+ */
776
715
  function findAncestorBlock(node) {
777
716
  const schema = node.root.document.model.schema;
778
717
  let parent = node.parent;