@ckeditor/ckeditor5-engine 34.2.0 → 35.1.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 (125) hide show
  1. package/CHANGELOG.md +823 -0
  2. package/LICENSE.md +4 -0
  3. package/package.json +32 -25
  4. package/src/controller/datacontroller.js +467 -561
  5. package/src/controller/editingcontroller.js +168 -204
  6. package/src/conversion/conversion.js +541 -565
  7. package/src/conversion/conversionhelpers.js +24 -28
  8. package/src/conversion/downcastdispatcher.js +457 -686
  9. package/src/conversion/downcasthelpers.js +1583 -1965
  10. package/src/conversion/mapper.js +518 -707
  11. package/src/conversion/modelconsumable.js +240 -283
  12. package/src/conversion/upcastdispatcher.js +372 -718
  13. package/src/conversion/upcasthelpers.js +707 -818
  14. package/src/conversion/viewconsumable.js +524 -581
  15. package/src/dataprocessor/basichtmlwriter.js +12 -16
  16. package/src/dataprocessor/dataprocessor.js +5 -0
  17. package/src/dataprocessor/htmldataprocessor.js +101 -117
  18. package/src/dataprocessor/htmlwriter.js +1 -18
  19. package/src/dataprocessor/xmldataprocessor.js +117 -138
  20. package/src/dev-utils/model.js +260 -352
  21. package/src/dev-utils/operationreplayer.js +106 -126
  22. package/src/dev-utils/utils.js +34 -51
  23. package/src/dev-utils/view.js +632 -753
  24. package/src/index.js +0 -11
  25. package/src/model/batch.js +111 -127
  26. package/src/model/differ.js +988 -1233
  27. package/src/model/document.js +340 -449
  28. package/src/model/documentfragment.js +327 -364
  29. package/src/model/documentselection.js +996 -1189
  30. package/src/model/element.js +306 -410
  31. package/src/model/history.js +224 -262
  32. package/src/model/item.js +5 -0
  33. package/src/model/liveposition.js +84 -145
  34. package/src/model/liverange.js +108 -185
  35. package/src/model/markercollection.js +379 -480
  36. package/src/model/model.js +883 -1034
  37. package/src/model/node.js +419 -463
  38. package/src/model/nodelist.js +175 -201
  39. package/src/model/operation/attributeoperation.js +153 -182
  40. package/src/model/operation/detachoperation.js +64 -83
  41. package/src/model/operation/insertoperation.js +135 -166
  42. package/src/model/operation/markeroperation.js +114 -140
  43. package/src/model/operation/mergeoperation.js +163 -191
  44. package/src/model/operation/moveoperation.js +157 -187
  45. package/src/model/operation/nooperation.js +28 -38
  46. package/src/model/operation/operation.js +106 -125
  47. package/src/model/operation/operationfactory.js +30 -34
  48. package/src/model/operation/renameoperation.js +109 -135
  49. package/src/model/operation/rootattributeoperation.js +155 -188
  50. package/src/model/operation/splitoperation.js +196 -232
  51. package/src/model/operation/transform.js +1833 -2204
  52. package/src/model/operation/utils.js +140 -204
  53. package/src/model/position.js +899 -1053
  54. package/src/model/range.js +910 -1028
  55. package/src/model/rootelement.js +77 -97
  56. package/src/model/schema.js +1189 -1835
  57. package/src/model/selection.js +745 -862
  58. package/src/model/text.js +90 -114
  59. package/src/model/textproxy.js +204 -240
  60. package/src/model/treewalker.js +316 -397
  61. package/src/model/typecheckable.js +16 -0
  62. package/src/model/utils/autoparagraphing.js +32 -44
  63. package/src/model/utils/deletecontent.js +334 -418
  64. package/src/model/utils/findoptimalinsertionrange.js +25 -36
  65. package/src/model/utils/getselectedcontent.js +96 -118
  66. package/src/model/utils/insertcontent.js +654 -773
  67. package/src/model/utils/insertobject.js +96 -119
  68. package/src/model/utils/modifyselection.js +120 -158
  69. package/src/model/utils/selection-post-fixer.js +153 -201
  70. package/src/model/writer.js +1305 -1474
  71. package/src/view/attributeelement.js +189 -225
  72. package/src/view/containerelement.js +75 -85
  73. package/src/view/document.js +172 -215
  74. package/src/view/documentfragment.js +200 -249
  75. package/src/view/documentselection.js +338 -367
  76. package/src/view/domconverter.js +1371 -1613
  77. package/src/view/downcastwriter.js +1747 -2076
  78. package/src/view/editableelement.js +81 -97
  79. package/src/view/element.js +739 -890
  80. package/src/view/elementdefinition.js +5 -0
  81. package/src/view/emptyelement.js +82 -92
  82. package/src/view/filler.js +35 -50
  83. package/src/view/item.js +5 -0
  84. package/src/view/matcher.js +260 -559
  85. package/src/view/node.js +274 -360
  86. package/src/view/observer/arrowkeysobserver.js +19 -28
  87. package/src/view/observer/bubblingemittermixin.js +120 -263
  88. package/src/view/observer/bubblingeventinfo.js +47 -55
  89. package/src/view/observer/clickobserver.js +7 -13
  90. package/src/view/observer/compositionobserver.js +14 -24
  91. package/src/view/observer/domeventdata.js +57 -67
  92. package/src/view/observer/domeventobserver.js +40 -64
  93. package/src/view/observer/fakeselectionobserver.js +81 -96
  94. package/src/view/observer/focusobserver.js +45 -61
  95. package/src/view/observer/inputobserver.js +7 -13
  96. package/src/view/observer/keyobserver.js +17 -27
  97. package/src/view/observer/mouseobserver.js +7 -14
  98. package/src/view/observer/mutationobserver.js +220 -315
  99. package/src/view/observer/observer.js +81 -102
  100. package/src/view/observer/selectionobserver.js +191 -246
  101. package/src/view/observer/tabobserver.js +23 -36
  102. package/src/view/placeholder.js +128 -173
  103. package/src/view/position.js +350 -401
  104. package/src/view/range.js +453 -513
  105. package/src/view/rawelement.js +85 -112
  106. package/src/view/renderer.js +874 -1014
  107. package/src/view/rooteditableelement.js +80 -90
  108. package/src/view/selection.js +608 -689
  109. package/src/view/styles/background.js +43 -44
  110. package/src/view/styles/border.js +220 -276
  111. package/src/view/styles/margin.js +8 -17
  112. package/src/view/styles/padding.js +8 -16
  113. package/src/view/styles/utils.js +127 -160
  114. package/src/view/stylesmap.js +728 -905
  115. package/src/view/text.js +102 -126
  116. package/src/view/textproxy.js +144 -170
  117. package/src/view/treewalker.js +383 -479
  118. package/src/view/typecheckable.js +19 -0
  119. package/src/view/uielement.js +166 -187
  120. package/src/view/upcastwriter.js +395 -449
  121. package/src/view/view.js +569 -664
  122. package/src/dataprocessor/dataprocessor.jsdoc +0 -64
  123. package/src/model/item.jsdoc +0 -14
  124. package/src/view/elementdefinition.jsdoc +0 -59
  125. package/src/view/item.jsdoc +0 -14
