@ckeditor/ckeditor5-engine 35.4.0 → 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 +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 +1 -1
  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
  /**
@@ -16,12 +16,9 @@ import Range from '../range';
16
16
  * which change the {@link module:engine/model/model~Model#deleteContent}
17
17
  * method's behavior.
18
18
  *
19
- * @param {module:engine/model/model~Model} model The model in context of which the insertion
20
- * should be performed.
21
- * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
22
- * Selection of which the content should be deleted.
23
- * @param {Object} [options]
24
- * @param {Boolean} [options.leaveUnmerged=false] Whether to merge elements after removing the content of the selection.
19
+ * @param model The model in context of which the insertion should be performed.
20
+ * @param selection Selection of which the content should be deleted.
21
+ * @param options.leaveUnmerged Whether to merge elements after removing the content of the selection.
25
22
  *
26
23
  * For example `<heading>x[x</heading><paragraph>y]y</paragraph>` will become:
27
24
  *
@@ -31,7 +28,7 @@ import Range from '../range';
31
28
  * Note: {@link module:engine/model/schema~Schema#isObject object} and {@link module:engine/model/schema~Schema#isLimit limit}
32
29
  * elements will not be merged.
33
30
  *
34
- * @param {Boolean} [options.doNotResetEntireContent=false] Whether to skip replacing the entire content with a
31
+ * @param options.doNotResetEntireContent Whether to skip replacing the entire content with a
35
32
  * paragraph when the entire content was selected.
36
33
  *
37
34
  * For example `<heading>[x</heading><paragraph>y]</paragraph>` will become:
@@ -39,7 +36,7 @@ import Range from '../range';
39
36
  * * `<paragraph>^</paragraph>` with the option disabled (`doNotResetEntireContent == false`)
40
37
  * * `<heading>^</heading>` with enabled (`doNotResetEntireContent == true`).
41
38
  *
42
- * @param {Boolean} [options.doNotAutoparagraph=false] Whether to create a paragraph if after content deletion selection is moved
39
+ * @param options.doNotAutoparagraph Whether to create a paragraph if after content deletion selection is moved
43
40
  * to a place where text cannot be inserted.
44
41
  *
45
42
  * For example `<paragraph>x</paragraph>[<imageBlock src="foo.jpg"></imageBlock>]` will become:
@@ -114,13 +111,17 @@ export default function deleteContent(model, selection, options = {}) {
114
111
  endPosition.detach();
115
112
  });
116
113
  }
117
- // Returns the live positions for the range adjusted to span only blocks selected from the user perspective. Example:
118
- //
119
- // <heading1>[foo</heading1>
120
- // <paragraph>bar</paragraph>
121
- // <heading1>]abc</heading1> <-- this block is not considered as selected
122
- //
123
- // This is the same behavior as in Selection#getSelectedBlocks() "special case".
114
+ /**
115
+ * Returns the live positions for the range adjusted to span only blocks selected from the user perspective. Example:
116
+ *
117
+ * ```
118
+ * <heading1>[foo</heading1>
119
+ * <paragraph>bar</paragraph>
120
+ * <heading1>]abc</heading1> <-- this block is not considered as selected
121
+ * ```
122
+ *
123
+ * This is the same behavior as in Selection#getSelectedBlocks() "special case".
124
+ */
124
125
  function getLivePositionsForSelectedBlocks(range) {
125
126
  const model = range.root.document.model;
126
127
  const startPosition = range.start;
@@ -154,8 +155,10 @@ function getLivePositionsForSelectedBlocks(range) {
154
155
  LivePosition.fromPosition(endPosition, 'toNext')
155
156
  ];
156
157
  }
157
- // Finds the lowest element in position's ancestors which is a block.
158
- // Returns null if a limit element is encountered before reaching a block element.
158
+ /**
159
+ * Finds the lowest element in position's ancestors which is a block.
160
+ * Returns null if a limit element is encountered before reaching a block element.
161
+ */
159
162
  function getParentBlock(position) {
160
163
  const element = position.parent;
161
164
  const schema = element.root.document.model.schema;
@@ -169,8 +172,10 @@ function getParentBlock(position) {
169
172
  }
170
173
  }
171
174
  }
