@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,5 +1,5 @@
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
5
  /**
@@ -9,10 +9,7 @@ import Differ from './differ';
9
9
  import DocumentSelection from './documentselection';
10
10
  import History from './history';
11
11
  import RootElement from './rootelement';
12
- import Collection from '@ckeditor/ckeditor5-utils/src/collection';
13
- import { Emitter } from '@ckeditor/ckeditor5-utils/src/emittermixin';
14
- import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
15
- import { isInsideSurrogatePair, isInsideCombinedSymbol } from '@ckeditor/ckeditor5-utils/src/unicode';
12
+ import { CKEditorError, Collection, EmitterMixin, isInsideSurrogatePair, isInsideCombinedSymbol } from '@ckeditor/ckeditor5-utils';
16
13
  import { clone } from 'lodash-es';
17
14
  // @if CK_DEBUG_ENGINE // const { logDocument } = require( '../dev-utils/utils' );
18
15
  const graveyardName = '$graveyard';
@@ -25,69 +22,26 @@ const graveyardName = '$graveyard';
25
22
  * Usually, the document contains just one {@link module:engine/model/document~Document#roots root element}, so
26
23
  * you can retrieve it by just calling {@link module:engine/model/document~Document#getRoot} without specifying its name:
27
24
  *
28
- * model.document.getRoot(); // -> returns the main root
25
+ * ```ts
26
+ * model.document.getRoot(); // -> returns the main root
27
+ * ```
29
28
  *
30
29
  * However, the document may contain multiple roots – e.g. when the editor has multiple editable areas
31
30
  * (e.g. a title and a body of a message).
32
- *
33
- * @mixes module:utils/emittermixin~EmitterMixin
34
31
  */
