@ckeditor/ckeditor5-engine 35.0.1 → 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 (124) hide show
  1. package/CHANGELOG.md +4 -4
  2. package/package.json +30 -24
  3. package/src/controller/datacontroller.js +467 -561
  4. package/src/controller/editingcontroller.js +168 -204
  5. package/src/conversion/conversion.js +541 -565
  6. package/src/conversion/conversionhelpers.js +24 -28
  7. package/src/conversion/downcastdispatcher.js +457 -686
  8. package/src/conversion/downcasthelpers.js +1583 -1965
  9. package/src/conversion/mapper.js +518 -707
  10. package/src/conversion/modelconsumable.js +240 -283
  11. package/src/conversion/upcastdispatcher.js +372 -718
  12. package/src/conversion/upcasthelpers.js +707 -818
  13. package/src/conversion/viewconsumable.js +524 -581
  14. package/src/dataprocessor/basichtmlwriter.js +12 -16
  15. package/src/dataprocessor/dataprocessor.js +5 -0
  16. package/src/dataprocessor/htmldataprocessor.js +100 -116
  17. package/src/dataprocessor/htmlwriter.js +1 -18
  18. package/src/dataprocessor/xmldataprocessor.js +116 -137
  19. package/src/dev-utils/model.js +260 -352
  20. package/src/dev-utils/operationreplayer.js +106 -126
  21. package/src/dev-utils/utils.js +34 -51
  22. package/src/dev-utils/view.js +632 -753
  23. package/src/index.js +0 -11
  24. package/src/model/batch.js +111 -127
  25. package/src/model/differ.js +988 -1233
  26. package/src/model/document.js +340 -449
  27. package/src/model/documentfragment.js +327 -364
  28. package/src/model/documentselection.js +996 -1189
  29. package/src/model/element.js +306 -410
  30. package/src/model/history.js +224 -262
  31. package/src/model/item.js +5 -0
  32. package/src/model/liveposition.js +84 -145
  33. package/src/model/liverange.js +108 -185
  34. package/src/model/markercollection.js +379 -480
  35. package/src/model/model.js +883 -1034
  36. package/src/model/node.js +419 -463
  37. package/src/model/nodelist.js +175 -201
  38. package/src/model/operation/attributeoperation.js +153 -182
  39. package/src/model/operation/detachoperation.js +64 -83
  40. package/src/model/operation/insertoperation.js +135 -166
  41. package/src/model/operation/markeroperation.js +114 -140
  42. package/src/model/operation/mergeoperation.js +163 -191
  43. package/src/model/operation/moveoperation.js +157 -187
  44. package/src/model/operation/nooperation.js +28 -38
  45. package/src/model/operation/operation.js +106 -125
  46. package/src/model/operation/operationfactory.js +30 -34
  47. package/src/model/operation/renameoperation.js +109 -135
  48. package/src/model/operation/rootattributeoperation.js +155 -188
  49. package/src/model/operation/splitoperation.js +196 -232
  50. package/src/model/operation/transform.js +1833 -2204
  51. package/src/model/operation/utils.js +140 -204
  52. package/src/model/position.js +899 -1053
  53. package/src/model/range.js +910 -1028
  54. package/src/model/rootelement.js +77 -97
  55. package/src/model/schema.js +1189 -1835
  56. package/src/model/selection.js +745 -862
  57. package/src/model/text.js +90 -114
  58. package/src/model/textproxy.js +204 -240
  59. package/src/model/treewalker.js +316 -397
  60. package/src/model/typecheckable.js +16 -0
  61. package/src/model/utils/autoparagraphing.js +32 -44
  62. package/src/model/utils/deletecontent.js +334 -418
  63. package/src/model/utils/findoptimalinsertionrange.js +25 -36
  64. package/src/model/utils/getselectedcontent.js +96 -118
  65. package/src/model/utils/insertcontent.js +654 -773
  66. package/src/model/utils/insertobject.js +96 -119
  67. package/src/model/utils/modifyselection.js +120 -158
  68. package/src/model/utils/selection-post-fixer.js +153 -201
  69. package/src/model/writer.js +1305 -1474
  70. package/src/view/attributeelement.js +189 -225
  71. package/src/view/containerelement.js +75 -85
  72. package/src/view/document.js +172 -215
  73. package/src/view/documentfragment.js +200 -249
  74. package/src/view/documentselection.js +338 -367
  75. package/src/view/domconverter.js +1370 -1617
  76. package/src/view/downcastwriter.js +1747 -2076
  77. package/src/view/editableelement.js +81 -97
  78. package/src/view/element.js +739 -890
  79. package/src/view/elementdefinition.js +5 -0
  80. package/src/view/emptyelement.js +82 -92
  81. package/src/view/filler.js +35 -50
  82. package/src/view/item.js +5 -0
  83. package/src/view/matcher.js +260 -559
  84. package/src/view/node.js +274 -360
  85. package/src/view/observer/arrowkeysobserver.js +19 -28
  86. package/src/view/observer/bubblingemittermixin.js +120 -263
  87. package/src/view/observer/bubblingeventinfo.js +47 -55
  88. package/src/view/observer/clickobserver.js +7 -13
  89. package/src/view/observer/compositionobserver.js +14 -24
  90. package/src/view/observer/domeventdata.js +57 -67
  91. package/src/view/observer/domeventobserver.js +40 -64
  92. package/src/view/observer/fakeselectionobserver.js +81 -96
  93. package/src/view/observer/focusobserver.js +45 -61
  94. package/src/view/observer/inputobserver.js +7 -13
  95. package/src/view/observer/keyobserver.js +17 -27
  96. package/src/view/observer/mouseobserver.js +7 -14
  97. package/src/view/observer/mutationobserver.js +220 -315
  98. package/src/view/observer/observer.js +81 -102
  99. package/src/view/observer/selectionobserver.js +191 -246
  100. package/src/view/observer/tabobserver.js +23 -36
  101. package/src/view/placeholder.js +128 -173
  102. package/src/view/position.js +350 -401
  103. package/src/view/range.js +453 -513
  104. package/src/view/rawelement.js +85 -112
  105. package/src/view/renderer.js +874 -1018
  106. package/src/view/rooteditableelement.js +80 -90
  107. package/src/view/selection.js +608 -689
  108. package/src/view/styles/background.js +43 -44
  109. package/src/view/styles/border.js +220 -276
  110. package/src/view/styles/margin.js +8 -17
  111. package/src/view/styles/padding.js +8 -16
  112. package/src/view/styles/utils.js +127 -160
  113. package/src/view/stylesmap.js +728 -905
  114. package/src/view/text.js +102 -126
  115. package/src/view/textproxy.js +144 -170
  116. package/src/view/treewalker.js +383 -479
  117. package/src/view/typecheckable.js +19 -0
  118. package/src/view/uielement.js +166 -187
  119. package/src/view/upcastwriter.js +395 -449
  120. package/src/view/view.js +569 -664
  121. package/src/dataprocessor/dataprocessor.jsdoc +0 -64
  122. package/src/model/item.jsdoc +0 -14
  123. package/src/view/elementdefinition.jsdoc +0 -59
  124. package/src/view/item.jsdoc +0 -14
