@ckeditor/ckeditor5-engine 35.4.0 → 36.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/LICENSE.md +1 -1
  2. package/package.json +22 -22
  3. package/src/controller/datacontroller.js +5 -1
  4. package/src/controller/editingcontroller.js +1 -1
  5. package/src/conversion/conversion.js +1 -1
  6. package/src/conversion/conversionhelpers.js +1 -1
  7. package/src/conversion/downcastdispatcher.js +1 -1
  8. package/src/conversion/downcasthelpers.js +1 -1
  9. package/src/conversion/mapper.js +1 -1
  10. package/src/conversion/modelconsumable.js +1 -1
  11. package/src/conversion/upcastdispatcher.js +1 -1
  12. package/src/conversion/upcasthelpers.js +8 -1
  13. package/src/conversion/viewconsumable.js +1 -1
  14. package/src/dataprocessor/basichtmlwriter.js +1 -1
  15. package/src/dataprocessor/dataprocessor.js +1 -1
  16. package/src/dataprocessor/htmldataprocessor.js +1 -2
  17. package/src/dataprocessor/htmlwriter.js +1 -1
  18. package/src/dataprocessor/xmldataprocessor.js +1 -1
  19. package/src/dev-utils/model.js +1 -1
  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 +3 -2
  24. package/src/model/batch.js +9 -46
  25. package/src/model/differ.js +81 -174
  26. package/src/model/document.js +36 -92
  27. package/src/model/documentfragment.js +43 -96
  28. package/src/model/documentselection.js +151 -245
  29. package/src/model/element.js +47 -100
  30. package/src/model/history.js +15 -46
  31. package/src/model/item.js +1 -1
  32. package/src/model/liveposition.js +10 -36
  33. package/src/model/liverange.js +13 -36
  34. package/src/model/markercollection.js +40 -111
  35. package/src/model/model.js +212 -289
  36. package/src/model/node.js +35 -125
  37. package/src/model/nodelist.js +11 -39
  38. package/src/model/operation/attributeoperation.js +13 -44
  39. package/src/model/operation/detachoperation.js +3 -16
  40. package/src/model/operation/insertoperation.js +6 -34
  41. package/src/model/operation/markeroperation.js +9 -48
  42. package/src/model/operation/mergeoperation.js +8 -41
  43. package/src/model/operation/moveoperation.js +14 -37
  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 +8 -28
  48. package/src/model/operation/rootattributeoperation.js +18 -47
  49. package/src/model/operation/splitoperation.js +9 -47
  50. package/src/model/operation/transform.js +109 -150
  51. package/src/model/operation/utils.js +36 -50
  52. package/src/model/position.js +117 -228
  53. package/src/model/range.js +145 -200
  54. package/src/model/rootelement.js +8 -47
  55. package/src/model/schema.js +236 -272
  56. package/src/model/selection.js +134 -192
  57. package/src/model/text.js +10 -37
  58. package/src/model/textproxy.js +15 -69
  59. package/src/model/treewalker.js +10 -101
  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 +24 -24
  64. package/src/model/utils/getselectedcontent.js +3 -6
  65. package/src/model/utils/insertcontent.js +36 -129
  66. package/src/model/utils/insertobject.js +19 -21
  67. package/src/model/utils/modifyselection.js +23 -33
  68. package/src/model/utils/selection-post-fixer.js +53 -59
  69. package/src/model/writer.js +208 -314
  70. package/src/view/attributeelement.js +1 -1
  71. package/src/view/containerelement.js +1 -1
  72. package/src/view/datatransfer.js +25 -28
  73. package/src/view/document.js +1 -17
  74. package/src/view/documentfragment.js +49 -1
  75. package/src/view/documentselection.js +1 -1
  76. package/src/view/domconverter.js +4 -3
  77. package/src/view/downcastwriter.js +1 -1
  78. package/src/view/editableelement.js +1 -1
  79. package/src/view/element.js +5 -5
  80. package/src/view/elementdefinition.js +1 -1
  81. package/src/view/emptyelement.js +1 -1
  82. package/src/view/filler.js +1 -1
  83. package/src/view/item.js +1 -1
  84. package/src/view/matcher.js +1 -1
  85. package/src/view/node.js +1 -1
  86. package/src/view/observer/arrowkeysobserver.js +1 -1
  87. package/src/view/observer/bubblingemittermixin.js +1 -1
  88. package/src/view/observer/bubblingeventinfo.js +1 -1
  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 +1 -1
  94. package/src/view/observer/focusobserver.js +22 -4
  95. package/src/view/observer/inputobserver.js +1 -1
  96. package/src/view/observer/keyobserver.js +1 -1
  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 +1 -1
  100. package/src/view/observer/selectionobserver.js +13 -2
  101. package/src/view/observer/tabobserver.js +1 -1
  102. package/src/view/placeholder.js +1 -1
  103. package/src/view/position.js +1 -1
  104. package/src/view/range.js +1 -1
  105. package/src/view/rawelement.js +1 -1
  106. package/src/view/renderer.js +1 -14
  107. package/src/view/rooteditableelement.js +1 -1
  108. package/src/view/selection.js +1 -1
  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 +1 -1
  117. package/src/view/treewalker.js +1 -1
  118. package/src/view/typecheckable.js +1 -1
  119. package/src/view/uielement.js +1 -1
  120. package/src/view/upcastwriter.js +1 -1
  121. package/src/view/view.js +5 -5
  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
  /**
@@ -27,47 +27,14 @@ import { CKEditorError, ObservableMixin } from '@ckeditor/ckeditor5-utils';
27
27
  /**
28
28
  * Editor's data model. Read about the model in the
29
29
  * {@glink framework/guides/architecture/editing-engine engine architecture guide}.
30
- *
31
- * @mixes module:utils/observablemixin~ObservableMixin
32
30
  */
