@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,17 +2,14 @@
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/attributeoperation
8
7
  */
9
-
10
8
  import Operation from './operation';
9
+ import { _setAttribute } from './utils';
11
10
  import Range from '../range';
12
11
  import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
13
- import { _setAttribute } from './utils';
14
12
  import { isEqual } from 'lodash-es';
15
-
16
13
  /**
17
14
  * Operation to change nodes' attribute.
18
15
  *
@@ -21,182 +18,156 @@ import { isEqual } from 'lodash-es';
21
18
  * @extends module:engine/model/operation/operation~Operation
22
19
  */
23
20
  export default class AttributeOperation extends Operation {
24
- /**
25
- * Creates an operation that changes, removes or adds attributes.
26
- *
27
- * If only `newValue` is set, attribute will be added on a node. Note that all nodes in operation's range must not
28
- * have an attribute with the same key as the added attribute.
29
- *
30
- * If only `oldValue` is set, then attribute with given key will be removed. Note that all nodes in operation's range
31
- * must have an attribute with that key added.
32
- *
33
- * If both `newValue` and `oldValue` are set, then the operation will change the attribute value. Note that all nodes in
34
- * operation's ranges must already have an attribute with given key and `oldValue` as value
35
- *
36
- * @param {module:engine/model/range~Range} range Range on which the operation should be applied. Must be a flat range.
37
- * @param {String} key Key of an attribute to change or remove.
38
- * @param {*} oldValue Old value of the attribute with given key or `null`, if attribute was not set before.
39
- * @param {*} newValue New value of the attribute with given key or `null`, if operation should remove attribute.
40
- * @param {Number|null} baseVersion Document {@link module:engine/model/document~Document#version} on which operation
41
- * can be applied or `null` if the operation operates on detached (non-document) tree.
42
- */
43
- constructor( range, key, oldValue, newValue, baseVersion ) {
44
- super( baseVersion );
45
-
46
- /**
47
- * Range on which operation should be applied.
48
- *
49
- * @readonly
50
- * @member {module:engine/model/range~Range}
51
- */
52
- this.range = range.clone();
53
-
54
- /**
55
- * Key of an attribute to change or remove.
56
- *
57
- * @readonly
58
- * @member {String}
59
- */
60
- this.key = key;
61
-
62
- /**
63
- * Old value of the attribute with given key or `null`, if attribute was not set before.
64
- *
65
- * @readonly
66
- * @member {*}
67
- */
68
- this.oldValue = oldValue === undefined ? null : oldValue;
69
-
70
- /**
71
- * New value of the attribute with given key or `null`, if operation should remove attribute.
72
- *
73
- * @readonly
74
- * @member {*}
75
- */
76
- this.newValue = newValue === undefined ? null : newValue;
77
- }
78
-
79
- /**
80
- * @inheritDoc
81
- */
82
- get type() {
83
- if ( this.oldValue === null ) {
84
- return 'addAttribute';
85
- } else if ( this.newValue === null ) {
86
- return 'removeAttribute';
87
- } else {
88
- return 'changeAttribute';
89
- }
90
- }
91
-
92
- /**
93
- * Creates and returns an operation that has the same parameters as this operation.
94
- *
95
- * @returns {module:engine/model/operation/attributeoperation~AttributeOperation} Clone of this operation.
96
- */
97
- clone() {
98
- return new AttributeOperation( this.range, this.key, this.oldValue, this.newValue, this.baseVersion );
99
- }
100
-
101
- /**
102
- * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.
103
- *
104
- * @returns {module:engine/model/operation/attributeoperation~AttributeOperation}
105
- */
106
- getReversed() {
107
- return new AttributeOperation( this.range, this.key, this.newValue, this.oldValue, this.baseVersion + 1 );
108
- }
109
-
110
- /**
111
- * @inheritDoc
112
- */
113
- toJSON() {
114
- const json = super.toJSON();
115
-
116
- json.range = this.range.toJSON();
117
-
118
- return json;
119
- }
120
-
121
- /**
122
- * @inheritDoc
123
- */
124
- _validate() {
125
- if ( !this.range.isFlat ) {
126
- /**
127
- * The range to change is not flat.
128
- *
129
- * @error attribute-operation-range-not-flat
130
- */
131
- throw new CKEditorError( 'attribute-operation-range-not-flat', this );
132
- }
133
-
134
- for ( const item of this.range.getItems( { shallow: true } ) ) {
135
- if ( this.oldValue !== null && !isEqual( item.getAttribute( this.key ), this.oldValue ) ) {
136
- /**
137
- * Changed node has different attribute value than operation's old attribute value.
138
- *
139
- * @error attribute-operation-wrong-old-value
140
- * @param {module:engine/model/item~Item} item
141
- * @param {String} key
142
- * @param {*} value
143
- */
144
- throw new CKEditorError(
145
- 'attribute-operation-wrong-old-value',
146
- this,
147
- { item, key: this.key, value: this.oldValue }
148
- );
149
- }
150
-
151
- if ( this.oldValue === null && this.newValue !== null && item.hasAttribute( this.key ) ) {
152
- /**
153
- * The attribute with given key already exists for the given node.
154
- *
155
- * @error attribute-operation-attribute-exists
156
- * @param {module:engine/model/node~Node} node
157
- * @param {String} key
158
- */
159
- throw new CKEditorError(
160
- 'attribute-operation-attribute-exists',
161
- this,
162
- { node: item, key: this.key }
163
- );
164
- }
165
- }
166
- }
167
-
168
- /**
169
- * @inheritDoc
170
- */
171
- _execute() {
172
- // If value to set is same as old value, don't do anything.
173
- if ( !isEqual( this.oldValue, this.newValue ) ) {
174
- // Execution.
175
- _setAttribute( this.range, this.key, this.newValue );
176
- }
177
- }
178
-
179
- /**
180
- * @inheritDoc
181
- */
182
- static get className() {
183
- return 'AttributeOperation';
184
- }
185
-
186
- /**
187
- * Creates `AttributeOperation` object from deserilized object, i.e. from parsed JSON string.
188
- *
189
- * @param {Object} json Deserialized JSON object.
190
- * @param {module:engine/model/document~Document} document Document on which this operation will be applied.
191
- * @returns {module:engine/model/operation/attributeoperation~AttributeOperation}
192
- */
193
- static fromJSON( json, document ) {
194
- return new AttributeOperation( Range.fromJSON( json.range, document ), json.key, json.oldValue, json.newValue, json.baseVersion );
195
- }
196
-
197
- // @if CK_DEBUG_ENGINE // toString() {
198
- // @if CK_DEBUG_ENGINE // return `AttributeOperation( ${ this.baseVersion } ): ` +
199
- // @if CK_DEBUG_ENGINE // `"${ this.key }": ${ JSON.stringify( this.oldValue ) }` +
200
- // @if CK_DEBUG_ENGINE // ` -> ${ JSON.stringify( this.newValue ) }, ${ this.range }`;
201
- // @if CK_DEBUG_ENGINE // }
21
+ /**
22
+ * Creates an operation that changes, removes or adds attributes.
23
+ *
24
+ * If only `newValue` is set, attribute will be added on a node. Note that all nodes in operation's range must not
25
+ * have an attribute with the same key as the added attribute.
26
+ *
27
+ * If only `oldValue` is set, then attribute with given key will be removed. Note that all nodes in operation's range
28
+ * must have an attribute with that key added.
29
+ *
30
+ * If both `newValue` and `oldValue` are set, then the operation will change the attribute value. Note that all nodes in
31
+ * operation's ranges must already have an attribute with given key and `oldValue` as value
32
+ *
33
+ * @param {module:engine/model/range~Range} range Range on which the operation should be applied. Must be a flat range.
34
+ * @param {String} key Key of an attribute to change or remove.
35
+ * @param {*} oldValue Old value of the attribute with given key or `null`, if attribute was not set before.
36
+ * @param {*} newValue New value of the attribute with given key or `null`, if operation should remove attribute.
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(range, key, oldValue, newValue, baseVersion) {
41
+ super(baseVersion);
42
+ /**
43
+ * Range on which operation should be applied.
44
+ *
45
+ * @readonly
46
+ * @member {module:engine/model/range~Range}
47
+ */
48
+ this.range = range.clone();
49
+ /**
50
+ * Key of an attribute to change or remove.
51
+ *
52
+ * @readonly
53
+ * @member {String}
54
+ */
55
+ this.key = key;
56
+ /**
57
+ * Old value of the attribute with given key or `null`, if attribute was not set before.
58
+ *
59
+ * @readonly
60
+ * @member {*}
61
+ */
62
+ this.oldValue = oldValue === undefined ? null : oldValue;
63
+ /**
64
+ * New value of the attribute with given key or `null`, if operation should remove attribute.
65
+ *
66
+ * @readonly
67
+ * @member {*}
68
+ */
69
+ this.newValue = newValue === undefined ? null : newValue;
70
+ }
71
+ /**
72
+ * @inheritDoc
73
+ */
74
+ get type() {
75
+ if (this.oldValue === null) {
76
+ return 'addAttribute';
77
+ }
78
+ else if (this.newValue === null) {
79
+ return 'removeAttribute';
80
+ }
81
+ else {
82
+ return 'changeAttribute';
83
+ }
84
+ }
85
+ /**
86
+ * Creates and returns an operation that has the same parameters as this operation.
87
+ *
88
+ * @returns {module:engine/model/operation/attributeoperation~AttributeOperation} Clone of this operation.
89
+ */
90
+ clone() {
91
+ return new AttributeOperation(this.range, this.key, this.oldValue, this.newValue, this.baseVersion);
92
+ }
93
+ /**
94
+ * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.
95
+ *
96
+ * @returns {module:engine/model/operation/attributeoperation~AttributeOperation}
97
+ */
98
+ getReversed() {
99
+ return new AttributeOperation(this.range, this.key, this.newValue, this.oldValue, this.baseVersion + 1);
100
+ }
101
+ /**
102
+ * @inheritDoc
103
+ */
104
+ toJSON() {
105
+ const json = super.toJSON();
106
+ json.range = this.range.toJSON();
107
+ return json;
108
+ }
109
+ /**
110
+ * @inheritDoc
111
+ * @internal
112
+ */
113
+ _validate() {
114
+ if (!this.range.isFlat) {
115
+ /**
116
+ * The range to change is not flat.
117
+ *
118
+ * @error attribute-operation-range-not-flat
119
+ */
120
+ throw new CKEditorError('attribute-operation-range-not-flat', this);
121
+ }
122
+ for (const item of this.range.getItems({ shallow: true })) {
123
+ if (this.oldValue !== null && !isEqual(item.getAttribute(this.key), this.oldValue)) {
124
+ /**
125
+ * Changed node has different attribute value than operation's old attribute value.
126
+ *
127
+ * @error attribute-operation-wrong-old-value
128
+ * @param {module:engine/model/item~Item} item
129
+ * @param {String} key
130
+ * @param {*} value
131
+ */
132
+ throw new CKEditorError('attribute-operation-wrong-old-value', this, { item, key: this.key, value: this.oldValue });
133
+ }
134
+ if (this.oldValue === null && this.newValue !== null && item.hasAttribute(this.key)) {
135
+ /**
136
+ * The attribute with given key already exists for the given node.
137
+ *
138
+ * @error attribute-operation-attribute-exists
139
+ * @param {module:engine/model/node~Node} node
140
+ * @param {String} key
141
+ */
142
+ throw new CKEditorError('attribute-operation-attribute-exists', this, { node: item, key: this.key });
143
+ }
144
+ }
145
+ }
146
+ /**
147
+ * @inheritDoc
148
+ * @internal
149
+ */
150
+ _execute() {
151
+ // If value to set is same as old value, don't do anything.
152
+ if (!isEqual(this.oldValue, this.newValue)) {
153
+ // Execution.
154
+ _setAttribute(this.range, this.key, this.newValue);
155
+ }
156
+ }
157
+ /**
158
+ * @inheritDoc
159
+ */
160
+ static get className() {
161
+ return 'AttributeOperation';
162
+ }
163
+ /**
164
+ * Creates `AttributeOperation` object from deserilized object, i.e. from parsed JSON string.
165
+ *
166
+ * @param {Object} json Deserialized JSON object.
167
+ * @param {module:engine/model/document~Document} document Document on which this operation will be applied.
168
+ * @returns {module:engine/model/operation/attributeoperation~AttributeOperation}
169
+ */
170
+ static fromJSON(json, document) {
171
+ return new AttributeOperation(Range.fromJSON(json.range, document), json.key, json.oldValue, json.newValue, json.baseVersion);
172
+ }
202
173
  }