172
- // This function is a result of reaching the Ballmer's peak for just the right amount of time.
173
- // Even I had troubles documenting it after a while and after reading it again I couldn't believe that it really works.
175
+ /**
176
+ * This function is a result of reaching the Ballmer's peak for just the right amount of time.
177
+ * Even I had troubles documenting it after a while and after reading it again I couldn't believe that it really works.
178
+ */
174
179
  function mergeBranches(writer, startPosition, endPosition) {
175
180
  const model = writer.model;
176
181
  // Verify if there is a need and possibility to merge.
@@ -220,19 +225,26 @@ function mergeBranches(writer, startPosition, endPosition) {
220
225
  mergeBranchesLeft(writer, startPosition, endPosition, startAncestor.parent);
221
226
  }
222
227
  }
223
- // Merging blocks to the left (properties of the left block are preserved).
224
- // Simple example:
225
- // <heading1>foo[</heading1> -> <heading1>foo[bar</heading1>]
226
- // <paragraph>]bar</paragraph> -> --^
227
- //
228
- // Nested example:
229
- // <blockQuote> -> <blockQuote>
230
- // <heading1>foo[</heading1> -> <heading1>foo[bar</heading1>
231
- // </blockQuote> -> </blockQuote>] ^
232
- // <blockBlock> -> |
233
- // <paragraph>]bar</paragraph> -> ---
234
- // </blockBlock> ->
235
- //
228
+ /**
229
+ * Merging blocks to the left (properties of the left block are preserved).
230
+ * Simple example:
231
+ *
232
+ * ```
233
+ * <heading1>foo[</heading1> -> <heading1>foo[bar</heading1>]
234
+ * <paragraph>]bar</paragraph> -> --^
235
+ * ```
236
+ *
237
+ * Nested example:
238
+ *
239
+ * ```
240
+ * <blockQuote> -> <blockQuote>
241
+ * <heading1>foo[</heading1> -> <heading1>foo[bar</heading1>
242
+ * </blockQuote> -> </blockQuote>] ^
243
+ * <blockBlock> -> |
244
+ * <paragraph>]bar</paragraph> -> ---
245
+ * </blockBlock> ->
246
+ * ```
247
+ */
236
248
  function mergeBranchesLeft(writer, startPosition, endPosition, commonAncestor) {
237
249
  const startElement = startPosition.parent;
238
250
  const endElement = endPosition.parent;
@@ -289,19 +301,26 @@ function mergeBranchesLeft(writer, startPosition, endPosition, commonAncestor) {
289
301
  // Continue merging next level (blockQuote with blockBlock in the examples above if it would not be empty and got removed).
290
302
  mergeBranchesLeft(writer, startPosition, endPosition, commonAncestor);
291
303
  }
292
- // Merging blocks to the right (properties of the right block are preserved).
293
- // Simple example:
294
- // <heading1>foo[</heading1> -> --v
295
- // <paragraph>]bar</paragraph> -> [<paragraph>foo]bar</paragraph>
296
- //
297
- // Nested example:
298
- // <blockQuote> ->
299
- // <heading1>foo[</heading1> -> ---
300
- // </blockQuote> -> |
301
- // <blockBlock> -> [<blockBlock> v
302
- // <paragraph>]bar</paragraph> -> <paragraph>foo]bar</paragraph>
303
- // </blockBlock> -> </blockBlock>
304
- //
304
+ /**
305
+ * Merging blocks to the right (properties of the right block are preserved).
306
+ * Simple example:
307
+ *
308
+ * ```
309
+ * <heading1>foo[</heading1> -> --v
310
+ * <paragraph>]bar</paragraph> -> [<paragraph>foo]bar</paragraph>
311
+ * ```
312
+ *
313
+ * Nested example:
314
+ *
315
+ * ```
316
+ * <blockQuote> ->
317
+ * <heading1>foo[</heading1> -> ---
318
+ * </blockQuote> -> |
319
+ * <blockBlock> -> [<blockBlock> v
320
+ * <paragraph>]bar</paragraph> -> <paragraph>foo]bar</paragraph>
321
+ * </blockBlock> -> </blockBlock>
322
+ * ```
323
+ */
305
324
  function mergeBranchesRight(writer, startPosition, endPosition, commonAncestor) {
306
325
  const startElement = startPosition.parent;
307
326
  const endElement = endPosition.parent;
@@ -359,7 +378,9 @@ function mergeBranchesRight(writer, startPosition, endPosition, commonAncestor)
359
378
  // Continue merging next level (blockQuote with blockBlock in the examples above if it would not be empty and got removed).
360
379
  mergeBranchesRight(writer, startPosition, endPosition, commonAncestor);
361
380
  }
362
- // There is no right merge operation so we need to simulate it.
381
+ /**
382
+ * There is no right merge operation so we need to simulate it.
383
+ */
363
384
  function mergeRight(writer, position) {
364
385
  const startElement = position.nodeBefore;
365
386
  const endElement = position.nodeAfter;
@@ -370,8 +391,10 @@ function mergeRight(writer, position) {
370
391
  writer.setAttributes(Object.fromEntries(endElement.getAttributes()), startElement);
371
392
  writer.merge(position);
372
393
  }
373
- // Verifies if merging is needed and possible. It's not needed if both positions are in the same element
374
- // and it's not possible if some element is a limit or the range crosses a limit element.
394
+ /**
395
+ * Verifies if merging is needed and possible. It's not needed if both positions are in the same element
396
+ * and it's not possible if some element is a limit or the range crosses a limit element.
397
+ */
375
398
  function checkShouldMerge(schema, startPosition, endPosition) {
376
399
  const startElement = startPosition.parent;
377
400
  const endElement = endPosition.parent;
@@ -389,7 +412,9 @@ function checkShouldMerge(schema, startPosition, endPosition) {
389
412
  // <limit><startElement>x[</startElement></limit><endElement>]</endElement>
390
413
  return isCrossingLimitElement(startPosition, endPosition, schema);
391
414
  }
392
- // Returns the elements that are the ancestors of the provided positions that are direct children of the common ancestor.
415
+ /**
416
+ * Returns the elements that are the ancestors of the provided positions that are direct children of the common ancestor.
417
+ */
393
418
  function getAncestorsJustBelowCommonAncestor(positionA, positionB) {
394
419
  const ancestorsA = positionA.getAncestors();
395
420
  const ancestorsB = positionB.getAncestors();
@@ -404,12 +429,14 @@ function shouldAutoparagraph(schema, position) {
404
429
  const isParagraphAllowed = schema.checkChild(position, 'paragraph');
405
430
  return !isTextAllowed && isParagraphAllowed;
406
431
  }
407
- // Check if parents of two positions can be merged by checking if there are no limit/object
408
- // boundaries between those two positions.
409
- //
410
- // E.g. in <bQ><p>x[]</p></bQ><widget><caption>{}</caption></widget>
411
- // we'll check <p>, <bQ>, <widget> and <caption>.
412
- // Usually, widget and caption are marked as objects/limits in the schema, so in this case merging will be blocked.
432
+ /**
433
+ * Check if parents of two positions can be merged by checking if there are no limit/object
434
+ * boundaries between those two positions.
435
+ *
436
+ * E.g. in <bQ><p>x[]</p></bQ><widget><caption>{}</caption></widget>
437
+ * we'll check <p>, <bQ>, <widget> and <caption>.
438
+ * Usually, widget and caption are marked as objects/limits in the schema, so in this case merging will be blocked.
439
+ */
413
440
  function isCrossingLimitElement(leftPos, rightPos, schema) {
414
441
  const rangeToCheck = new Range(leftPos, rightPos);
415
442
  for (const value of rangeToCheck.getWalker()) {
@@ -430,10 +457,12 @@ function replaceEntireContentWithParagraph(writer, selection) {
430
457
  writer.remove(writer.createRangeIn(limitElement));
431
458
  insertParagraph(writer, writer.createPositionAt(limitElement, 0), selection);
432
459
  }
433
- // We want to replace the entire content with a paragraph when:
434
- // * the entire content is selected,
435
- // * selection contains at least two elements,
436
- // * whether the paragraph is allowed in schema in the common ancestor.
460
+ /**
461
+ * We want to replace the entire content with a paragraph when:
462
+ * * the entire content is selected,
463
+ * * selection contains at least two elements,
464
+ * * whether the paragraph is allowed in schema in the common ancestor.
465
+ */
437
466
  function shouldEntireContentBeReplacedWithParagraph(schema, selection) {
438
467
  const limitElement = schema.getLimitElement(selection);
439
468
  if (!selection.containsEntireContent(limitElement)) {
@@ -445,8 +474,10 @@ function shouldEntireContentBeReplacedWithParagraph(schema, selection) {
445
474
  }
446
475
  return schema.checkChild(limitElement, 'paragraph');
447
476
  }
448
- // Helper function that sets the selection. Depending whether given `selection` is a document selection or not,
449
- // uses a different method to set it.
477
+ /**
478
+ * Helper function that sets the selection. Depending whether given `selection` is a document selection or not,
479
+ * uses a different method to set it.
480
+ */
450
481
  function collapseSelectionAt(writer, selection, positionOrRange) {
451
482
  if (selection instanceof DocumentSelection) {
452
483
  writer.setSelection(positionOrRange);
@@ -1,34 +1,34 @@
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
  /**
6
6
  * @module engine/model/utils/findoptimalinsertionrange
7
7
  */
8
8
  import { first } from '@ckeditor/ckeditor5-utils';
9
- // Returns a model range which is optimal (in terms of UX) for inserting a widget block.
10
- //
11
- // For instance, if a selection is in the middle of a paragraph, the collapsed range before this paragraph
12
- // will be returned so that it is not split. If the selection is at the end of a paragraph,
13
- // the collapsed range after this paragraph will be returned.
14
- //
15
- // Note: If the selection is placed in an empty block, the range in that block will be returned. If that range
16
- // is then passed to {@link module:engine/model/model~Model#insertContent}, the block will be fully replaced
17
- // by the inserted widget block.
18
- //
19
- // **Note:** Use {@link module:widget/utils#findOptimalInsertionRange} instead of this function outside engine.
20
- // This function is only exposed to be used by {@link module:widget/utils#findOptimalInsertionRange findOptimalInsertionRange()}
21
- // in the `widget` package and inside the `engine` package.
22
- //
23
- // @private
24
- // @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
25
- // The selection based on which the insertion position should be calculated.
26
- // @param {module:engine/model/model~Model} model Model instance.
27
- // @param {'auto'|'before'|'after'} [place='auto'] The place where to look for optimal insertion range.
28
- // The default `auto` value will determine itself the best position for insertion.
29
- // The `before` value will try to find a position before selection.
30
- // The `after` value will try to find a position after selection.
31
- // @returns {module:engine/model/range~Range} The optimal range.
9
+ /**
10
+ * Returns a model range which is optimal (in terms of UX) for inserting a widget block.
11
+ *
12
+ * For instance, if a selection is in the middle of a paragraph, the collapsed range before this paragraph
13
+ * will be returned so that it is not split. If the selection is at the end of a paragraph,
14
+ * the collapsed range after this paragraph will be returned.
15
+ *
16
+ * Note: If the selection is placed in an empty block, the range in that block will be returned. If that range
17
+ * is then passed to {@link module:engine/model/model~Model#insertContent}, the block will be fully replaced
18
+ * by the inserted widget block.
19
+ *
20
+ * **Note:** Use {@link module:widget/utils#findOptimalInsertionRange} instead of this function outside engine.
21
+ * This function is only exposed to be used by {@link module:widget/utils#findOptimalInsertionRange findOptimalInsertionRange()}
22
+ * in the `widget` package and inside the `engine` package.
23
+ *
24
+ * @param selection The selection based on which the insertion position should be calculated.
25
+ * @param model Model instance.
26
+ * @param place The place where to look for optimal insertion range.
27
+ * The default `auto` value will determine itself the best position for insertion.
28
+ * The `before` value will try to find a position before selection.
29
+ * The `after` value will try to find a position after selection.
30
+ * @returns The optimal range.
31
+ */
32
32
  export function findOptimalInsertionRange(selection, model, place = 'auto') {
33
33
  const selectedElement = selection.getSelectedElement();
34
34
  if (selectedElement && model.schema.isObject(selectedElement) && !model.schema.isInline(selectedElement)) {
@@ -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
  /**
@@ -20,11 +20,8 @@
20
20
  * <quote><h>st</h></quote><p>se</p>
21
21
  * ```
22
22
  *
23
- * @param {module:engine/model/model~Model} model The model in context of which
24
- * the selection modification should be performed.
25
- * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection
26
- * The selection of which content will be returned.
27
- * @returns {module:engine/model/documentfragment~DocumentFragment}
23
+ * @param model The model in context of which the selection modification should be performed.
24
+ * @param selection The selection of which content will be returned.
28
25
  */
29
26
  export default function getSelectedContent(model, selection) {
30
27
  return model.change(writer => {