@ckeditor/ckeditor5-engine 35.0.1 → 35.2.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 +176 -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 +980 -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 +757 -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 +199 -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,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
  }