@@ -2,18 +2,14 @@
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/detachoperation
8
7
  */
9
-
10
8
  import Operation from './operation';
11
9
  import Range from '../range';
12
10
  import { _remove } from './utils';
13
11
  import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
14
-
15
12
  // @if CK_DEBUG_ENGINE // const ModelRange = require( '../range' ).default;
16
-
17
13
  /**
18
14
  * Operation to permanently remove node from detached root.
19
15
  * Note this operation is only a local operation and won't be send to the other clients.
@@ -21,83 +17,68 @@ import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
21
17
  * @extends module:engine/model/operation/operation~Operation
22
18
  */
23
19
  export default class DetachOperation extends Operation {
24
- /**
25
- * Creates an insert operation.
26
- *
27
- * @param {module:engine/model/position~Position} sourcePosition
28
- * Position before the first {@link module:engine/model/item~Item model item} to move.
29
- * @param {Number} howMany Offset size of moved range. Moved range will start from `sourcePosition` and end at
30
- * `sourcePosition` with offset shifted by `howMany`.
31
- */
32
- constructor( sourcePosition, howMany ) {
33
- super( null );
34
-
35
- /**
36
- * Position before the first {@link module:engine/model/item~Item model item} to detach.
37
- *
38
- * @member {module:engine/model/position~Position} #sourcePosition
39
- */
40
- this.sourcePosition = sourcePosition.clone();
41
-
42
- /**
43
- * Offset size of moved range.
44
- *
45
- * @member {Number} #howMany
46
- */
47
- this.howMany = howMany;
48
- }
49
-
50
- /**
51
- * @inheritDoc
52
- */
53
- get type() {
54
- return 'detach';
55
- }
56
-
57
- /**
58
- * @inheritDoc
59
- */
60
- toJSON() {
61
- const json = super.toJSON();
62
-
63
- json.sourcePosition = this.sourcePosition.toJSON();
64
-
65
- return json;
66
- }
67
-
68
- /**
69
- * @inheritDoc
70
- */
71
- _validate() {
72
- if ( this.sourcePosition.root.document ) {
73
- /**
74
- * Cannot detach document node.
75
- *
76
- * @error detach-operation-on-document-node
77
- */
78
- throw new CKEditorError( 'detach-operation-on-document-node', this );
79
- }
80
- }
81
-
82
- /**
83
- * @inheritDoc
84
- */
85
- _execute() {
86
- _remove( Range._createFromPositionAndShift( this.sourcePosition, this.howMany ) );
87
- }
88
-
89
- /**
90
- * @inheritDoc
91
- */
92
- static get className() {
93
- return 'DetachOperation';
94
- }
95
-
96
- // @if CK_DEBUG_ENGINE // toString() {
97
- // @if CK_DEBUG_ENGINE // const range = ModelRange._createFromPositionAndShift( this.sourcePosition, this.howMany );
98
- // @if CK_DEBUG_ENGINE // const nodes = Array.from( range.getItems() );
99
- // @if CK_DEBUG_ENGINE // const nodeString = nodes.length > 1 ? `[ ${ nodes.length } ]` : nodes[ 0 ];
100
-
101
- // @if CK_DEBUG_ENGINE // return `DetachOperation( ${ this.baseVersion } ): ${ nodeString } -> ${ range }`;
102
- // @if CK_DEBUG_ENGINE // }
20
+ /**
21
+ * Creates an insert operation.
22
+ *
23
+ * @param {module:engine/model/position~Position} sourcePosition
24
+ * Position before the first {@link module:engine/model/item~Item model item} to move.
25
+ * @param {Number} howMany Offset size of moved range. Moved range will start from `sourcePosition` and end at
26
+ * `sourcePosition` with offset shifted by `howMany`.
27
+ */
28
+ constructor(sourcePosition, howMany) {
29
+ super(null);
30
+ /**
31
+ * Position before the first {@link module:engine/model/item~Item model item} to detach.
32
+ *
33
+ * @member {module:engine/model/position~Position} #sourcePosition
34
+ */
35
+ this.sourcePosition = sourcePosition.clone();
36
+ /**
37
+ * Offset size of moved range.
38
+ *
39
+ * @member {Number} #howMany
40
+ */
41
+ this.howMany = howMany;
42
+ }
43
+ /**
44
+ * @inheritDoc
45
+ */
46
+ get type() {
47
+ return 'detach';
48
+ }
49
+ /**
50
+ * @inheritDoc
51
+ */
52
+ toJSON() {
53
+ const json = super.toJSON();
54
+ json.sourcePosition = this.sourcePosition.toJSON();
55
+ return json;
56
+ }
57
+ /**
58
+ * @inheritDoc
59
+ * @internal
60
+ */
61
+ _validate() {
62
+ if (this.sourcePosition.root.document) {
63
+ /**
64
+ * Cannot detach document node.
65
+ *
66
+ * @error detach-operation-on-document-node
67
+ */
68
+ throw new CKEditorError('detach-operation-on-document-node', this);
69
+ }
70
+ }
71
+ /**
72
+ * @inheritDoc
73
+ * @internal
74
+ */
75
+ _execute() {
76
+ _remove(Range._createFromPositionAndShift(this.sourcePosition, this.howMany));
77
+ }
78
+ /**
79
+ * @inheritDoc
80
+ */
81
+ static get className() {
82
+ return 'DetachOperation';
83
+ }
103
84
  }