33
31
  export default class Model extends ObservableMixin() {
34
32
  constructor() {
35
33
  super();
36
- /**
37
- * Model's marker collection.
38
- *
39
- * @readonly
40
- * @member {module:engine/model/markercollection~MarkerCollection}
41
- */
42
34
  this.markers = new MarkerCollection();
43
- /**
44
- * Model's document.
45
- *
46
- * @readonly
47
- * @member {module:engine/model/document~Document}
48
- */
49
35
  this.document = new Document(this);
50
- /**
51
- * Model's schema.
52
- *
53
- * @readonly
54
- * @member {module:engine/model/schema~Schema}
55
- */
56
36
  this.schema = new Schema();
57
- /**
58
- * All callbacks added by {@link module:engine/model/model~Model#change} or
59
- * {@link module:engine/model/model~Model#enqueueChange} methods waiting to be executed.
60
- *
61
- * @private
62
- * @type {Array.<Function>}
63
- */
64
37
  this._pendingChanges = [];
65
- /**
66
- * The last created and currently used writer instance.
67
- *
68
- * @private
69
- * @member {module:engine/model/writer~Writer}
70
- */
71
38
  this._currentWriter = null;
72
39
  ['insertContent', 'insertObject', 'deleteContent', 'modifySelection', 'getSelectedContent', 'applyOperation']
73
40
  .forEach(methodName => this.decorate(methodName));
@@ -137,34 +104,40 @@ export default class Model extends ObservableMixin() {
137
104
  * the {@link module:engine/model/document~Document#selection document's selection}, and
138
105
  * {@link module:engine/model/model~Model#markers model markers}.
139
106
  *
140
- * model.change( writer => {
141
- * writer.insertText( 'foo', paragraph, 'end' );
142
- * } );
107
+ * ```ts
108
+ * model.change( writer => {
109
+ * writer.insertText( 'foo', paragraph, 'end' );
110
+ * } );
111
+ * ```
143
112
  *
144
113
  * All changes inside the change block use the same {@link module:engine/model/batch~Batch} so they are combined
145
114
  * into a single undo step.
146
115
  *
147
- * model.change( writer => {
148
- * writer.insertText( 'foo', paragraph, 'end' ); // foo.
116
+ * ```ts
117
+ * model.change( writer => {
118
+ * writer.insertText( 'foo', paragraph, 'end' ); // foo.
149
119
  *
150
- * model.change( writer => {
151
- * writer.insertText( 'bar', paragraph, 'end' ); // foobar.
152
- * } );
120
+ * model.change( writer => {
121
+ * writer.insertText( 'bar', paragraph, 'end' ); // foobar.
122
+ * } );
153
123
  *
154
- * writer.insertText( 'bom', paragraph, 'end' ); // foobarbom.
155
- * } );
124
+ * writer.insertText( 'bom', paragraph, 'end' ); // foobarbom.
125
+ * } );
126
+ * ```
156
127
  *
157
128
  * The callback of the `change()` block is executed synchronously.
158
129
  *
159
130
  * You can also return a value from the change block.
160
131
  *
161
- * const img = model.change( writer => {
162
- * return writer.createElement( 'img' );
163
- * } );
132
+ * ```ts
133
+ * const img = model.change( writer => {
134
+ * return writer.createElement( 'img' );
135
+ * } );
136
+ * ```
164
137
  *
165
138
  * @see #enqueueChange
166
- * @param {Function} callback Callback function which may modify the model.
167
- * @returns {*} Value returned by the callback.
139
+ * @typeParam TReturn The return type of the provided callback.
140
+ * @param callback Callback function which may modify the model.
168
141
  */
169
142
  change(callback) {
170
143
  try {
@@ -184,49 +157,6 @@ export default class Model extends ObservableMixin() {
184
157
  CKEditorError.rethrowUnexpectedError(err, this);
185
158
  }
186
159
  }
187
- /**
188
- * The `enqueueChange()` method performs similar task as the {@link #change `change()` method}, with two major differences.
189
- *
190
- * First, the callback of `enqueueChange()` is executed when all other enqueued changes are done. It might be executed
191
- * immediately if it is not nested in any other change block, but if it is nested in another (enqueue)change block,
192
- * it will be delayed and executed after the outermost block.
193
- *
194
- * model.change( writer => {
195
- * console.log( 1 );
196
- *
197
- * model.enqueueChange( writer => {
198
- * console.log( 2 );
199
- * } );
200
- *
201
- * console.log( 3 );
202
- * } ); // Will log: 1, 3, 2.
203
- *
204
- * In addition to that, the changes enqueued with `enqueueChange()` will be converted separately from the changes
205
- * done in the outer `change()` block.
206
- *
207
- * Second, it lets you define the {@link module:engine/model/batch~Batch} into which you want to add your changes.
208
- * By default, a new batch with the default {@link module:engine/model/batch~Batch#constructor batch type} is created.
209
- * In the sample above, the `change` and `enqueueChange` blocks will use a different batch (and a different
210
- * {@link module:engine/model/writer~Writer} instance since each of them operates on a separate batch).
211
- *
212
- * model.enqueueChange( { isUndoable: false }, writer => {
213
- * writer.insertText( 'foo', paragraph, 'end' );
214
- * } );
215
- *
216
- * When using the `enqueueChange()` block you can also add some changes to the batch you used before.
217
- *
218
- * model.enqueueChange( batch, writer => {
219
- * writer.insertText( 'foo', paragraph, 'end' );
220
- * } );
221
- *
222
- * In order to make a nested `enqueueChange()` create a single undo step together with the changes done in the outer `change()`
223
- * block, you can obtain the batch instance from the {@link module:engine/model/writer~Writer#batch writer} of the outer block.
224
- *
225
- * @param {module:engine/model/batch~Batch|Object} [batchOrType] A batch or a
226
- * {@link module:engine/model/batch~Batch#constructor batch type} that should be used in the callback. If not defined, a new batch with
227
- * the default type will be created.
228
- * @param {Function} callback Callback function which may modify the model.
229
- */
230
160
  enqueueChange(batchOrType, callback) {
231
161
  try {
232
162
  if (!batchOrType) {
@@ -251,7 +181,7 @@ export default class Model extends ObservableMixin() {
251
181
  }
252
182
  }
253
183
  /**
254
- * {@link module:utils/observablemixin~ObservableMixin#decorate Decorated} function for applying
184
+ * {@link module:utils/observablemixin~Observable#decorate Decorated} function for applying
255
185
  * {@link module:engine/model/operation/operation~Operation operations} to the model.
256
186
  *
257
187
  * This is a low-level way of changing the model. It is exposed for very specific use cases (like the undo feature).
@@ -259,7 +189,7 @@ export default class Model extends ObservableMixin() {
259
189
  * See also {@glink framework/guides/architecture/editing-engine#changing-the-model Changing the model} section
260
190
  * of the {@glink framework/guides/architecture/editing-engine Editing architecture} guide.
261
191
  *
262
- * @param {module:engine/model/operation/operation~Operation} operation The operation to apply.
192
+ * @param operation The operation to apply.
263
193
  */
264
194
  applyOperation(operation) {
265
195
  // @if CK_DEBUG_ENGINE // console.log( 'Applying ' + operation );
@@ -316,104 +246,112 @@ export default class Model extends ObservableMixin() {
316
246
  *
317
247
  * Using `insertContent()` with a manually created model structure:
318
248
  *
319
- * // Let's create a document fragment containing such content as:
320
- * //
321
- * // <paragraph>foo</paragraph>
322
- * // <blockQuote>
323
- * // <paragraph>bar</paragraph>
324
- * // </blockQuote>
325
- * const docFrag = editor.model.change( writer => {
326
- * const p1 = writer.createElement( 'paragraph' );
327
- * const p2 = writer.createElement( 'paragraph' );
328
- * const blockQuote = writer.createElement( 'blockQuote' );
329
- * const docFrag = writer.createDocumentFragment();
330
- *
331
- * writer.append( p1, docFrag );
332
- * writer.append( blockQuote, docFrag );
333
- * writer.append( p2, blockQuote );
334
- * writer.insertText( 'foo', p1 );
335
- * writer.insertText( 'bar', p2 );
336
- *
337
- * return docFrag;
338
- * } );
339
- *
340
- * // insertContent() does not have to be used in a change() block. It can, though,
341
- * // so this code could be moved to the callback defined above.
342
- * editor.model.insertContent( docFrag );
249
+ * ```ts
250
+ * // Let's create a document fragment containing such content as:
251
+ * //
252
+ * // <paragraph>foo</paragraph>
253
+ * // <blockQuote>
254
+ * // <paragraph>bar</paragraph>
255
+ * // </blockQuote>
256
+ * const docFrag = editor.model.change( writer => {
257
+ * const p1 = writer.createElement( 'paragraph' );
258
+ * const p2 = writer.createElement( 'paragraph' );
259
+ * const blockQuote = writer.createElement( 'blockQuote' );
260
+ * const docFrag = writer.createDocumentFragment();
261
+ *
262
+ * writer.append( p1, docFrag );
263
+ * writer.append( blockQuote, docFrag );
264
+ * writer.append( p2, blockQuote );
265
+ * writer.insertText( 'foo', p1 );
266
+ * writer.insertText( 'bar', p2 );
267
+ *
268
+ * return docFrag;
269
+ * } );
270
+ *
271
+ * // insertContent() does not have to be used in a change() block. It can, though,
272
+ * // so this code could be moved to the callback defined above.
273
+ * editor.model.insertContent( docFrag );
274
+ * ```
343
275
  *
344
276
  * Using `insertContent()` with an HTML string converted to a model document fragment (similar to the pasting mechanism):
345
277
  *
346
- * // You can create your own HtmlDataProcessor instance or use editor.data.processor
347
- * // if you have not overridden the default one (which is the HtmlDataProcessor instance).
348
- * const htmlDP = new HtmlDataProcessor( viewDocument );
349
- *
350
- * // Convert an HTML string to a view document fragment:
351
- * const viewFragment = htmlDP.toView( htmlString );
352
- *
353
- * // Convert the view document fragment to a model document fragment
354
- * // in the context of $root. This conversion takes the schema into
355
- * // account so if, for example, the view document fragment contained a bare text node,
356
- * // this text node cannot be a child of $root, so it will be automatically
357
- * // wrapped with a <paragraph>. You can define the context yourself (in the second parameter),
358
- * // and e.g. convert the content like it would happen in a <paragraph>.
359
- * // Note: The clipboard feature uses a custom context called $clipboardHolder
360
- * // which has a loosened schema.
361
- * const modelFragment = editor.data.toModel( viewFragment );
362
- *
363
- * editor.model.insertContent( modelFragment );
278
+ * ```ts
279
+ * // You can create your own HtmlDataProcessor instance or use editor.data.processor
280
+ * // if you have not overridden the default one (which is the HtmlDataProcessor instance).
281
+ * const htmlDP = new HtmlDataProcessor( viewDocument );
282
+ *
283
+ * // Convert an HTML string to a view document fragment:
284
+ * const viewFragment = htmlDP.toView( htmlString );
285
+ *
286
+ * // Convert the view document fragment to a model document fragment
287
+ * // in the context of $root. This conversion takes the schema into
288
+ * // account so if, for example, the view document fragment contained a bare text node,
289
+ * // this text node cannot be a child of $root, so it will be automatically
290
+ * // wrapped with a <paragraph>. You can define the context yourself (in the second parameter),
291
+ * // and e.g. convert the content like it would happen in a <paragraph>.
292
+ * // Note: The clipboard feature uses a custom context called $clipboardHolder
293
+ * // which has a loosened schema.
294
+ * const modelFragment = editor.data.toModel( viewFragment );
295
+ *
296
+ * editor.model.insertContent( modelFragment );
297
+ * ```
364
298
  *
365
299
  * By default this method will use the document selection but it can also be used with a position, range or selection instance.
366
300
  *
367
- * // Insert text at the current document selection position.
368
- * editor.model.change( writer => {
369
- * editor.model.insertContent( writer.createText( 'x' ) );
370
- * } );
301
+ * ```ts
302
+ * // Insert text at the current document selection position.
303
+ * editor.model.change( writer => {
304
+ * editor.model.insertContent( writer.createText( 'x' ) );
305
+ * } );
371
306
  *
372
- * // Insert text at a given position - the document selection will not be modified.
373
- * editor.model.change( writer => {
374
- * editor.model.insertContent( writer.createText( 'x' ), doc.getRoot(), 2 );
307
+ * // Insert text at a given position - the document selection will not be modified.
308
+ * editor.model.change( writer => {
309
+ * editor.model.insertContent( writer.createText( 'x' ), doc.getRoot(), 2 );
375
310
  *
376
- * // Which is a shorthand for:
377
- * editor.model.insertContent( writer.createText( 'x' ), writer.createPositionAt( doc.getRoot(), 2 ) );
378
- * } );
311
+ * // Which is a shorthand for:
312
+ * editor.model.insertContent( writer.createText( 'x' ), writer.createPositionAt( doc.getRoot(), 2 ) );
313
+ * } );
314
+ * ```
379
315
  *
380
316
  * If you want the document selection to be moved to the inserted content, use the
381
317
  * {@link module:engine/model/writer~Writer#setSelection `setSelection()`} method of the writer after inserting
382
318
  * the content:
383
319
  *
384
- * editor.model.change( writer => {
385
- * const paragraph = writer.createElement( 'paragraph' );
320
+ * ```ts
321
+ * editor.model.change( writer => {
322
+ * const paragraph = writer.createElement( 'paragraph' );
386
323
  *
387
- * // Insert an empty paragraph at the beginning of the root.
388
- * editor.model.insertContent( paragraph, writer.createPositionAt( editor.model.document.getRoot(), 0 ) );
324
+ * // Insert an empty paragraph at the beginning of the root.
325
+ * editor.model.insertContent( paragraph, writer.createPositionAt( editor.model.document.getRoot(), 0 ) );
389
326
  *
390
- * // Move the document selection to the inserted paragraph.
391
- * writer.setSelection( paragraph, 'in' );
392
- * } );
327
+ * // Move the document selection to the inserted paragraph.
328
+ * writer.setSelection( paragraph, 'in' );
329
+ * } );
330
+ * ```
393
331
  *
394
332
  * If an instance of the {@link module:engine/model/selection~Selection model selection} is passed as `selectable`,
395
333
  * the new content will be inserted at the passed selection (instead of document selection):
396
334
  *
397
- * editor.model.change( writer => {
398
- * // Create a selection in a paragraph that will be used as a place of insertion.
399
- * const selection = writer.createSelection( paragraph, 'in' );
335
+ * ```ts
336
+ * editor.model.change( writer => {
337
+ * // Create a selection in a paragraph that will be used as a place of insertion.
338
+ * const selection = writer.createSelection( paragraph, 'in' );
400
339
  *
401
- * // Insert the new text at the created selection.
402
- * editor.model.insertContent( writer.createText( 'x' ), selection );
340
+ * // Insert the new text at the created selection.
341
+ * editor.model.insertContent( writer.createText( 'x' ), selection );
403
342
  *
404
- * // insertContent() modifies the passed selection instance so it can be used to set the document selection.
405
- * // Note: This is not necessary when you passed the document selection to insertContent().
406
- * writer.setSelection( selection );
407
- * } );
343
+ * // insertContent() modifies the passed selection instance so it can be used to set the document selection.
344
+ * // Note: This is not necessary when you passed the document selection to insertContent().
345
+ * writer.setSelection( selection );
346
+ * } );
347
+ * ```
408
348
  *
409
349
  * @fires insertContent
410
- * @param {module:engine/model/documentfragment~DocumentFragment|module:engine/model/item~Item} content The content to insert.
411
- * @param {module:engine/model/selection~Selectable} [selectable=model.document.selection]
412
- * The selection into which the content should be inserted. If not provided the current model document selection will be used.
413
- * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] To be used when a model item was passed as `selectable`.
350
+ * @param content The content to insert.
351
+ * @param selectable The selection into which the content should be inserted.
352
+ * If not provided the current model document selection will be used.
353
+ * @param placeOrOffset To be used when a model item was passed as `selectable`.
414
354
  * This param defines a position in relation to that item.
415
- * @returns {module:engine/model/range~Range} Range which contains all the performed changes. This is a range that, if removed,
416
- * would return the model to the state before the insertion. If no changes were preformed by `insertContent`, returns a range collapsed
417
355
  * at the insertion position.
418
356
  */
419
357
  insertContent(content, selectable, placeOrOffset) {
@@ -446,56 +384,60 @@ export default class Model extends ObservableMixin() {
446
384
  *
447
385
  * Use the following code to insert an object at the current selection and keep the selection on the inserted element:
448
386
  *
449
- * const rawHtmlEmbedElement = writer.createElement( 'rawHtml' );
387
+ * ```ts
388
+ * const rawHtmlEmbedElement = writer.createElement( 'rawHtml' );
450
389
  *
451
- * model.insertObject( rawHtmlEmbedElement, null, null, {
452
- * setSelection: 'on'
453
- * } );
390
+ * model.insertObject( rawHtmlEmbedElement, null, null, {
391
+ * setSelection: 'on'
392
+ * } );
393
+ * ```
454
394
  *
455
395
  * Use the following code to insert an object at the current selection and nudge the selection after the inserted object:
456
396
  *
457
- * const pageBreakElement = writer.createElement( 'pageBreak' );
397
+ * ```ts
398
+ * const pageBreakElement = writer.createElement( 'pageBreak' );
458
399
  *
459
- * model.insertObject( pageBreakElement, null, null, {
460
- * setSelection: 'after'
461
- * } );
400
+ * model.insertObject( pageBreakElement, null, null, {
401
+ * setSelection: 'after'
402
+ * } );
403
+ * ```
462
404
  *
463
405
  * Use the following code to insert an object at the current selection and avoid splitting the content (non-destructive insertion):
464
406
  *
465
- * const tableElement = writer.createElement( 'table' );
407
+ * ```ts
408
+ * const tableElement = writer.createElement( 'table' );
466
409
  *
467
- * model.insertObject( tableElement, null, null, {
468
- * findOptimalPosition: 'auto'
469
- * } );
410
+ * model.insertObject( tableElement, null, null, {
411
+ * findOptimalPosition: 'auto'
412
+ * } );
413
+ * ```
470
414
  *
471
415
  * Use the following code to insert an object at the specific range (also: replace the content of the range):
472
416
  *
473
- * const tableElement = writer.createElement( 'table' );
474
- * const range = model.createRangeOn( model.document.getRoot().getChild( 1 ) );
417
+ * ```ts
418
+ * const tableElement = writer.createElement( 'table' );
419
+ * const range = model.createRangeOn( model.document.getRoot().getChild( 1 ) );
475
420
  *
476
- * model.insertObject( tableElement, range );
421
+ * model.insertObject( tableElement, range );
422
+ * ```
477
423
  *
478
- * @param {module:engine/model/element~Element} object An object to be inserted into the model document.
479
- * @param {module:engine/model/selection~Selectable} [selectable=model.document.selection]
480
- * A selectable where the content should be inserted. If not specified, the current
424
+ * @param object An object to be inserted into the model document.
425
+ * @param selectable A selectable where the content should be inserted. If not specified, the current
481
426
  * {@link module:engine/model/document~Document#selection document selection} will be used instead.
482
- * @param {Number|'before'|'end'|'after'|'on'|'in'} placeOrOffset Specifies the exact place or offset for the insertion to take place,
483
- * relative to `selectable`.
484
- * @param {Object} [options] Additional options.
485
- * @param {'auto'|'before'|'after'} [options.findOptimalPosition] An option that, when set, adjusts the insertion position (relative to
427
+ * @param placeOrOffset Specifies the exact place or offset for the insertion to take place, relative to `selectable`.
428
+ * @param options Additional options.
429
+ * @param options.findOptimalPosition An option that, when set, adjusts the insertion position (relative to
486
430
  * `selectable` and `placeOrOffset`) so that the content of `selectable` is not split upon insertion (a.k.a. non-destructive insertion).
487
431
  * * When `'auto'`, the algorithm will decide whether to insert the object before or after `selectable` to avoid content splitting.
488
432
  * * When `'before'`, the closest position before `selectable` will be used that will not result in content splitting.
489
433
  * * When `'after'`, the closest position after `selectable` will be used that will not result in content splitting.
490
434
  *
491
435
  * Note that this option only works for block objects. Inline objects are inserted into text and do not split blocks.
492
- * @param {'on'|'after'} [options.setSelection] An option that, when set, moves the
436
+ * @param options.setSelection An option that, when set, moves the
493
437
  * {@link module:engine/model/document~Document#selection document selection} after inserting the object.
494
438
  * * When `'on'`, the document selection will be set on the inserted object.
495
439
  * * When `'after'`, the document selection will move to the closest text node after the inserted object. If there is no
496
440
  * such text node, a paragraph will be created and the document selection will be moved inside it.
497
- * @returns {module:engine/model/range~Range} A range which contains all the performed changes. This is a range that, if removed,
498
- * would return the model to the state before the insertion. If no changes were preformed by `insertObject()`, returns a range collapsed
499
441
  * at the insertion position.
500
442
  */
501
443
  insertObject(object, selectable, placeOrOffset, options) {
@@ -513,10 +455,8 @@ export default class Model extends ObservableMixin() {
513
455
  * That needs to be done in order to ensure that other features which use `deleteContent()` will work well with tables.
514
456
  *
515
457
  * @fires deleteContent
516
- * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
517
- * Selection of which the content should be deleted.
518
- * @param {Object} [options]
519
- * @param {Boolean} [options.leaveUnmerged=false] Whether to merge elements after removing the content of the selection.
458
+ * @param selection Selection of which the content should be deleted.
459
+ * @param options.leaveUnmerged Whether to merge elements after removing the content of the selection.
520
460
  *
521
461
  * For example `<heading1>x[x</heading1><paragraph>y]y</paragraph>` will become:
522
462
  *
@@ -526,7 +466,7 @@ export default class Model extends ObservableMixin() {
526
466
  * Note: {@link module:engine/model/schema~Schema#isObject object} and {@link module:engine/model/schema~Schema#isLimit limit}
527
467
  * elements will not be merged.
528
468
  *
529
- * @param {Boolean} [options.doNotResetEntireContent=false] Whether to skip replacing the entire content with a
469
+ * @param options.doNotResetEntireContent Whether to skip replacing the entire content with a
530
470
  * paragraph when the entire content was selected.
531
471
  *
532
472
  * For example `<heading1>[x</heading1><paragraph>y]</paragraph>` will become:
@@ -534,7 +474,7 @@ export default class Model extends ObservableMixin() {
534
474
  * * `<paragraph>^</paragraph>` with the option disabled (`doNotResetEntireContent == false`)
535
475
  * * `<heading1>^</heading1>` with enabled (`doNotResetEntireContent == true`)
536
476
  *
537
- * @param {Boolean} [options.doNotAutoparagraph=false] Whether to create a paragraph if after content deletion selection is moved
477
+ * @param options.doNotAutoparagraph Whether to create a paragraph if after content deletion selection is moved
538
478
  * to a place where text cannot be inserted.
539
479
  *
540
480
  * For example `<paragraph>x</paragraph>[<imageBlock src="foo.jpg"></imageBlock>]` will become:
@@ -546,7 +486,7 @@ export default class Model extends ObservableMixin() {
546
486
  *
547
487
  * `[<imageBlock src="foo.jpg"></imageBlock>]` -> `<paragraph>[]</paragraph>`.
548
488
  *
549
- * @param {'forward'|'backward'} [options.direction='backward'] The direction in which the content is being consumed.
489
+ * @param options.direction The direction in which the content is being consumed.
550
490
  * Deleting backward corresponds to using the <kbd>Backspace</kbd> key, while deleting content forward corresponds to
551
491
  * the <kbd>Shift</kbd>+<kbd>Backspace</kbd> keystroke.
552
492
  */
@@ -576,12 +516,10 @@ export default class Model extends ObservableMixin() {
576
516
  * **Note:** if you extend a forward selection in a backward direction you will in fact shrink it.
577
517
  *
578
518
  * @fires modifySelection
579
- * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
580
- * The selection to modify.
581
- * @param {Object} [options]
582
- * @param {'forward'|'backward'} [options.direction='forward'] The direction in which the selection should be modified.
583
- * @param {'character'|'codePoint'|'word'} [options.unit='character'] The unit by which selection should be modified.
584
- * @param {Boolean} [options.treatEmojiAsSingleUnit=false] Whether multi-characer emoji sequences should be handled as single unit.
519
+ * @param selection The selection to modify.
520
+ * @param options.direction The direction in which the selection should be modified.
521
+ * @param options.unit The unit by which selection should be modified.
522
+ * @param options.treatEmojiAsSingleUnit Whether multi-characer emoji sequences should be handled as single unit.
585
523
  */
586
524
  modifySelection(selection, options) {
587
525
  modifySelection(this, selection, options);
@@ -594,8 +532,8 @@ export default class Model extends ObservableMixin() {
594
532
  * ```html
595
533
  * <paragraph>x</paragraph>
596
534
  * <blockQuote>
597
- * <paragraph>y</paragraph>
598
- * <heading1>fir[st</heading1>
535
+ * <paragraph>y</paragraph>
536
+ * <heading1>fir[st</heading1>
599
537
  * </blockQuote>
600
538
  * <paragraph>se]cond</paragraph>
601
539
  * <paragraph>z</paragraph>
@@ -605,15 +543,13 @@ export default class Model extends ObservableMixin() {
605
543
  *
606
544
  * ```html
607
545
  * <blockQuote>
608
- * <heading1>st</heading1>
546
+ * <heading1>st</heading1>
609
547
  * </blockQuote>
610
548
  * <paragraph>se</paragraph>
611
549
  * ```
612
550
  *
613
551
  * @fires getSelectedContent
614
- * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
615
- * The selection of which content will be returned.
616
- * @returns {module:engine/model/documentfragment~DocumentFragment}
552
+ * @param selection The selection of which content will be returned.
617
553
  */
618
554
  getSelectedContent(selection) {
619
555
  return getSelectedContent(this, selection);
@@ -634,11 +570,9 @@ export default class Model extends ObservableMixin() {
634
570
  * However, a range containing an `<imageBlock></imageBlock>` (which would normally be marked in the schema as an object element)
635
571
  * is considered non-empty.
636
572
  *
637
- * @param {module:engine/model/range~Range|module:engine/model/element~Element} rangeOrElement Range or element to check.
638
- * @param {Object} [options]
639
- * @param {Boolean} [options.ignoreWhitespaces] Whether text node with whitespaces only should be considered empty.
640
- * @param {Boolean} [options.ignoreMarkers] Whether markers should be ignored.
641
- * @returns {Boolean}
573
+ * @param rangeOrElement Range or element to check.
574
+ * @param options.ignoreWhitespaces Whether text node with whitespaces only should be considered empty.
575
+ * @param options.ignoreMarkers Whether markers should be ignored.
642
576
  */
643
577
  hasContent(rangeOrElement, options = {}) {
644
578
  const range = rangeOrElement instanceof ModelRange ? rangeOrElement : ModelRange._createIn(rangeOrElement);
@@ -677,11 +611,9 @@ export default class Model extends ObservableMixin() {
677
611
  * Note: This method is also available as
678
612
  * {@link module:engine/model/writer~Writer#createPositionFromPath `Writer#createPositionFromPath()`}.
679
613
  *
680
- * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} root Root of the position.
681
- * @param {Array.<Number>} path Position path. See {@link module:engine/model/position~Position#path}.
682
- * @param {module:engine/model/position~PositionStickiness} [stickiness='toNone'] Position stickiness.
683
- * See {@link module:engine/model/position~PositionStickiness}.
684
- * @returns {module:engine/model/position~Position}
614
+ * @param root Root of the position.
615
+ * @param path Position path. See {@link module:engine/model/position~Position#path}.
616
+ * @param stickiness Position stickiness. See {@link module:engine/model/position~PositionStickiness}.
685
617
  */
686
618
  createPositionFromPath(root, path, stickiness) {
687
619
  return new ModelPosition(root, path, stickiness);
@@ -703,9 +635,8 @@ export default class Model extends ObservableMixin() {
703
635
  * Note: This method is also available as
704
636
  * {@link module:engine/model/writer~Writer#createPositionAt `Writer#createPositionAt()`},
705
637
  *
706
- * @param {module:engine/model/item~Item|module:engine/model/position~Position} itemOrPosition
707
- * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when
708
- * first parameter is a {@link module:engine/model/item~Item model item}.
638
+ * @param itemOrPosition
639
+ * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~Item model item}.
709
640
  */
710
641
  createPositionAt(itemOrPosition, offset) {
711
642
  return ModelPosition._createAt(itemOrPosition, offset);
@@ -716,8 +647,7 @@ export default class Model extends ObservableMixin() {
716
647
  * Note: This method is also available as
717
648
  * {@link module:engine/model/writer~Writer#createPositionAfter `Writer#createPositionAfter()`}.
718
649
  *
719
- * @param {module:engine/model/item~Item} item Item after which the position should be placed.
720
- * @returns {module:engine/model/position~Position}
650
+ * @param item Item after which the position should be placed.
721
651
  */
722
652
  createPositionAfter(item) {
723
653
  return ModelPosition._createAfter(item);
@@ -728,8 +658,7 @@ export default class Model extends ObservableMixin() {
728
658
  * Note: This method is also available as
729
659
  * {@link module:engine/model/writer~Writer#createPositionBefore `Writer#createPositionBefore()`}.
730
660
  *
731
- * @param {module:engine/model/item~Item} item Item before which the position should be placed.
732
- * @returns {module:engine/model/position~Position}
661
+ * @param item Item before which the position should be placed.
733
662
  */
734
663
  createPositionBefore(item) {
735
664
  return ModelPosition._createBefore(item);
@@ -740,14 +669,14 @@ export default class Model extends ObservableMixin() {
740
669
  * Note: This method is also available as
741
670
  * {@link module:engine/model/writer~Writer#createRange `Writer#createRange()`}:
742
671
  *
743
- * model.change( writer => {
744
- * const range = writer.createRange( start, end );
745
- * } );
672
+ * ```ts
673
+ * model.change( writer => {
674
+ * const range = writer.createRange( start, end );
675
+ * } );
676
+ * ```
746
677
  *
747
- * @param {module:engine/model/position~Position} start Start position.
748
- * @param {module:engine/model/position~Position} [end] End position. If not set, the range will be collapsed
749
- * to the `start` position.
750
- * @returns {module:engine/model/range~Range}
678
+ * @param start Start position.
679
+ * @param end End position. If not set, the range will be collapsed to the `start` position.
751
680
  */
752
681
  createRange(start, end) {
753
682
  return new ModelRange(start, end);
@@ -759,12 +688,13 @@ export default class Model extends ObservableMixin() {
759
688
  * Note: This method is also available as
760
689
  * {@link module:engine/model/writer~Writer#createRangeIn `Writer#createRangeIn()`}:
761
690
  *
762
- * model.change( writer => {
763
- * const range = writer.createRangeIn( paragraph );
764
- * } );
691
+ * ```ts
692
+ * model.change( writer => {
693
+ * const range = writer.createRangeIn( paragraph );
694
+ * } );
695
+ * ```
765
696
  *
766
- * @param {module:engine/model/element~Element} element Element which is a parent for the range.
767
- * @returns {module:engine/model/range~Range}
697
+ * @param element Element which is a parent for the range.
768
698
  */
769
699
  createRangeIn(element) {
770
700
  return ModelRange._createIn(element);
@@ -775,12 +705,13 @@ export default class Model extends ObservableMixin() {
775
705
  * Note: This method is also available on `writer` instance as
776
706
  * {@link module:engine/model/writer~Writer#createRangeOn `Writer.createRangeOn()`}:
777
707
  *
778
- * model.change( writer => {
779
- * const range = writer.createRangeOn( paragraph );
780
- * } );
708
+ * ```ts
709
+ * model.change( writer => {
710
+ * const range = writer.createRangeOn( paragraph );
711
+ * } );
712
+ * ```
781
713
  *
782
- * @param {module:engine/model/item~Item} item
783
- * @returns {module:engine/model/range~Range}
714
+ * @param item
784
715
  */
785
716
  createRangeOn(item) {
786
717
  return ModelRange._createOn(item);
@@ -792,53 +723,49 @@ export default class Model extends ObservableMixin() {
792
723
  * Note: This method is also available as
793
724
  * {@link module:engine/model/writer~Writer#createSelection `Writer#createSelection()`}.
794
725
  *
795
- * // Creates empty selection without ranges.
796
- * const selection = writer.createSelection();
726
+ * ```ts
727
+ * // Creates empty selection without ranges.
728
+ * const selection = writer.createSelection();
797
729
  *
798
- * // Creates selection at the given range.
799
- * const range = writer.createRange( start, end );
800
- * const selection = writer.createSelection( range );
730
+ * // Creates selection at the given range.
731
+ * const range = writer.createRange( start, end );
732
+ * const selection = writer.createSelection( range );
801
733
  *
802
- * // Creates selection at the given ranges
803
- * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];
804
- * const selection = writer.createSelection( ranges );
734
+ * // Creates selection at the given ranges
735
+ * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];
736
+ * const selection = writer.createSelection( ranges );
805
737
  *
806
- * // Creates selection from the other selection.
807
- * // Note: It doesn't copies selection attributes.
808
- * const otherSelection = writer.createSelection();
809
- * const selection = writer.createSelection( otherSelection );
738
+ * // Creates selection from the other selection.
739
+ * // Note: It doesn't copies selection attributes.
740
+ * const otherSelection = writer.createSelection();
741
+ * const selection = writer.createSelection( otherSelection );
810
742
  *
811
- * // Creates selection from the given document selection.
812
- * // Note: It doesn't copies selection attributes.
813
- * const documentSelection = model.document.selection;
814
- * const selection = writer.createSelection( documentSelection );
743
+ * // Creates selection from the given document selection.
744
+ * // Note: It doesn't copies selection attributes.
745
+ * const documentSelection = model.document.selection;
746
+ * const selection = writer.createSelection( documentSelection );
815
747
  *
816
- * // Creates selection at the given position.
817
- * const position = writer.createPositionFromPath( root, path );
818
- * const selection = writer.createSelection( position );
748
+ * // Creates selection at the given position.
749
+ * const position = writer.createPositionFromPath( root, path );
750
+ * const selection = writer.createSelection( position );
819
751
  *
820
- * // Creates selection at the given offset in the given element.
821
- * const paragraph = writer.createElement( 'paragraph' );
822
- * const selection = writer.createSelection( paragraph, offset );
752
+ * // Creates selection at the given offset in the given element.
753
+ * const paragraph = writer.createElement( 'paragraph' );
754
+ * const selection = writer.createSelection( paragraph, offset );
823
755
  *
824
- * // Creates a range inside an {@link module:engine/model/element~Element element} which starts before the
825
- * // first child of that element and ends after the last child of that element.
826
- * const selection = writer.createSelection( paragraph, 'in' );
756
+ * // Creates a range inside an {@link module:engine/model/element~Element element} which starts before the
757
+ * // first child of that element and ends after the last child of that element.
758
+ * const selection = writer.createSelection( paragraph, 'in' );
827
759
  *
828
- * // Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends
829
- * // just after the item.
830
- * const selection = writer.createSelection( paragraph, 'on' );
760
+ * // Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends
761
+ * // just after the item.
762
+ * const selection = writer.createSelection( paragraph, 'on' );
831
763
  *
832
- * // Additional options (`'backward'`) can be specified as the last argument.
764
+ * // Additional options (`'backward'`) can be specified as the last argument.
833
765
  *
834
- * // Creates backward selection.
835
- * const selection = writer.createSelection( range, { backward: true } );
836
- *
837
- * @param {module:engine/model/selection~Selectable} selectable
838
- * @param {Number|'before'|'end'|'after'|'on'|'in'} [optionsOrPlaceOrOffset] Sets place or offset of the selection.
839
- * @param {Object} [options]
840
- * @param {Boolean} [options.backward] Sets this selection instance to be backward.
841
- * @returns {module:engine/model/selection~Selection}
766
+ * // Creates backward selection.
767
+ * const selection = writer.createSelection( range, { backward: true } );
768
+ * ```
842
769
  */
843
770
  createSelection(...args) {
844
771
  return new ModelSelection(...args);
@@ -851,8 +778,7 @@ export default class Model extends ObservableMixin() {
851
778
  * * {@link #change `change()`},
852
779
  * * {@link #enqueueChange `enqueueChange()`}.
853
780
  *
854
- * @param {Object} [type] {@link module:engine/model/batch~Batch#constructor The type} of the batch.
855
- * @returns {module:engine/model/batch~Batch}
781
+ * @param type {@link module:engine/model/batch~Batch#constructor The type} of the batch.
856
782
  */
857
783
  createBatch(type) {
858
784
  return new Batch(type);
@@ -862,8 +788,7 @@ export default class Model extends ObservableMixin() {
862
788
  *
863
789
  * This is an alias for {@link module:engine/model/operation/operationfactory~OperationFactory.fromJSON `OperationFactory.fromJSON()`}.
864
790
  *
865
- * @param {Object} json Deserialized JSON object.
866
- * @returns {module:engine/model/operation/operation~Operation}
791
+ * @param json Deserialized JSON object.
867
792
  */
868
793
  createOperationFromJSON(json) {
869
794
  return OperationFactory.fromJSON(json, this.document);
@@ -879,8 +804,6 @@ export default class Model extends ObservableMixin() {
879
804
  * Common part of {@link module:engine/model/model~Model#change} and {@link module:engine/model/model~Model#enqueueChange}
880
805
  * which calls callbacks and returns array of values returned by these callbacks.
881
806
  *
882
- * @private
883
- * @returns {Array.<*>} Array of values returned by callbacks.
884
807
  */
885
808
  _runPendingChanges() {
886
809
  const ret = [];