35
- export default class Document extends Emitter {
32
+ export default class Document extends EmitterMixin() {
36
33
  /**
37
34
  * Creates an empty document instance with no {@link #roots} (other than
38
35
  * the {@link #graveyard graveyard root}).
39
36
  */
40
37
  constructor(model) {
41
38
  super();
42
- /**
43
- * The {@link module:engine/model/model~Model model} that the document is a part of.
44
- *
45
- * @readonly
46
- * @type {module:engine/model/model~Model}
47
- */
48
39
  this.model = model;
49
- /**
50
- * The document's history.
51
- *
52
- * @readonly
53
- * @type {module:engine/model/history~History}
54
- */
55
40
  this.history = new History();
56
- /**
57
- * The selection in this document.
58
- *
59
- * @readonly
60
- * @type {module:engine/model/documentselection~DocumentSelection}
61
- */
62
41
  this.selection = new DocumentSelection(this);
63
- /**
64
- * A list of roots that are owned and managed by this document. Use {@link #createRoot} and
65
- * {@link #getRoot} to manipulate it.
66
- *
67
- * @readonly
68
- * @type {module:utils/collection~Collection}
69
- */
70
42
  this.roots = new Collection({ idProperty: 'rootName' });
71
- /**
72
- * The model differ object. Its role is to buffer changes done on the model document and then calculate a diff of those changes.
73
- *
74
- * @readonly
75
- * @type {module:engine/model/differ~Differ}
76
- */
77
43
  this.differ = new Differ(model.markers);
78
- /**
79
- * Post-fixer callbacks registered to the model document.
80
- *
81
- * @private
82
- * @type {Set.<Function>}
83
- */
84
44
  this._postFixers = new Set();
85
- /**
86
- * A boolean indicates whether the selection has changed until
87
- *
88
- * @private
89
- * @type {Boolean}
90
- */
91
45
  this._hasSelectionChangedFromTheLastChangeBlock = false;
92
46
  // Graveyard tree root. Document always have a graveyard root, which stores removed nodes.
93
47
  this.createRoot('$root', graveyardName);
@@ -134,8 +88,6 @@ export default class Document extends Emitter {
134
88
  *
135
89
  * If the {@link module:engine/model/operation/operation~Operation#baseVersion base version} does not match the document version,
136
90
  * a {@link module:utils/ckeditorerror~CKEditorError model-document-applyoperation-wrong-version} error is thrown.
137
- *
138
- * @type {Number}
139
91
  */
140
92
  get version() {
141
93
  return this.history.version;
@@ -145,9 +97,6 @@ export default class Document extends Emitter {
145
97
  }
146
98
  /**
147
99
  * The graveyard tree root. A document always has a graveyard root that stores removed nodes.
148
- *
149
- * @readonly
150
- * @member {module:engine/model/rootelement~RootElement}
151
100
  */
152
101
  get graveyard() {
153
102
  return this.getRoot(graveyardName);
@@ -155,10 +104,10 @@ export default class Document extends Emitter {
155
104
  /**
156
105
  * Creates a new root.
157
106
  *
158
- * @param {String} [elementName='$root'] The element name. Defaults to `'$root'` which also has some basic schema defined
107
+ * @param elementName The element name. Defaults to `'$root'` which also has some basic schema defined
159
108
  * (`$block`s are allowed inside the `$root`). Make sure to define a proper schema if you use a different name.
160
- * @param {String} [rootName='main'] A unique root name.
161
- * @returns {module:engine/model/rootelement~RootElement} The created root.
109
+ * @param rootName A unique root name.
110
+ * @returns The created root.
162
111
  */
163
112
  createRoot(elementName = '$root', rootName = 'main') {
164
113
  if (this.roots.get(rootName)) {
@@ -166,8 +115,6 @@ export default class Document extends Emitter {
166
115
  * A root with the specified name already exists.
167
116
  *
168
117
  * @error model-document-createroot-name-exists
169
- * @param {module:engine/model/document~Document} doc
170
- * @param {String} name
171
118
  */
172
119
  throw new CKEditorError('model-document-createroot-name-exists', this, { name: rootName });
173
120
  }
@@ -185,9 +132,8 @@ export default class Document extends Emitter {
185
132
  /**
186
133
  * Returns a root by its name.
187
134
  *
188
- * @param {String} [name='main'] A unique root name.
189
- * @returns {module:engine/model/rootelement~RootElement|null} The root registered under a given name or `null` when
190
- * there is no root with the given name.
135
+ * @param name A unique root name.
136
+ * @returns The root registered under a given name or `null` when there is no root with the given name.
191
137
  */
192
138
  getRoot(name = 'main') {
193
139
  return this.roots.get(name);
@@ -195,7 +141,7 @@ export default class Document extends Emitter {
195
141
  /**
196
142
  * Returns an array with names of all roots (without the {@link #graveyard}) added to the document.
197
143
  *
198
- * @returns {Array.<String>} Roots names.
144
+ * @returns Roots names.
199
145
  */
200
146
  getRootNames() {
201
147
  return Array.from(this.roots, root => root.rootName).filter(name => name != graveyardName);
@@ -218,24 +164,24 @@ export default class Document extends Emitter {
218
164
  * An example of a post-fixer is a callback that checks if all the data were removed from the editor. If so, the
219
165
  * callback should add an empty paragraph so that the editor is never empty:
220
166
  *
221
- * document.registerPostFixer( writer => {
222
- * const changes = document.differ.getChanges();
167
+ * ```ts
168
+ * document.registerPostFixer( writer => {
169
+ * const changes = document.differ.getChanges();
223
170
  *
224
- * // Check if the changes lead to an empty root in the editor.
225
- * for ( const entry of changes ) {
226
- * if ( entry.type == 'remove' && entry.position.root.isEmpty ) {
227
- * writer.insertElement( 'paragraph', entry.position.root, 0 );
171
+ * // Check if the changes lead to an empty root in the editor.
172
+ * for ( const entry of changes ) {
173
+ * if ( entry.type == 'remove' && entry.position.root.isEmpty ) {
174
+ * writer.insertElement( 'paragraph', entry.position.root, 0 );
228
175
  *
229
- * // It is fine to return early, even if multiple roots would need to be fixed.
230
- * // All post-fixers will be fired again, so if there are more empty roots, those will be fixed, too.
231
- * return true;
232
- * }
233
- * }
176
+ * // It is fine to return early, even if multiple roots would need to be fixed.
177
+ * // All post-fixers will be fired again, so if there are more empty roots, those will be fixed, too.
178
+ * return true;
179
+ * }
180
+ * }
234
181
  *
235
- * return false;
236
- * } );
237
- *
238
- * @param {Function} postFixer
182
+ * return false;
183
+ * } );
184
+ * ```
239
185
  */
240
186
  registerPostFixer(postFixer) {
241
187
  this._postFixers.add(postFixer);
@@ -243,7 +189,7 @@ export default class Document extends Emitter {
243
189
  /**
244
190
  * A custom `toJSON()` method to solve child-parent circular dependencies.
245
191
  *
246
- * @returns {Object} A clone of this object with the document property changed to a string.
192
+ * @returns A clone of this object with the document property changed to a string.
247
193
  */
248
194
  toJSON() {
249
195
  const json = clone(this);
@@ -258,10 +204,9 @@ export default class Document extends Emitter {
258
204
  * Fire `change:data` event when at least one operation or buffered marker changes the data.
259
205
  *
260
206
  * @internal
261
- * @protected
262
207
  * @fires change
263
208
  * @fires change:data
264
- * @param {module:engine/model/writer~Writer} writer The writer on which post-fixers will be called.
209
+ * @param writer The writer on which post-fixers will be called.
265
210
  */
266
211
  _handleChangeBlock(writer) {
267
212
  if (this._hasDocumentChangedFromTheLastChangeBlock()) {
@@ -286,8 +231,7 @@ export default class Document extends Emitter {
286
231
  * {@link module:engine/model/model~Model#enqueueChange `enqueueChange()` block}
287
232
  * or {@link module:engine/model/model~Model#change `change()` block}.
288
233
  *
289
- * @protected
290
- * @returns {Boolean} Returns `true` if document has changed from the last `change()` or `enqueueChange()` block.
234
+ * @returns Returns `true` if document has changed from the last `change()` or `enqueueChange()` block.
291
235
  */
292
236
  _hasDocumentChangedFromTheLastChangeBlock() {
293
237
  return !this.differ.isEmpty || this._hasSelectionChangedFromTheLastChangeBlock;
@@ -296,8 +240,7 @@ export default class Document extends Emitter {
296
240
  * Returns the default root for this document which is either the first root that was added to the document using
297
241
  * {@link #createRoot} or the {@link #graveyard graveyard root} if no other roots were created.
298
242
  *
299
- * @protected
300
- * @returns {module:engine/model/rootelement~RootElement} The default root for this document.
243
+ * @returns The default root for this document.
301
244
  */
302
245
  _getDefaultRoot() {
303
246
  for (const root of this.roots) {
@@ -312,8 +255,6 @@ export default class Document extends Emitter {
312
255
  * at the beginning of this selection's document {@link #_getDefaultRoot default root}.
313
256
  *
314
257
  * @internal
315
- * @protected
316
- * @returns {module:engine/model/range~Range}
317
258
  */
318
259
  _getDefaultRange() {
319
260
  const defaultRoot = this._getDefaultRoot();
@@ -330,9 +271,8 @@ export default class Document extends Emitter {
330
271
  * the {@link #selection document's selection}.
331
272
  *
332
273
  * @internal
333
- * @protected
334
- * @param {module:engine/model/range~Range} range A range to check.
335
- * @returns {Boolean} `true` if `range` is valid, `false` otherwise.
274
+ * @param range A range to check.
275
+ * @returns `true` if `range` is valid, `false` otherwise.
336
276
  */
337
277
  _validateSelectionRange(range) {
338
278
  return validateTextNodePosition(range.start) && validateTextNodePosition(range.end);
@@ -340,8 +280,7 @@ export default class Document extends Emitter {
340
280
  /**
341
281
  * Performs post-fixer loops. Executes post-fixer callbacks as long as none of them has done any changes to the model.
342
282
  *
343
- * @private
344
- * @param {module:engine/model/writer~Writer} writer The writer on which post-fixer callbacks will be called.
283
+ * @param writer The writer on which post-fixer callbacks will be called.
345
284
  */
346
285
  _callPostFixers(writer) {
347
286
  let wasFixed = false;
@@ -362,8 +301,10 @@ export default class Document extends Emitter {
362
301
  } while (wasFixed);
363
302
  }
364
303
  }
365
- // Checks whether given range boundary position is valid for document selection, meaning that is not between
366
- // unicode surrogate pairs or base character and combining marks.
304
+ /**
305
+ * Checks whether given range boundary position is valid for document selection, meaning that is not between
306
+ * unicode surrogate pairs or base character and combining marks.
307
+ */
367
308
  function validateTextNodePosition(rangeBoundary) {
368
309
  const textNode = rangeBoundary.textNode;
369
310
  if (textNode) {
@@ -1,5 +1,5 @@
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
5
  /**
@@ -10,7 +10,7 @@ import Element from './element';
10
10
  import NodeList from './nodelist';
11
11
  import Text from './text';
12
12
  import TextProxy from './textproxy';
13
- import isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';
13
+ import { isIterable } from '@ckeditor/ckeditor5-utils';
14
14
  // @if CK_DEBUG_ENGINE // const { stringifyMap } = require( '../dev-utils/utils' );
15
15
  /**
16
16
  * DocumentFragment represents a part of model which does not have a common root but its top-level nodes
@@ -27,9 +27,8 @@ export default class DocumentFragment extends TypeCheckable {
27
27
  * **Note:** Constructor of this class shouldn't be used directly in the code.
28
28
  * Use the {@link module:engine/model/writer~Writer#createDocumentFragment} method instead.
29
29
  *
30
- * @protected
31
- * @param {module:engine/model/node~Node|Iterable.<module:engine/model/node~Node>} [children]
32
- * Nodes to be contained inside the `DocumentFragment`.
30
+ * @internal
31
+ * @param children Nodes to be contained inside the `DocumentFragment`.
33
32
  */
34
33
  constructor(children) {
35
34
  super();
@@ -37,16 +36,10 @@ export default class DocumentFragment extends TypeCheckable {
37
36
  * DocumentFragment static markers map. This is a list of names and {@link module:engine/model/range~Range ranges}
38
37
  * which will be set as Markers to {@link module:engine/model/model~Model#markers model markers collection}
39
38
  * when DocumentFragment will be inserted to the document.
40
- *
41
- * @readonly
42
- * @member {Map<String,module:engine/model/range~Range>} module:engine/model/documentfragment~DocumentFragment#markers
43
39
  */
44
40
  this.markers = new Map();
45
41
  /**
46
42
  * List of nodes contained inside the document fragment.
47
- *
48
- * @private
49
- * @member {module:engine/model/nodelist~NodeList} module:engine/model/documentfragment~DocumentFragment#_children
50
43
  */
51
44
  this._children = new NodeList();
52
45
  if (children) {
@@ -55,88 +48,60 @@ export default class DocumentFragment extends TypeCheckable {
55
48
  }
56
49
  /**
57
50
  * Returns an iterator that iterates over all nodes contained inside this document fragment.
58
- *
59
- * @returns {Iterator.<module:engine/model/node~Node>}
60
51
  */
61
52
  [Symbol.iterator]() {
62
53
  return this.getChildren();
63
54
  }
64
55
  /**
65
56
  * Number of this document fragment's children.
66
- *
67
- * @readonly
68
- * @type {Number}
69
57
  */
70
58
  get childCount() {
71
59
  return this._children.length;
72
60
  }
73
61
  /**
74
62
  * Sum of {@link module:engine/model/node~Node#offsetSize offset sizes} of all of this document fragment's children.
75
- *
76
- * @readonly
77
- * @type {Number}
78
63
  */
79
64
  get maxOffset() {
80
65
  return this._children.maxOffset;
81
66
  }
82
67
  /**
83
68
  * Is `true` if there are no nodes inside this document fragment, `false` otherwise.
84
- *
85
- * @readonly
86
- * @type {Boolean}
87
69
  */
88
70
  get isEmpty() {
89
71
  return this.childCount === 0;
90
72
  }
91
73
  /**
92
74
  * Artificial next sibling. Returns `null`. Added for compatibility reasons.
93
- *
94
- * @readonly
95
- * @type {null}
96
75
  */
97
76
  get nextSibling() {
98
77
  return null;
99
78
  }
100
79
  /**
101
80
  * Artificial previous sibling. Returns `null`. Added for compatibility reasons.
102
- *
103
- * @readonly
104
- * @type {null}
105
81
  */
106
82
  get previousSibling() {
107
83
  return null;
108
84
  }
109
85
  /**
110
86
  * Artificial root of `DocumentFragment`. Returns itself. Added for compatibility reasons.
111
- *
112
- * @readonly
113
- * @type {module:engine/model/documentfragment~DocumentFragment}
114
87
  */
115
88
  get root() {
116
89
  return this;
117
90
  }
118
91
  /**
119
92
  * Artificial parent of `DocumentFragment`. Returns `null`. Added for compatibility reasons.
120
- *
121
- * @readonly
122
- * @type {null}
123
93
  */
124
94
  get parent() {
125
95
  return null;
126
96
  }
127
97
  /**
128
98
  * Artificial owner of `DocumentFragment`. Returns `null`. Added for compatibility reasons.
129
- *
130
- * @readonly
131
- * @type {null}
132
99
  */
133
100
  get document() {
134
101
  return null;
135
102
  }
136
103
  /**
137
104
  * Returns empty array. Added for compatibility reasons.
138
- *
139
- * @returns {Array}
140
105
  */
141
106
  getAncestors() {
142
107
  return [];
@@ -144,16 +109,14 @@ export default class DocumentFragment extends TypeCheckable {
144
109
  /**
145
110
  * Gets the child at the given index. Returns `null` if incorrect index was passed.
146
111
  *
147
- * @param {Number} index Index of child.
148
- * @returns {module:engine/model/node~Node|null} Child node.
112
+ * @param index Index of child.
113
+ * @returns Child node.
149
114
  */
150
115
  getChild(index) {
151
116
  return this._children.getNode(index);
152
117
  }
153
118
  /**
154
119
  * Returns an iterator that iterates over all of this document fragment's children.
155
- *
156
- * @returns {Iterable.<module:engine/model/node~Node>}
157
120
  */
158
121
  getChildren() {
159
122
  return this._children[Symbol.iterator]();
@@ -161,8 +124,8 @@ export default class DocumentFragment extends TypeCheckable {
161
124
  /**
162
125
  * Returns an index of the given child node. Returns `null` if given node is not a child of this document fragment.
163
126
  *
164
- * @param {module:engine/model/node~Node} node Child node to look for.
165
- * @returns {Number|null} Child node's index.
127
+ * @param node Child node to look for.
128
+ * @returns Child node's index.
166
129
  */
167
130
  getChildIndex(node) {
168
131
  return this._children.getNodeIndex(node);
@@ -172,16 +135,14 @@ export default class DocumentFragment extends TypeCheckable {
172
135
  * {@link module:engine/model/node~Node#offsetSize offset sizes} of all node's siblings that are before it. Returns `null` if
173
136
  * given node is not a child of this document fragment.
174
137
  *
175
- * @param {module:engine/model/node~Node} node Child node to look for.
176
- * @returns {Number|null} Child node's starting offset.
138
+ * @param node Child node to look for.
139
+ * @returns Child node's starting offset.
177
140
  */
178
141
  getChildStartOffset(node) {
179
142
  return this._children.getNodeStartOffset(node);
180
143
  }
181
144
  /**
182
145
  * Returns path to a `DocumentFragment`, which is an empty array. Added for compatibility reasons.
183
- *
184
- * @returns {Array}
185
146
  */
186
147
  getPath() {
187
148
  return [];
@@ -189,13 +150,14 @@ export default class DocumentFragment extends TypeCheckable {
189
150
  /**
190
151
  * Returns a descendant node by its path relative to this element.
191
152
  *
192
- * // <this>a<b>c</b></this>
193
- * this.getNodeByPath( [ 0 ] ); // -> "a"
194
- * this.getNodeByPath( [ 1 ] ); // -> <b>
195
- * this.getNodeByPath( [ 1, 0 ] ); // -> "c"
153
+ * ```ts
154
+ * // <this>a<b>c</b></this>
155
+ * this.getNodeByPath( [ 0 ] ); // -> "a"
156
+ * this.getNodeByPath( [ 1 ] ); // -> <b>
157
+ * this.getNodeByPath( [ 1, 0 ] ); // -> "c"
158
+ * ```
196
159
  *
197
- * @param {Array.<Number>} relativePath Path of the node to find, relative to this element.
198
- * @returns {module:engine/model/node~Node|module:engine/model/documentfragment~DocumentFragment}
160
+ * @param relativePath Path of the node to find, relative to this element.
199
161
  */
200
162
  getNodeByPath(relativePath) {
201
163
  // eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this
@@ -211,18 +173,20 @@ export default class DocumentFragment extends TypeCheckable {
211
173
  * Returns index of a node that occupies given offset. If given offset is too low, returns `0`. If given offset is
212
174
  * too high, returns index after last child}.
213
175
  *
214
- * const textNode = new Text( 'foo' );
215
- * const pElement = new Element( 'p' );
216
- * const docFrag = new DocumentFragment( [ textNode, pElement ] );
217
- * docFrag.offsetToIndex( -1 ); // Returns 0, because offset is too low.
218
- * docFrag.offsetToIndex( 0 ); // Returns 0, because offset 0 is taken by `textNode` which is at index 0.
219
- * docFrag.offsetToIndex( 1 ); // Returns 0, because `textNode` has `offsetSize` equal to 3, so it occupies offset 1 too.
220
- * docFrag.offsetToIndex( 2 ); // Returns 0.
221
- * docFrag.offsetToIndex( 3 ); // Returns 1.
222
- * docFrag.offsetToIndex( 4 ); // Returns 2. There are no nodes at offset 4, so last available index is returned.
176
+ * ```ts
177
+ * const textNode = new Text( 'foo' );
178
+ * const pElement = new Element( 'p' );
179
+ * const docFrag = new DocumentFragment( [ textNode, pElement ] );
180
+ * docFrag.offsetToIndex( -1 ); // Returns 0, because offset is too low.
181
+ * docFrag.offsetToIndex( 0 ); // Returns 0, because offset 0 is taken by `textNode` which is at index 0.
182
+ * docFrag.offsetToIndex( 1 ); // Returns 0, because `textNode` has `offsetSize` equal to 3, so it occupies offset 1 too.
183
+ * docFrag.offsetToIndex( 2 ); // Returns 0.
184
+ * docFrag.offsetToIndex( 3 ); // Returns 1.
185
+ * docFrag.offsetToIndex( 4 ); // Returns 2. There are no nodes at offset 4, so last available index is returned.
186
+ * ```
223
187
  *
224
- * @param {Number} offset Offset to look for.
225
- * @returns {Number} Index of a node that occupies given offset.
188
+ * @param offset Offset to look for.
189
+ * @returns Index of a node that occupies given offset.
226
190
  */
227
191
  offsetToIndex(offset) {
228
192
  return this._children.offsetToIndex(offset);
@@ -231,7 +195,7 @@ export default class DocumentFragment extends TypeCheckable {
231
195
  * Converts `DocumentFragment` instance to plain object and returns it.
232
196
  * Takes care of converting all of this document fragment's children.
233
197
  *
234
- * @returns {Object} `DocumentFragment` instance converted to plain object.
198
+ * @returns `DocumentFragment` instance converted to plain object.
235
199
  */
236
200
  toJSON() {
237
201
  const json = [];
@@ -244,8 +208,8 @@ export default class DocumentFragment extends TypeCheckable {
244
208
  * Creates a `DocumentFragment` instance from given plain object (i.e. parsed JSON string).
245
209
  * Converts `DocumentFragment` children to proper nodes.
246
210
  *
247
- * @param {Object} json Plain object to be converted to `DocumentFragment`.
248
- * @returns {module:engine/model/documentfragment~DocumentFragment} `DocumentFragment` instance created using given plain object.
211
+ * @param json Plain object to be converted to `DocumentFragment`.
212
+ * @returns `DocumentFragment` instance created using given plain object.
249
213
  */
250
214
  static fromJSON(json) {
251
215
  const children = [];
@@ -265,8 +229,7 @@ export default class DocumentFragment extends TypeCheckable {
265
229
  * {@link #_insertChild Inserts} one or more nodes at the end of this document fragment.
266
230
  *
267
231
  * @internal
268
- * @protected
269
- * @param {String|module:engine/model/item~Item|Iterable.<String|module:engine/model/item~Item>} items Items to be inserted.
232
+ * @param items Items to be inserted.
270
233
  */
271
234
  _appendChild(items) {
272
235
  this._insertChild(this.childCount, items);
@@ -276,9 +239,8 @@ export default class DocumentFragment extends TypeCheckable {
276
239
  * to this document fragment.
277
240
  *
278
241
  * @internal
279
- * @protected
280
- * @param {Number} index Index at which nodes should be inserted.
281
- * @param {String|module:engine/model/item~Item|Iterable.<String|module:engine/model/item~Item>} items Items to be inserted.
242
+ * @param index Index at which nodes should be inserted.
243
+ * @param items Items to be inserted.
282
244
  */
283
245
  _insertChild(index, items) {
284
246
  const nodes = normalize(items);
@@ -296,10 +258,9 @@ export default class DocumentFragment extends TypeCheckable {
296
258
  * and sets {@link module:engine/model/node~Node#parent parent} of these nodes to `null`.
297
259
  *
298
260
  * @internal
299
- * @protected
300
- * @param {Number} index Index of the first node to remove.
301
- * @param {Number} [howMany=1] Number of nodes to remove.
302
- * @returns {Array.<module:engine/model/node~Node>} Array containing removed nodes.
261
+ * @param index Index of the first node to remove.
262
+ * @param howMany Number of nodes to remove.
263
+ * @returns Array containing removed nodes.
303
264
  */
304
265
  _removeChildren(index, howMany = 1) {
305
266
  const nodes = this._children._removeNodes(index, howMany);
@@ -309,28 +270,14 @@ export default class DocumentFragment extends TypeCheckable {
309
270
  return nodes;
310
271
  }
311
272
  }
312
- /**
313
- * Checks whether this object is of the given type.
314
- *
315
- * docFrag.is( 'documentFragment' ); // -> true
316
- * docFrag.is( 'model:documentFragment' ); // -> true
317
- *
318
- * docFrag.is( 'view:documentFragment' ); // -> false
319
- * docFrag.is( 'element' ); // -> false
320
- * docFrag.is( 'node' ); // -> false
321
- *
322
- * {@link module:engine/model/node~Node#is Check the entire list of model objects} which implement the `is()` method.
323
- *
324
- * @param {String} type
325
- * @returns {Boolean}
326
- */
273
+ // The magic of type inference using `is` method is centralized in `TypeCheckable` class.
274
+ // Proper overload would interfere with that.
327
275
  DocumentFragment.prototype.is = function (type) {
328
276
  return type === 'documentFragment' || type === 'model:documentFragment';
329
277
  };
330
- // Converts strings to Text and non-iterables to arrays.
331
- //
332
- // @param {String|module:engine/model/item~Item|Iterable.<module:engine/model/item~Item>}
333
- // @returns {Iterable.<module:engine/model/node~Node>}
278
+ /**
279
+ * Converts strings to Text and non-iterables to arrays.
280
+ */
334
281
  function normalize(nodes) {
335
282
  // Separate condition because string is iterable.
336
283
  if (typeof nodes == 'string') {