@@ -2,15 +2,13 @@
2
2
  * @license Copyright (c) 2003-2022, 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
+ /* eslint-disable new-cap */
6
6
  /**
7
7
  * @module engine/view/documentselection
8
8
  */
9
-
9
+ import TypeCheckable from './typecheckable';
10
10
  import Selection from './selection';
11
- import mix from '@ckeditor/ckeditor5-utils/src/mix';
12
11
  import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
13
-
14
12
  /**
15
13
  * Class representing the document selection in the view.
16
14
  *
@@ -21,367 +19,340 @@ import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
21
19
  * the {@link module:engine/view/view~View#change `View#change()`} block
22
20
  * (so via {@link module:engine/view/downcastwriter~DowncastWriter#setSelection `DowncastWriter#setSelection()`}).
23
21
  */
24
- export default class DocumentSelection {
25
- /**
26
- * Creates new DocumentSelection instance.
27
- *
28
- * // Creates empty selection without ranges.
29
- * const selection = new DocumentSelection();
30
- *
31
- * // Creates selection at the given range.
32
- * const range = writer.createRange( start, end );
33
- * const selection = new DocumentSelection( range );
34
- *
35
- * // Creates selection at the given ranges
36
- * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( start2, end2 ) ];
37
- * const selection = new DocumentSelection( ranges );
38
- *
39
- * // Creates selection from the other selection.
40
- * const otherSelection = writer.createSelection();
41
- * const selection = new DocumentSelection( otherSelection );
42
- *
43
- * // Creates selection at the given position.
44
- * const position = writer.createPositionAt( root, offset );
45
- * const selection = new DocumentSelection( position );
46
- *
47
- * // Creates collapsed selection at the position of given item and offset.
48
- * const paragraph = writer.createContainerElement( 'paragraph' );
49
- * const selection = new DocumentSelection( paragraph, offset );
50
- *
51
- * // Creates a range inside an {@link module:engine/view/element~Element element} which starts before the
52
- * // first child of that element and ends after the last child of that element.
53
- * const selection = new DocumentSelection( paragraph, 'in' );
54
- *
55
- * // Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends
56
- * // just after the item.
57
- * const selection = new DocumentSelection( paragraph, 'on' );
58
- *
59
- * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.
60
- *
61
- * // Creates backward selection.
62
- * const selection = new DocumentSelection( range, { backward: true } );
63
- *
64
- * Fake selection does not render as browser native selection over selected elements and is hidden to the user.
65
- * This way, no native selection UI artifacts are displayed to the user and selection over elements can be
66
- * represented in other way, for example by applying proper CSS class.
67
- *
68
- * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM
69
- * (and be properly handled by screen readers).
70
- *
71
- * // Creates fake selection with label.
72
- * const selection = new DocumentSelection( range, { fake: true, label: 'foo' } );
73
- *
74
- * @param {module:engine/view/selection~Selectable} [selectable=null]
75
- * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Offset or place when selectable is an `Item`.
76
- * @param {Object} [options]
77
- * @param {Boolean} [options.backward] Sets this selection instance to be backward.
78
- * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.
79
- * @param {String} [options.label] Label for the fake selection.
80
- */
81
- constructor( selectable = null, placeOrOffset, options ) {
82
- /**
83
- * Selection is used internally (`DocumentSelection` is a proxy to that selection).
84
- *
85
- * @private
86
- * @member {module:engine/view/selection~Selection}
87
- */
88
- this._selection = new Selection();
89
-
90
- // Delegate change event to be fired on DocumentSelection instance.
91
- this._selection.delegate( 'change' ).to( this );
92
-
93
- // Set selection data.
94
- this._selection.setTo( selectable, placeOrOffset, options );
95
- }
96
-
97
- /**
98
- * Returns true if selection instance is marked as `fake`.
99
- *
100
- * @see #_setTo
101
- * @type {Boolean}
102
- */
103
- get isFake() {
104
- return this._selection.isFake;
105
- }
106
-
107
- /**
108
- * Returns fake selection label.
109
- *
110
- * @see #_setTo
111
- * @type {String}
112
- */
113
- get fakeSelectionLabel() {
114
- return this._selection.fakeSelectionLabel;
115
- }
116
-
117
- /**
118
- * Selection anchor. Anchor may be described as a position where the selection starts. Together with
119
- * {@link #focus focus} they define the direction of selection, which is important
120
- * when expanding/shrinking selection. Anchor is always the start or end of the most recent added range.
121
- * It may be a bit unintuitive when there are multiple ranges in selection.
122
- *
123
- * @see #focus
124
- * @type {module:engine/view/position~Position}
125
- */
126
- get anchor() {
127
- return this._selection.anchor;
128
- }
129
-
130
- /**
131
- * Selection focus. Focus is a position where the selection ends.
132
- *
133
- * @see #anchor
134
- * @type {module:engine/view/position~Position}
135
- */
136
- get focus() {
137
- return this._selection.focus;
138
- }
139
-
140
- /**
141
- * Returns whether the selection is collapsed. Selection is collapsed when there is exactly one range which is
142
- * collapsed.
143
- *
144
- * @type {Boolean}
145
- */
146
- get isCollapsed() {
147
- return this._selection.isCollapsed;
148
- }
149
-
150
- /**
151
- * Returns number of ranges in selection.
152
- *
153
- * @type {Number}
154
- */
155
- get rangeCount() {
156
- return this._selection.rangeCount;
157
- }
158
-
159
- /**
160
- * Specifies whether the {@link #focus} precedes {@link #anchor}.
161
- *
162
- * @type {Boolean}
163
- */
164
- get isBackward() {
165
- return this._selection.isBackward;
166
- }
167
-
168
- /**
169
- * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this selection, or `null`
170
- * if the selection is not inside an editable element.
171
- *
172
- * @type {module:engine/view/editableelement~EditableElement|null}
173
- */
174
- get editableElement() {
175
- return this._selection.editableElement;
176
- }
177
-
178
- /**
179
- * Used for the compatibility with the {@link module:engine/view/selection~Selection#isEqual} method.
180
- *
181
- * @protected
182
- */
183
- get _ranges() {
184
- return this._selection._ranges;
185
- }
186
-
187
- /**
188
- * Returns an iterable that contains copies of all ranges added to the selection.
189
- *
190
- * @returns {Iterable.<module:engine/view/range~Range>}
191
- */
192
- * getRanges() {
193
- yield* this._selection.getRanges();
194
- }
195
-
196
- /**
197
- * Returns copy of the first range in the selection. First range is the one which
198
- * {@link module:engine/view/range~Range#start start} position {@link module:engine/view/position~Position#isBefore is before} start
199
- * position of all other ranges (not to confuse with the first range added to the selection).
200
- * Returns `null` if no ranges are added to selection.
201
- *
202
- * @returns {module:engine/view/range~Range|null}
203
- */
204
- getFirstRange() {
205
- return this._selection.getFirstRange();
206
- }
207
-
208
- /**
209
- * Returns copy of the last range in the selection. Last range is the one which {@link module:engine/view/range~Range#end end}
210
- * position {@link module:engine/view/position~Position#isAfter is after} end position of all other ranges (not to confuse
211
- * with the last range added to the selection). Returns `null` if no ranges are added to selection.
212
- *
213
- * @returns {module:engine/view/range~Range|null}
214
- */
215
- getLastRange() {
216
- return this._selection.getLastRange();
217
- }
218
-
219
- /**
220
- * Returns copy of the first position in the selection. First position is the position that
221
- * {@link module:engine/view/position~Position#isBefore is before} any other position in the selection ranges.
222
- * Returns `null` if no ranges are added to selection.
223
- *
224
- * @returns {module:engine/view/position~Position|null}
225
- */
226
- getFirstPosition() {
227
- return this._selection.getFirstPosition();
228
- }
229
-
230
- /**
231
- * Returns copy of the last position in the selection. Last position is the position that
232
- * {@link module:engine/view/position~Position#isAfter is after} any other position in the selection ranges.
233
- * Returns `null` if no ranges are added to selection.
234
- *
235
- * @returns {module:engine/view/position~Position|null}
236
- */
237
- getLastPosition() {
238
- return this._selection.getLastPosition();
239
- }
240
-
241
- /**
242
- * Returns the selected element. {@link module:engine/view/element~Element Element} is considered as selected if there is only
243
- * one range in the selection, and that range contains exactly one element.
244
- * Returns `null` if there is no selected element.
245
- *
246
- * @returns {module:engine/view/element~Element|null}
247
- */
248
- getSelectedElement() {
249
- return this._selection.getSelectedElement();
250
- }
251
-
252
- /**
253
- * Checks whether, this selection is equal to given selection. Selections are equal if they have same directions,
254
- * same number of ranges and all ranges from one selection equal to a range from other selection.
255
- *
256
- * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} otherSelection
257
- * Selection to compare with.
258
- * @returns {Boolean} `true` if selections are equal, `false` otherwise.
259
- */
260
- isEqual( otherSelection ) {
261
- return this._selection.isEqual( otherSelection );
262
- }
263
-
264
- /**
265
- * Checks whether this selection is similar to given selection. Selections are similar if they have same directions, same
266
- * number of ranges, and all {@link module:engine/view/range~Range#getTrimmed trimmed} ranges from one selection are
267
- * equal to any trimmed range from other selection.
268
- *
269
- * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} otherSelection
270
- * Selection to compare with.
271
- * @returns {Boolean} `true` if selections are similar, `false` otherwise.
272
- */
273
- isSimilar( otherSelection ) {
274
- return this._selection.isSimilar( otherSelection );
275
- }
276
-
277
- /**
278
- * Checks whether this object is of the given type.
279
- *
280
- * docSelection.is( 'selection' ); // -> true
281
- * docSelection.is( 'documentSelection' ); // -> true
282
- * docSelection.is( 'view:selection' ); // -> true
283
- * docSelection.is( 'view:documentSelection' ); // -> true
284
- *
285
- * docSelection.is( 'model:documentSelection' ); // -> false
286
- * docSelection.is( 'element' ); // -> false
287
- * docSelection.is( 'node' ); // -> false
288
- *
289
- * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.
290
- *
291
- * @param {String} type
292
- * @returns {Boolean}
293
- */
294
- is( type ) {
295
- return type === 'selection' ||
296
- type == 'documentSelection' ||
297
- type == 'view:selection' ||
298
- type == 'view:documentSelection';
299
- }
300
-
301
- /**
302
- * Sets this selection's ranges and direction to the specified location based on the given
303
- * {@link module:engine/view/selection~Selectable selectable}.
304
- *
305
- * // Sets selection to the given range.
306
- * const range = writer.createRange( start, end );
307
- * documentSelection._setTo( range );
308
- *
309
- * // Sets selection to given ranges.
310
- * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( start2, end2 ) ];
311
- * documentSelection._setTo( range );
312
- *
313
- * // Sets selection to the other selection.
314
- * const otherSelection = writer.createSelection();
315
- * documentSelection._setTo( otherSelection );
316
- *
317
- * // Sets collapsed selection at the given position.
318
- * const position = writer.createPositionAt( root, offset );
319
- * documentSelection._setTo( position );
320
- *
321
- * // Sets collapsed selection at the position of given item and offset.
322
- * documentSelection._setTo( paragraph, offset );
323
- *
324
- * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of
325
- * that element and ends after the last child of that element.
326
- *
327
- * documentSelection._setTo( paragraph, 'in' );
328
- *
329
- * Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends just after the item.
330
- *
331
- * documentSelection._setTo( paragraph, 'on' );
332
- *
333
- * // Clears selection. Removes all ranges.
334
- * documentSelection._setTo( null );
335
- *
336
- * `Selection#_setTo()` method allow passing additional options (`backward`, `fake` and `label`) as the last argument.
337
- *
338
- * // Sets selection as backward.
339
- * documentSelection._setTo( range, { backward: true } );
340
- *
341
- * Fake selection does not render as browser native selection over selected elements and is hidden to the user.
342
- * This way, no native selection UI artifacts are displayed to the user and selection over elements can be
343
- * represented in other way, for example by applying proper CSS class.
344
- *
345
- * Additionally fake's selection label can be provided. It will be used to des cribe fake selection in DOM
346
- * (and be properly handled by screen readers).
347
- *
348
- * // Creates fake selection with label.
349
- * documentSelection._setTo( range, { fake: true, label: 'foo' } );
350
- *
351
- * @protected
352
- * @fires change
353
- * @param {module:engine/view/selection~Selectable} selectable
354
- * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.
355
- * @param {Object} [options]
356
- * @param {Boolean} [options.backward] Sets this selection instance to be backward.
357
- * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.
358
- * @param {String} [options.label] Label for the fake selection.
359
- */
360
- _setTo( selectable, placeOrOffset, options ) {
361
- this._selection.setTo( selectable, placeOrOffset, options );
362
- }
363
-
364
- /**
365
- * Moves {@link #focus} to the specified location.
366
- *
367
- * The location can be specified in the same form as {@link module:engine/view/view~View#createPositionAt view.createPositionAt()}
368
- * parameters.
369
- *
370
- * @protected
371
- * @fires change
372
- * @param {module:engine/view/item~Item|module:engine/view/position~Position} itemOrPosition
373
- * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when
374
- * first parameter is a {@link module:engine/view/item~Item view item}.
375
- */
376
- _setFocus( itemOrPosition, offset ) {
377
- this._selection.setFocus( itemOrPosition, offset );
378
- }
379
-
380
- /**
381
- * Fired whenever selection ranges are changed through {@link ~DocumentSelection Selection API}.
382
- *
383
- * @event change
384
- */
22
+ export default class DocumentSelection extends EmitterMixin(TypeCheckable) {
23
+ /**
24
+ * Creates new DocumentSelection instance.
25
+ *
26
+ * // Creates empty selection without ranges.
27
+ * const selection = new DocumentSelection();
28
+ *
29
+ * // Creates selection at the given range.
30
+ * const range = writer.createRange( start, end );
31
+ * const selection = new DocumentSelection( range );
32
+ *
33
+ * // Creates selection at the given ranges
34
+ * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( start2, end2 ) ];
35
+ * const selection = new DocumentSelection( ranges );
36
+ *
37
+ * // Creates selection from the other selection.
38
+ * const otherSelection = writer.createSelection();
39
+ * const selection = new DocumentSelection( otherSelection );
40
+ *
41
+ * // Creates selection at the given position.
42
+ * const position = writer.createPositionAt( root, offset );
43
+ * const selection = new DocumentSelection( position );
44
+ *
45
+ * // Creates collapsed selection at the position of given item and offset.
46
+ * const paragraph = writer.createContainerElement( 'paragraph' );
47
+ * const selection = new DocumentSelection( paragraph, offset );
48
+ *
49
+ * // Creates a range inside an {@link module:engine/view/element~Element element} which starts before the
50
+ * // first child of that element and ends after the last child of that element.
51
+ * const selection = new DocumentSelection( paragraph, 'in' );
52
+ *
53
+ * // Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends
54
+ * // just after the item.
55
+ * const selection = new DocumentSelection( paragraph, 'on' );
56
+ *
57
+ * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.
58
+ *
59
+ * // Creates backward selection.
60
+ * const selection = new DocumentSelection( range, { backward: true } );
61
+ *
62
+ * Fake selection does not render as browser native selection over selected elements and is hidden to the user.
63
+ * This way, no native selection UI artifacts are displayed to the user and selection over elements can be
64
+ * represented in other way, for example by applying proper CSS class.
65
+ *
66
+ * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM
67
+ * (and be properly handled by screen readers).
68
+ *
69
+ * // Creates fake selection with label.
70
+ * const selection = new DocumentSelection( range, { fake: true, label: 'foo' } );
71
+ *
72
+ * @param {module:engine/view/selection~Selectable} [selectable=null]
73
+ * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Offset or place when selectable is an `Item`.
74
+ * @param {Object} [options]
75
+ * @param {Boolean} [options.backward] Sets this selection instance to be backward.
76
+ * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.
77
+ * @param {String} [options.label] Label for the fake selection.
78
+ */
79
+ constructor(...args) {
80
+ super();
81
+ /**
82
+ * Selection is used internally (`DocumentSelection` is a proxy to that selection).
83
+ *
84
+ * @private
85
+ * @member {module:engine/view/selection~Selection}
86
+ */
87
+ this._selection = new Selection();
88
+ // Delegate change event to be fired on DocumentSelection instance.
89
+ this._selection.delegate('change').to(this);
90
+ // Set selection data.
91
+ if (args.length) {
92
+ this._selection.setTo(...args);
93
+ }
94
+ }
95
+ /**
96
+ * Returns true if selection instance is marked as `fake`.
97
+ *
98
+ * @see #_setTo
99
+ * @type {Boolean}
100
+ */
101
+ get isFake() {
102
+ return this._selection.isFake;
103
+ }
104
+ /**
105
+ * Returns fake selection label.
106
+ *
107
+ * @see #_setTo
108
+ * @type {String}
109
+ */
110
+ get fakeSelectionLabel() {
111
+ return this._selection.fakeSelectionLabel;
112
+ }
113
+ /**
114
+ * Selection anchor. Anchor may be described as a position where the selection starts. Together with
115
+ * {@link #focus focus} they define the direction of selection, which is important
116
+ * when expanding/shrinking selection. Anchor is always the start or end of the most recent added range.
117
+ * It may be a bit unintuitive when there are multiple ranges in selection.
118
+ *
119
+ * @see #focus
120
+ * @type {module:engine/view/position~Position}
121
+ */
122
+ get anchor() {
123
+ return this._selection.anchor;
124
+ }
125
+ /**
126
+ * Selection focus. Focus is a position where the selection ends.
127
+ *
128
+ * @see #anchor
129
+ * @type {module:engine/view/position~Position}
130
+ */
131
+ get focus() {
132
+ return this._selection.focus;
133
+ }
134
+ /**
135
+ * Returns whether the selection is collapsed. Selection is collapsed when there is exactly one range which is
136
+ * collapsed.
137
+ *
138
+ * @type {Boolean}
139
+ */
140
+ get isCollapsed() {
141
+ return this._selection.isCollapsed;
142
+ }
143
+ /**
144
+ * Returns number of ranges in selection.
145
+ *
146
+ * @type {Number}
147
+ */
148
+ get rangeCount() {
149
+ return this._selection.rangeCount;
150
+ }
151
+ /**
152
+ * Specifies whether the {@link #focus} precedes {@link #anchor}.
153
+ *
154
+ * @type {Boolean}
155
+ */
156
+ get isBackward() {
157
+ return this._selection.isBackward;
158
+ }
159
+ /**
160
+ * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this selection, or `null`
161
+ * if the selection is not inside an editable element.
162
+ *
163
+ * @type {module:engine/view/editableelement~EditableElement|null}
164
+ */
165
+ get editableElement() {
166
+ return this._selection.editableElement;
167
+ }
168
+ /**
169
+ * Used for the compatibility with the {@link module:engine/view/selection~Selection#isEqual} method.
170
+ *
171
+ * @protected
172
+ */
173
+ get _ranges() {
174
+ return this._selection._ranges;
175
+ }
176
+ /**
177
+ * Returns an iterable that contains copies of all ranges added to the selection.
178
+ *
179
+ * @returns {Iterable.<module:engine/view/range~Range>}
180
+ */
181
+ *getRanges() {
182
+ yield* this._selection.getRanges();
183
+ }
184
+ /**
185
+ * Returns copy of the first range in the selection. First range is the one which
186
+ * {@link module:engine/view/range~Range#start start} position {@link module:engine/view/position~Position#isBefore is before} start
187
+ * position of all other ranges (not to confuse with the first range added to the selection).
188
+ * Returns `null` if no ranges are added to selection.
189
+ *
190
+ * @returns {module:engine/view/range~Range|null}
191
+ */
192
+ getFirstRange() {
193
+ return this._selection.getFirstRange();
194
+ }
195
+ /**
196
+ * Returns copy of the last range in the selection. Last range is the one which {@link module:engine/view/range~Range#end end}
197
+ * position {@link module:engine/view/position~Position#isAfter is after} end position of all other ranges (not to confuse
198
+ * with the last range added to the selection). Returns `null` if no ranges are added to selection.
199
+ *
200
+ * @returns {module:engine/view/range~Range|null}
201
+ */
202
+ getLastRange() {
203
+ return this._selection.getLastRange();
204
+ }
205
+ /**
206
+ * Returns copy of the first position in the selection. First position is the position that
207
+ * {@link module:engine/view/position~Position#isBefore is before} any other position in the selection ranges.
208
+ * Returns `null` if no ranges are added to selection.
209
+ *
210
+ * @returns {module:engine/view/position~Position|null}
211
+ */
212
+ getFirstPosition() {
213
+ return this._selection.getFirstPosition();
214
+ }
215
+ /**
216
+ * Returns copy of the last position in the selection. Last position is the position that
217
+ * {@link module:engine/view/position~Position#isAfter is after} any other position in the selection ranges.
218
+ * Returns `null` if no ranges are added to selection.
219
+ *
220
+ * @returns {module:engine/view/position~Position|null}
221
+ */
222
+ getLastPosition() {
223
+ return this._selection.getLastPosition();
224
+ }
225
+ /**
226
+ * Returns the selected element. {@link module:engine/view/element~Element Element} is considered as selected if there is only
227
+ * one range in the selection, and that range contains exactly one element.
228
+ * Returns `null` if there is no selected element.
229
+ *
230
+ * @returns {module:engine/view/element~Element|null}
231
+ */
232
+ getSelectedElement() {
233
+ return this._selection.getSelectedElement();
234
+ }
235
+ /**
236
+ * Checks whether, this selection is equal to given selection. Selections are equal if they have same directions,
237
+ * same number of ranges and all ranges from one selection equal to a range from other selection.
238
+ *
239
+ * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} otherSelection
240
+ * Selection to compare with.
241
+ * @returns {Boolean} `true` if selections are equal, `false` otherwise.
242
+ */
243
+ isEqual(otherSelection) {
244
+ return this._selection.isEqual(otherSelection);
245
+ }
246
+ /**
247
+ * Checks whether this selection is similar to given selection. Selections are similar if they have same directions, same
248
+ * number of ranges, and all {@link module:engine/view/range~Range#getTrimmed trimmed} ranges from one selection are
249
+ * equal to any trimmed range from other selection.
250
+ *
251
+ * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} otherSelection
252
+ * Selection to compare with.
253
+ * @returns {Boolean} `true` if selections are similar, `false` otherwise.
254
+ */
255
+ isSimilar(otherSelection) {
256
+ return this._selection.isSimilar(otherSelection);
257
+ }
258
+ /**
259
+ * Sets this selection's ranges and direction to the specified location based on the given
260
+ * {@link module:engine/view/selection~Selectable selectable}.
261
+ *
262
+ * // Sets selection to the given range.
263
+ * const range = writer.createRange( start, end );
264
+ * documentSelection._setTo( range );
265
+ *
266
+ * // Sets selection to given ranges.
267
+ * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( start2, end2 ) ];
268
+ * documentSelection._setTo( range );
269
+ *
270
+ * // Sets selection to the other selection.
271
+ * const otherSelection = writer.createSelection();
272
+ * documentSelection._setTo( otherSelection );
273
+ *
274
+ * // Sets collapsed selection at the given position.
275
+ * const position = writer.createPositionAt( root, offset );
276
+ * documentSelection._setTo( position );
277
+ *
278
+ * // Sets collapsed selection at the position of given item and offset.
279
+ * documentSelection._setTo( paragraph, offset );
280
+ *
281
+ * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of
282
+ * that element and ends after the last child of that element.
283
+ *
284
+ * documentSelection._setTo( paragraph, 'in' );
285
+ *
286
+ * Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends just after the item.
287
+ *
288
+ * documentSelection._setTo( paragraph, 'on' );
289
+ *
290
+ * // Clears selection. Removes all ranges.
291
+ * documentSelection._setTo( null );
292
+ *
293
+ * `Selection#_setTo()` method allow passing additional options (`backward`, `fake` and `label`) as the last argument.
294
+ *
295
+ * // Sets selection as backward.
296
+ * documentSelection._setTo( range, { backward: true } );
297
+ *
298
+ * Fake selection does not render as browser native selection over selected elements and is hidden to the user.
299
+ * This way, no native selection UI artifacts are displayed to the user and selection over elements can be
300
+ * represented in other way, for example by applying proper CSS class.
301
+ *
302
+ * Additionally fake's selection label can be provided. It will be used to des cribe fake selection in DOM
303
+ * (and be properly handled by screen readers).
304
+ *
305
+ * // Creates fake selection with label.
306
+ * documentSelection._setTo( range, { fake: true, label: 'foo' } );
307
+ *
308
+ * @protected
309
+ * @fires change
310
+ * @param {module:engine/view/selection~Selectable} selectable
311
+ * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Sets place or offset of the selection.
312
+ * @param {Object} [options]
313
+ * @param {Boolean} [options.backward] Sets this selection instance to be backward.
314
+ * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.
315
+ * @param {String} [options.label] Label for the fake selection.
316
+ */
317
+ _setTo(...args) {
318
+ this._selection.setTo(...args);
319
+ }
320
+ /**
321
+ * Moves {@link #focus} to the specified location.
322
+ *
323
+ * The location can be specified in the same form as {@link module:engine/view/view~View#createPositionAt view.createPositionAt()}
324
+ * parameters.
325
+ *
326
+ * @protected
327
+ * @fires change
328
+ * @param {module:engine/view/item~Item|module:engine/view/position~Position} itemOrPosition
329
+ * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when
330
+ * first parameter is a {@link module:engine/view/item~Item view item}.
331
+ */
332
+ _setFocus(itemOrPosition, offset) {
333
+ this._selection.setFocus(itemOrPosition, offset);
334
+ }
385
335
  }
386
-
387
- mix( DocumentSelection, EmitterMixin );
336
+ /**
337
+ * Checks whether this object is of the given type.
338
+ *
339
+ * docSelection.is( 'selection' ); // -> true
340
+ * docSelection.is( 'documentSelection' ); // -> true
341
+ * docSelection.is( 'view:selection' ); // -> true
342
+ * docSelection.is( 'view:documentSelection' ); // -> true
343
+ *
344
+ * docSelection.is( 'model:documentSelection' ); // -> false
345
+ * docSelection.is( 'element' ); // -> false
346
+ * docSelection.is( 'node' ); // -> false
347
+ *
348
+ * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.
349
+ *
350
+ * @param {String} type
351
+ * @returns {Boolean}
352
+ */
353
+ DocumentSelection.prototype.is = function (type) {
354
+ return type === 'selection' ||
355
+ type == 'documentSelection' ||
356
+ type == 'view:selection' ||
357
+ type == 'view:documentSelection';
358
+ };