@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,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
  }