@@ -2,19 +2,15 @@
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
-
6
5
  /**
7
6
  * @module engine/model/operation/mergeoperation
8
7
  */
9
-
10
8
  import Operation from './operation';
11
9
  import SplitOperation from './splitoperation';
12
10
  import Position from '../position';
13
11
  import Range from '../range';
14
12
  import { _move } from './utils';
15
-
16
13
  import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
17
-
18
14
  /**
19
15
  * Operation to merge two {@link module:engine/model/element~Element elements}.
20
16
  *
@@ -26,191 +22,167 @@ import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
26
22
  * @extends module:engine/model/operation/operation~Operation
27
23
  */
28
24
  export default class MergeOperation extends Operation {
29
- /**
30
- * Creates a merge operation.
31
- *
32
- * @param {module:engine/model/position~Position} sourcePosition Position inside the merged element. All nodes from that
33
- * element after that position will be moved to {@link ~#targetPosition}.
34
- * @param {Number} howMany Summary offset size of nodes which will be moved from the merged element to the new parent.
35
- * @param {module:engine/model/position~Position} targetPosition Position which the nodes from the merged elements will be moved to.
36
- * @param {module:engine/model/position~Position} graveyardPosition Position in graveyard to which the merged element will be moved.
37
- * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation
38
- * can be applied or `null` if the operation operates on detached (non-document) tree.
39
- */
40
- constructor( sourcePosition, howMany, targetPosition, graveyardPosition, baseVersion ) {
41
- super( baseVersion );
42
-
43
- /**
44
- * Position inside the merged element. All nodes from that element after that position will be moved to {@link ~#targetPosition}.
45
- *
46
- * @member {module:engine/model/position~Position} module:engine/model/operation/mergeoperation~MergeOperation#sourcePosition
47
- */
48
- this.sourcePosition = sourcePosition.clone();
49
- // This is, and should always remain, the first position in its parent.
50
- this.sourcePosition.stickiness = 'toPrevious';
51
-
52
- /**
53
- * Summary offset size of nodes which will be moved from the merged element to the new parent.
54
- *
55
- * @member {Number} module:engine/model/operation/mergeoperation~MergeOperation#howMany
56
- */
57
- this.howMany = howMany;
58
-
59
- /**
60
- * Position which the nodes from the merged elements will be moved to.
61
- *
62
- * @member {module:engine/model/position~Position} module:engine/model/operation/mergeoperation~MergeOperation#targetPosition
63
- */
64
- this.targetPosition = targetPosition.clone();
65
- // Except of a rare scenario in `MergeOperation` x `MergeOperation` transformation,
66
- // this is, and should always remain, the last position in its parent.
67
- this.targetPosition.stickiness = 'toNext';
68
-
69
- /**
70
- * Position in graveyard to which the merged element will be moved.
71
- *
72
- * @member {module:engine/model/position~Position} module:engine/model/operation/mergeoperation~MergeOperation#graveyardPosition
73
- */
74
- this.graveyardPosition = graveyardPosition.clone();
75
- }
76
-
77
- /**
78
- * @inheritDoc
79
- */
80
- get type() {
81
- return 'merge';
82
- }
83
-
84
- /**
85
- * Position before the merged element (which will be deleted).
86
- *
87
- * @readonly
88
- * @type {module:engine/model/position~Position}
89
- */
90
- get deletionPosition() {
91
- return new Position( this.sourcePosition.root, this.sourcePosition.path.slice( 0, -1 ) );
92
- }
93
-
94
- /**
95
- * Artificial range that contains all the nodes from the merged element that will be moved to {@link ~MergeOperation#sourcePosition}.
96
- * The range starts at {@link ~MergeOperation#sourcePosition} and ends in the same parent, at `POSITIVE_INFINITY` offset.
97
- *
98
- * @readonly
99
- * @type {module:engine/model/range~Range}
100
- */
101
- get movedRange() {
102
- const end = this.sourcePosition.getShiftedBy( Number.POSITIVE_INFINITY );
103
-
104
- return new Range( this.sourcePosition, end );
105
- }
106
-
107
- /**
108
- * Creates and returns an operation that has the same parameters as this operation.
109
- *
110
- * @returns {module:engine/model/operation/mergeoperation~MergeOperation} Clone of this operation.
111
- */
112
- clone() {
113
- return new this.constructor( this.sourcePosition, this.howMany, this.targetPosition, this.graveyardPosition, this.baseVersion );
114
- }
115
-
116
- /**
117
- * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.
118
- *
119
- * @returns {module:engine/model/operation/splitoperation~SplitOperation}
120
- */
121
- getReversed() {
122
- // Positions in this method are transformed by this merge operation because the split operation bases on
123
- // the context after this merge operation happened (because split operation reverses it).
124
- // So we need to acknowledge that the merge operation happened and those positions changed a little.
125
- const targetPosition = this.targetPosition._getTransformedByMergeOperation( this );
126
-
127
- const path = this.sourcePosition.path.slice( 0, -1 );
128
- const insertionPosition = new Position( this.sourcePosition.root, path )._getTransformedByMergeOperation( this );
129
-
130
- return new SplitOperation( targetPosition, this.howMany, insertionPosition, this.graveyardPosition, this.baseVersion + 1 );
131
- }
132
-
133
- /**
134
- * @inheritDoc
135
- */
136
- _validate() {
137
- const sourceElement = this.sourcePosition.parent;
138
- const targetElement = this.targetPosition.parent;
139
-
140
- // Validate whether merge operation has correct parameters.
141
- if ( !sourceElement.parent ) {
142
- /**
143
- * Merge source position is invalid. The element to be merged must have a parent node.
144
- *
145
- * @error merge-operation-source-position-invalid
146
- */
147
- throw new CKEditorError( 'merge-operation-source-position-invalid', this );
148
- } else if ( !targetElement.parent ) {
149
- /**
150
- * Merge target position is invalid. The element to be merged must have a parent node.
151
- *
152
- * @error merge-operation-target-position-invalid
153
- */
154
- throw new CKEditorError( 'merge-operation-target-position-invalid', this );
155
- } else if ( this.howMany != sourceElement.maxOffset ) {
156
- /**
157
- * Merge operation specifies wrong number of nodes to move.
158
- *
159
- * @error merge-operation-how-many-invalid
160
- */
161
- throw new CKEditorError( 'merge-operation-how-many-invalid', this );
162
- }
163
- }
164
-
165
- /**
166
- * @inheritDoc
167
- */
168
- _execute() {
169
- const mergedElement = this.sourcePosition.parent;
170
- const sourceRange = Range._createIn( mergedElement );
171
-
172
- _move( sourceRange, this.targetPosition );
173
- _move( Range._createOn( mergedElement ), this.graveyardPosition );
174
- }
175
-
176
- /**
177
- * @inheritDoc
178
- */
179
- toJSON() {
180
- const json = super.toJSON();
181
-
182
- json.sourcePosition = json.sourcePosition.toJSON();
183
- json.targetPosition = json.targetPosition.toJSON();
184
- json.graveyardPosition = json.graveyardPosition.toJSON();
185
-
186
- return json;
187
- }
188
-
189
- /**
190
- * @inheritDoc
191
- */
192
- static get className() {
193
- return 'MergeOperation';
194
- }
195
-
196
- /**
197
- * Creates `MergeOperation` object from deserilized object, i.e. from parsed JSON string.
198
- *
199
- * @param {Object} json Deserialized JSON object.
200
- * @param {module:engine/model/document~Document} document Document on which this operation will be applied.
201
- * @returns {module:engine/model/operation/mergeoperation~MergeOperation}
202
- */
203
- static fromJSON( json, document ) {
204
- const sourcePosition = Position.fromJSON( json.sourcePosition, document );
205
- const targetPosition = Position.fromJSON( json.targetPosition, document );
206
- const graveyardPosition = Position.fromJSON( json.graveyardPosition, document );
207
-
208
- return new this( sourcePosition, json.howMany, targetPosition, graveyardPosition, json.baseVersion );
209
- }
210
-
211
- // @if CK_DEBUG_ENGINE // toString() {
212
- // @if CK_DEBUG_ENGINE // return `MergeOperation( ${ this.baseVersion } ): ` +
213
- // @if CK_DEBUG_ENGINE // `${ this.sourcePosition } -> ${ this.targetPosition }` +
214
- // @if CK_DEBUG_ENGINE // ` ( ${ this.howMany } ), ${ this.graveyardPosition }`;
215
- // @if CK_DEBUG_ENGINE // }
25
+ /**
26
+ * Creates a merge operation.
27
+ *
28
+ * @param {module:engine/model/position~Position} sourcePosition Position inside the merged element. All nodes from that
29
+ * element after that position will be moved to {@link ~#targetPosition}.
30
+ * @param {Number} howMany Summary offset size of nodes which will be moved from the merged element to the new parent.
31
+ * @param {module:engine/model/position~Position} targetPosition Position which the nodes from the merged elements will be moved to.
32
+ * @param {module:engine/model/position~Position} graveyardPosition Position in graveyard to which the merged element will be moved.
33
+ * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation
34
+ * can be applied or `null` if the operation operates on detached (non-document) tree.
35
+ */
36
+ constructor(sourcePosition, howMany, targetPosition, graveyardPosition, baseVersion) {
37
+ super(baseVersion);
38
+ /**
39
+ * Position inside the merged element. All nodes from that element after that position will be moved to {@link ~#targetPosition}.
40
+ *
41
+ * @member {module:engine/model/position~Position} module:engine/model/operation/mergeoperation~MergeOperation#sourcePosition
42
+ */
43
+ this.sourcePosition = sourcePosition.clone();
44
+ // This is, and should always remain, the first position in its parent.
45
+ this.sourcePosition.stickiness = 'toPrevious';
46
+ /**
47
+ * Summary offset size of nodes which will be moved from the merged element to the new parent.
48
+ *
49
+ * @member {Number} module:engine/model/operation/mergeoperation~MergeOperation#howMany
50
+ */
51
+ this.howMany = howMany;
52
+ /**
53
+ * Position which the nodes from the merged elements will be moved to.
54
+ *
55
+ * @member {module:engine/model/position~Position} module:engine/model/operation/mergeoperation~MergeOperation#targetPosition
56
+ */
57
+ this.targetPosition = targetPosition.clone();
58
+ // Except of a rare scenario in `MergeOperation` x `MergeOperation` transformation,
59
+ // this is, and should always remain, the last position in its parent.
60
+ this.targetPosition.stickiness = 'toNext';
61
+ /**
62
+ * Position in graveyard to which the merged element will be moved.
63
+ *
64
+ * @member {module:engine/model/position~Position} module:engine/model/operation/mergeoperation~MergeOperation#graveyardPosition
65
+ */
66
+ this.graveyardPosition = graveyardPosition.clone();
67
+ }
68
+ /**
69
+ * @inheritDoc
70
+ */
71
+ get type() {
72
+ return 'merge';
73
+ }
74
+ /**
75
+ * Position before the merged element (which will be deleted).
76
+ *
77
+ * @readonly
78
+ * @type {module:engine/model/position~Position}
79
+ */
80
+ get deletionPosition() {
81
+ return new Position(this.sourcePosition.root, this.sourcePosition.path.slice(0, -1));
82
+ }
83
+ /**
84
+ * Artificial range that contains all the nodes from the merged element that will be moved to {@link ~MergeOperation#sourcePosition}.
85
+ * The range starts at {@link ~MergeOperation#sourcePosition} and ends in the same parent, at `POSITIVE_INFINITY` offset.
86
+ *
87
+ * @readonly
88
+ * @type {module:engine/model/range~Range}
89
+ */
90
+ get movedRange() {
91
+ const end = this.sourcePosition.getShiftedBy(Number.POSITIVE_INFINITY);
92
+ return new Range(this.sourcePosition, end);
93
+ }
94
+ /**
95
+ * Creates and returns an operation that has the same parameters as this operation.
96
+ *
97
+ * @returns {module:engine/model/operation/mergeoperation~MergeOperation} Clone of this operation.
98
+ */
99
+ clone() {
100
+ return new MergeOperation(this.sourcePosition, this.howMany, this.targetPosition, this.graveyardPosition, this.baseVersion);
101
+ }
102
+ /**
103
+ * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.
104
+ *
105
+ * @returns {module:engine/model/operation/splitoperation~SplitOperation}
106
+ */
107
+ getReversed() {
108
+ // Positions in this method are transformed by this merge operation because the split operation bases on
109
+ // the context after this merge operation happened (because split operation reverses it).
110
+ // So we need to acknowledge that the merge operation happened and those positions changed a little.
111
+ const targetPosition = this.targetPosition._getTransformedByMergeOperation(this);
112
+ const path = this.sourcePosition.path.slice(0, -1);
113
+ const insertionPosition = new Position(this.sourcePosition.root, path)._getTransformedByMergeOperation(this);
114
+ return new SplitOperation(targetPosition, this.howMany, insertionPosition, this.graveyardPosition, this.baseVersion + 1);
115
+ }
116
+ /**
117
+ * @inheritDoc
118
+ * @internal
119
+ */
120
+ _validate() {
121
+ const sourceElement = this.sourcePosition.parent;
122
+ const targetElement = this.targetPosition.parent;
123
+ // Validate whether merge operation has correct parameters.
124
+ if (!sourceElement.parent) {
125
+ /**
126
+ * Merge source position is invalid. The element to be merged must have a parent node.
127
+ *
128
+ * @error merge-operation-source-position-invalid
129
+ */
130
+ throw new CKEditorError('merge-operation-source-position-invalid', this);
131
+ }
132
+ else if (!targetElement.parent) {
133
+ /**
134
+ * Merge target position is invalid. The element to be merged must have a parent node.
135
+ *
136
+ * @error merge-operation-target-position-invalid
137
+ */
138
+ throw new CKEditorError('merge-operation-target-position-invalid', this);
139
+ }
140
+ else if (this.howMany != sourceElement.maxOffset) {
141
+ /**
142
+ * Merge operation specifies wrong number of nodes to move.
143
+ *
144
+ * @error merge-operation-how-many-invalid
145
+ */
146
+ throw new CKEditorError('merge-operation-how-many-invalid', this);
147
+ }
148
+ }
149
+ /**
150
+ * @inheritDoc
151
+ * @internal
152
+ */
153
+ _execute() {
154
+ const mergedElement = this.sourcePosition.parent;
155
+ const sourceRange = Range._createIn(mergedElement);
156
+ _move(sourceRange, this.targetPosition);
157
+ _move(Range._createOn(mergedElement), this.graveyardPosition);
158
+ }
159
+ /**
160
+ * @inheritDoc
161
+ */
162
+ toJSON() {
163
+ const json = super.toJSON();
164
+ json.sourcePosition = json.sourcePosition.toJSON();
165
+ json.targetPosition = json.targetPosition.toJSON();
166
+ json.graveyardPosition = json.graveyardPosition.toJSON();
167
+ return json;
168
+ }
169
+ /**
170
+ * @inheritDoc
171
+ */
172
+ static get className() {
173
+ return 'MergeOperation';
174
+ }
175
+ /**
176
+ * Creates `MergeOperation` object from deserilized object, i.e. from parsed JSON string.
177
+ *
178
+ * @param {Object} json Deserialized JSON object.
179
+ * @param {module:engine/model/document~Document} document Document on which this operation will be applied.
180
+ * @returns {module:engine/model/operation/mergeoperation~MergeOperation}
181
+ */
182
+ static fromJSON(json, document) {
183
+ const sourcePosition = Position.fromJSON(json.sourcePosition, document);
184
+ const targetPosition = Position.fromJSON(json.targetPosition, document);
185
+ const graveyardPosition = Position.fromJSON(json.graveyardPosition, document);
186
+ return new this(sourcePosition, json.howMany, targetPosition, graveyardPosition, json.baseVersion);
187
+ }
216
188
  }