@ckeditor/ckeditor5-engine 31.1.0 → 34.0.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 (121) hide show
  1. package/LICENSE.md +2 -2
  2. package/README.md +2 -1
  3. package/package.json +25 -25
  4. package/src/controller/datacontroller.js +65 -74
  5. package/src/controller/editingcontroller.js +83 -6
  6. package/src/conversion/conversion.js +15 -14
  7. package/src/conversion/conversionhelpers.js +1 -1
  8. package/src/conversion/downcastdispatcher.js +298 -367
  9. package/src/conversion/downcasthelpers.js +860 -81
  10. package/src/conversion/mapper.js +105 -60
  11. package/src/conversion/modelconsumable.js +85 -35
  12. package/src/conversion/upcastdispatcher.js +34 -7
  13. package/src/conversion/upcasthelpers.js +4 -2
  14. package/src/conversion/viewconsumable.js +1 -1
  15. package/src/dataprocessor/basichtmlwriter.js +1 -1
  16. package/src/dataprocessor/dataprocessor.jsdoc +1 -1
  17. package/src/dataprocessor/htmldataprocessor.js +9 -31
  18. package/src/dataprocessor/htmlwriter.js +1 -1
  19. package/src/dataprocessor/xmldataprocessor.js +1 -1
  20. package/src/dev-utils/model.js +16 -14
  21. package/src/dev-utils/operationreplayer.js +1 -1
  22. package/src/dev-utils/utils.js +1 -1
  23. package/src/dev-utils/view.js +1 -1
  24. package/src/index.js +8 -1
  25. package/src/model/batch.js +77 -10
  26. package/src/model/differ.js +115 -69
  27. package/src/model/document.js +13 -4
  28. package/src/model/documentfragment.js +1 -1
  29. package/src/model/documentselection.js +1 -1
  30. package/src/model/element.js +1 -1
  31. package/src/model/history.js +1 -1
  32. package/src/model/item.jsdoc +1 -1
  33. package/src/model/liveposition.js +1 -1
  34. package/src/model/liverange.js +1 -1
  35. package/src/model/markercollection.js +29 -5
  36. package/src/model/model.js +138 -12
  37. package/src/model/node.js +1 -1
  38. package/src/model/nodelist.js +1 -1
  39. package/src/model/operation/attributeoperation.js +1 -1
  40. package/src/model/operation/detachoperation.js +1 -1
  41. package/src/model/operation/insertoperation.js +1 -1
  42. package/src/model/operation/markeroperation.js +1 -1
  43. package/src/model/operation/mergeoperation.js +1 -1
  44. package/src/model/operation/moveoperation.js +1 -1
  45. package/src/model/operation/nooperation.js +1 -1
  46. package/src/model/operation/operation.js +1 -1
  47. package/src/model/operation/operationfactory.js +1 -1
  48. package/src/model/operation/renameoperation.js +1 -1
  49. package/src/model/operation/rootattributeoperation.js +1 -1
  50. package/src/model/operation/splitoperation.js +1 -1
  51. package/src/model/operation/transform.js +1 -1
  52. package/src/model/operation/utils.js +1 -1
  53. package/src/model/position.js +1 -1
  54. package/src/model/range.js +1 -1
  55. package/src/model/rootelement.js +1 -1
  56. package/src/model/schema.js +80 -11
  57. package/src/model/selection.js +1 -1
  58. package/src/model/text.js +1 -1
  59. package/src/model/textproxy.js +1 -1
  60. package/src/model/treewalker.js +3 -4
  61. package/src/model/utils/autoparagraphing.js +1 -1
  62. package/src/model/utils/deletecontent.js +16 -3
  63. package/src/model/utils/findoptimalinsertionrange.js +68 -0
  64. package/src/model/utils/getselectedcontent.js +1 -1
  65. package/src/model/utils/insertcontent.js +1 -1
  66. package/src/model/utils/insertobject.js +173 -0
  67. package/src/model/utils/modifyselection.js +15 -8
  68. package/src/model/utils/selection-post-fixer.js +1 -1
  69. package/src/model/writer.js +17 -27
  70. package/src/view/attributeelement.js +1 -11
  71. package/src/view/containerelement.js +1 -1
  72. package/src/view/document.js +3 -2
  73. package/src/view/documentfragment.js +1 -1
  74. package/src/view/documentselection.js +1 -1
  75. package/src/view/domconverter.js +55 -28
  76. package/src/view/downcastwriter.js +91 -50
  77. package/src/view/editableelement.js +1 -1
  78. package/src/view/element.js +1 -28
  79. package/src/view/elementdefinition.jsdoc +1 -1
  80. package/src/view/emptyelement.js +1 -4
  81. package/src/view/filler.js +1 -1
  82. package/src/view/item.jsdoc +1 -1
  83. package/src/view/matcher.js +3 -3
  84. package/src/view/node.js +1 -1
  85. package/src/view/observer/arrowkeysobserver.js +1 -1
  86. package/src/view/observer/bubblingemittermixin.js +1 -1
  87. package/src/view/observer/bubblingeventinfo.js +1 -1
  88. package/src/view/observer/clickobserver.js +1 -2
  89. package/src/view/observer/compositionobserver.js +1 -1
  90. package/src/view/observer/domeventdata.js +1 -1
  91. package/src/view/observer/domeventobserver.js +1 -1
  92. package/src/view/observer/fakeselectionobserver.js +1 -1
  93. package/src/view/observer/focusobserver.js +1 -1
  94. package/src/view/observer/inputobserver.js +2 -2
  95. package/src/view/observer/keyobserver.js +1 -1
  96. package/src/view/observer/mouseobserver.js +1 -1
  97. package/src/view/observer/mutationobserver.js +1 -1
  98. package/src/view/observer/observer.js +1 -1
  99. package/src/view/observer/selectionobserver.js +1 -1
  100. package/src/view/observer/tabobserver.js +68 -0
  101. package/src/view/placeholder.js +2 -2
  102. package/src/view/position.js +1 -1
  103. package/src/view/range.js +1 -1
  104. package/src/view/rawelement.js +1 -4
  105. package/src/view/renderer.js +3 -2
  106. package/src/view/rooteditableelement.js +1 -1
  107. package/src/view/selection.js +1 -1
  108. package/src/view/styles/background.js +1 -1
  109. package/src/view/styles/border.js +1 -1
  110. package/src/view/styles/margin.js +1 -1
  111. package/src/view/styles/padding.js +1 -1
  112. package/src/view/styles/utils.js +1 -1
  113. package/src/view/stylesmap.js +1 -1
  114. package/src/view/text.js +1 -1
  115. package/src/view/textproxy.js +1 -1
  116. package/src/view/treewalker.js +1 -1
  117. package/src/view/uielement.js +1 -4
  118. package/src/view/upcastwriter.js +1 -1
  119. package/src/view/view.js +5 -1
  120. package/theme/placeholder.css +10 -1
  121. package/theme/renderer.css +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -40,10 +40,7 @@ import mix from '@ckeditor/ckeditor5-utils/src/mix';
40
40
  * The third parameter of the callback is an instance of {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi}
41
41
  * which provides additional tools for converters.
42
42
  *
43
- * You can read more about conversion in the following guides:
44
- *
45
- * * {@glink framework/guides/deep-dive/conversion/conversion-introduction Advanced conversion concepts — attributes}
46
- * * {@glink framework/guides/deep-dive/conversion/custom-element-conversion Custom element conversion}
43
+ * You can read more about conversion in the {@glink framework/guides/deep-dive/conversion/upcast Upcast conversion} guide.
47
44
  *
48
45
  * Examples of event-based converters:
49
46
  *
@@ -127,7 +124,7 @@ export default class UpcastDispatcher {
127
124
  /**
128
125
  * The list of elements that were created during splitting.
129
126
  *
130
- * After the conversion process the list is cleared.
127
+ * After the conversion process, the list is cleared.
131
128
  *
132
129
  * @private
133
130
  * @type {Map.<module:engine/model/element~Element,Array.<module:engine/model/element~Element>>}
@@ -154,6 +151,16 @@ export default class UpcastDispatcher {
154
151
  */
155
152
  this._modelCursor = null;
156
153
 
154
+ /**
155
+ * The list of elements that were created during splitting but should not get removed on conversion end even if they are empty.
156
+ *
157
+ * After the conversion process the list is cleared.
158
+ *
159
+ * @private
160
+ * @type {Set.<module:engine/model/element~Element>}
161
+ */
162
+ this._emptyElementsToKeep = new Set();
163
+
157
164
  /**
158
165
  * An interface passed by the dispatcher to the event callbacks.
159
166
  *
@@ -170,6 +177,7 @@ export default class UpcastDispatcher {
170
177
  // Advanced API - use only if custom position handling is needed.
171
178
  this.conversionApi.splitToAllowedParent = this._splitToAllowedParent.bind( this );
172
179
  this.conversionApi.getSplitParts = this._getSplitParts.bind( this );
180
+ this.conversionApi.keepEmptyElement = this._keepEmptyElement.bind( this );
173
181
  }
174
182
 
175
183
  /**
@@ -229,6 +237,7 @@ export default class UpcastDispatcher {
229
237
  // Clear split elements & parents lists.
230
238
  this._splitParts.clear();
231
239
  this._cursorParents.clear();
240
+ this._emptyElementsToKeep.clear();
232
241
 
233
242
  // Clear conversion API.
234
243
  this.conversionApi.writer = null;
@@ -454,6 +463,15 @@ export default class UpcastDispatcher {
454
463
  return parts;
455
464
  }
456
465
 
466
+ /**
467
+ * Mark an element that were created during splitting that it should not get removed on conversion end even if it's empty.
468
+ *
469
+ * @private
470
+ */
471
+ _keepEmptyElement( element ) {
472
+ this._emptyElementsToKeep.add( element );
473
+ }
474
+
457
475
  /**
458
476
  * Checks if there are any empty elements created while splitting and removes them.
459
477
  *
@@ -466,7 +484,7 @@ export default class UpcastDispatcher {
466
484
  let anyRemoved = false;
467
485
 
468
486
  for ( const element of this._splitParts.keys() ) {
469
- if ( element.isEmpty ) {
487
+ if ( element.isEmpty && !this._emptyElementsToKeep.has( element ) ) {
470
488
  this.conversionApi.writer.remove( element );
471
489
  this._splitParts.delete( element );
472
490
 
@@ -760,6 +778,15 @@ function createContextTree( contextDefinition, writer ) {
760
778
  * @returns {Array.<module:engine/model/element~Element>}
761
779
  */
762
780
 
781
+ /**
782
+ * Mark an element that was created during splitting that it should not get removed on conversion end even if it's empty.
783
+ *
784
+ * **Note:** This is an advanced method. For most cases you will not need to keep the split empty element.
785
+ *
786
+ * @method #keepEmptyElement
787
+ * @param {module:engine/model/element~Element} element
788
+ */
789
+
763
790
  /**
764
791
  * Stores information about what parts of the processed view item are still waiting to be handled. After a piece of view item
765
792
  * was converted, an appropriate consumable value should be
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -12,7 +12,7 @@ import priorities from '@ckeditor/ckeditor5-utils/src/priorities';
12
12
  import { isParagraphable, wrapInParagraph } from '../model/utils/autoparagraphing';
13
13
 
14
14
  /**
15
- * Contains {@link module:engine/view/view view} to {@link module:engine/model/model model} converters for
15
+ * Contains the {@link module:engine/view/view view} to {@link module:engine/model/model model} converters for
16
16
  * {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher}.
17
17
  *
18
18
  * @module engine/conversion/upcasthelpers
@@ -21,6 +21,8 @@ import { isParagraphable, wrapInParagraph } from '../model/utils/autoparagraphin
21
21
  /**
22
22
  * Upcast conversion helper functions.
23
23
  *
24
+ * Learn more about {@glink framework/guides/deep-dive/conversion/upcast upcast helpers}.
25
+ *
24
26
  * @extends module:engine/conversion/conversionhelpers~ConversionHelpers
25
27
  */
26
28
  export default class UpcastHelpers extends ConversionHelpers {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -7,7 +7,7 @@
7
7
  * @module engine/dataprocessor/htmldataprocessor
8
8
  */
9
9
 
10
- /* globals document, DOMParser, Node */
10
+ /* globals document, DOMParser */
11
11
 
12
12
  import BasicHtmlWriter from './basichtmlwriter';
13
13
  import DomConverter from '../view/domconverter';
@@ -114,37 +114,15 @@ export default class HtmlDataProcessor {
114
114
  * @returns {DocumentFragment}
115
115
  */
116
116
  _toDom( data ) {
117
- const document = this.domParser.parseFromString( data, 'text/html' );
118
- const fragment = document.createDocumentFragment();
119
-
120
- // The rules for parsing an HTML string can be read on https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inhtml.
121
- //
122
- // In short, parsing tokens in an HTML string starts with the so-called "initial" insertion mode. When a DOM parser is in this
123
- // state and encounters a comment node, it inserts this comment node as the last child of the newly-created `HTMLDocument` object.
124
- // The parser then proceeds to successive insertion modes during parsing subsequent tokens and appends in the `HTMLDocument` object
125
- // other nodes (like <html>, <head>, <body>). This causes that the first leading comments from HTML string become the first nodes
126
- // in the `HTMLDocument` object, but not in the <body> collection, because they are ultimately located before the <html> element.
127
- //
128
- // Therefore, so that such leading comments do not disappear, they all are moved from the `HTMLDocument` object to the document
129
- // fragment, until the <html> element is encountered.
130
- //
131
- // See: https://github.com/ckeditor/ckeditor5/issues/9861.
132
- let documentChildNode = document.firstChild;
133
-
134
- while ( !documentChildNode.isSameNode( document.documentElement ) ) {
135
- const node = documentChildNode;
136
-
137
- documentChildNode = documentChildNode.nextSibling;
138
-
139
- // It seems that `DOMParser#parseFromString()` adds only comment nodes directly to the `HTMLDocument` object, before the <html>
140
- // node. The condition below is just to be sure we are moving only comment nodes.
141
-
142
- /* istanbul ignore else */
143
- if ( node.nodeType == Node.COMMENT_NODE ) {
144
- fragment.appendChild( node );
145
- }
117
+ // Wrap data with a <body> tag so leading non-layout nodes (like <script>, <style>, HTML comment)
118
+ // will be preserved in the body collection.
119
+ // Do it only for data that is not a full HTML document.
120
+ if ( !data.match( /<(?:html|body|head|meta)(?:\s[^>]*)?>/i ) ) {
121
+ data = `<body>${ data }</body>`;
146
122
  }
147
123
 
124
+ const document = this.domParser.parseFromString( data, 'text/html' );
125
+ const fragment = document.createDocumentFragment();
148
126
  const bodyChildNodes = document.body.childNodes;
149
127
 
150
128
  while ( bodyChildNodes.length > 0 ) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -31,6 +31,7 @@ import Mapper from '../conversion/mapper';
31
31
  import {
32
32
  convertCollapsedSelection,
33
33
  convertRangeSelection,
34
+ insertAttributesAndChildren,
34
35
  insertElement,
35
36
  insertText,
36
37
  insertUIElement,
@@ -102,7 +103,7 @@ getData._stringify = stringify;
102
103
  * name will be used.
103
104
  * @param {Array<Object>} [options.selectionAttributes] A list of attributes which will be passed to the selection.
104
105
  * @param {Boolean} [options.lastRangeBackward=false] If set to `true`, the last range will be added as backward.
105
- * @param {String} [options.batchType='default'] Batch type used for inserting elements.
106
+ * @param {Object} [options.batchType] Batch type used for inserting elements. See {@link module:engine/model/batch~Batch#constructor}.
106
107
  * See {@link module:engine/model/batch~Batch#type}.
107
108
  */
108
109
  export function setData( model, data, options = {} ) {
@@ -128,7 +129,7 @@ export function setData( model, data, options = {} ) {
128
129
  modelDocumentFragment = parsedResult;
129
130
  }
130
131
 
131
- if ( typeof options.batchType === 'string' ) {
132
+ if ( options.batchType !== undefined ) {
132
133
  model.enqueueChange( options.batchType, writeToModel );
133
134
  } else {
134
135
  model.change( writeToModel );
@@ -233,6 +234,7 @@ export function stringify( node, selectionOrPositionOrRange = null, markers = nu
233
234
  mapper.bindElements( node.root, viewRoot );
234
235
 
235
236
  downcastDispatcher.on( 'insert:$text', insertText() );
237
+ downcastDispatcher.on( 'insert', insertAttributesAndChildren(), { priority: 'lowest' } );
236
238
  downcastDispatcher.on( 'attribute', ( evt, data, conversionApi ) => {
237
239
  if ( data.item instanceof ModelSelection || data.item instanceof DocumentSelection || data.item.is( '$textProxy' ) ) {
238
240
  const converter = wrap( ( modelAttributeValue, { writer } ) => {
@@ -260,28 +262,28 @@ export function stringify( node, selectionOrPositionOrRange = null, markers = nu
260
262
  return writer.createUIElement( name );
261
263
  } ) );
262
264
 
265
+ const markersMap = new Map();
266
+
267
+ if ( markers ) {
268
+ // To provide stable results, sort markers by name.
269
+ for ( const marker of Array.from( markers ).sort( ( a, b ) => a.name < b.name ? 1 : -1 ) ) {
270
+ markersMap.set( marker.name, marker.getRange() );
271
+ }
272
+ }
273
+
263
274
  // Convert model to view.
264
275
  const writer = view._writer;
265
- downcastDispatcher.convertInsert( range, writer );
276
+ downcastDispatcher.convert( range, markersMap, writer );
266
277
 
267
278
  // Convert model selection to view selection.
268
279
  if ( selection ) {
269
280
  downcastDispatcher.convertSelection( selection, markers || model.markers, writer );
270
281
  }
271
282
 
272
- if ( markers ) {
273
- // To provide stable results, sort markers by name.
274
- markers = Array.from( markers ).sort( ( a, b ) => a.name < b.name ? 1 : -1 );
275
-
276
- for ( const marker of markers ) {
277
- downcastDispatcher.convertMarkerAdd( marker.name, marker.getRange(), writer );
278
- }
279
- }
280
-
281
283
  // Parse view to data string.
282
284
  let data = viewStringify( viewRoot, viewDocument.selection, { sameSelectionCharacters: true } );
283
285
 
284
- // Removing unneccessary <div> and </div> added because `viewRoot` was also stringified alongside input data.
286
+ // Removing unnecessary <div> and </div> added because `viewRoot` was also stringified alongside input data.
285
287
  data = data.substr( 5, data.length - 11 );
286
288
 
287
289
  view.destroy();
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
package/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -28,10 +28,17 @@ export { default as LivePosition } from './model/liveposition';
28
28
  export { default as Model } from './model/model';
29
29
  export { default as TreeWalker } from './model/treewalker';
30
30
  export { default as Element } from './model/element';
31
+ export { default as Position } from './model/position';
32
+ export { default as DocumentFragment } from './model/documentfragment';
33
+ export { default as History } from './model/history';
34
+ export { default as Text } from './model/text';
31
35
 
32
36
  export { default as DomConverter } from './view/domconverter';
33
37
  export { default as Renderer } from './view/renderer';
34
38
  export { default as ViewDocument } from './view/document';
39
+ export { default as ViewText } from './view/text';
40
+ export { default as ViewElement } from './view/element';
41
+ export { default as ViewDocumentFragment } from './view/documentfragment';
35
42
 
36
43
  export { getFillerOffset } from './view/containerelement';
37
44
  export { default as Observer } from './view/observer/observer';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
2
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
 
@@ -7,6 +7,8 @@
7
7
  * @module engine/model/batch
8
8
  */
9
9
 
10
+ import { logWarning } from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
11
+
10
12
  /**
11
13
  * A batch instance groups model changes ({@link module:engine/model/operation/operation~Operation operations}). All operations
12
14
  * grouped in a single batch can be reverted together, so you can also think about a batch as of a single undo step. If you want
@@ -25,9 +27,30 @@ export default class Batch {
25
27
  *
26
28
  * @see module:engine/model/model~Model#enqueueChange
27
29
  * @see module:engine/model/model~Model#change
28
- * @param {'transparent'|'default'} [type='default'] The type of the batch.
30
+ * @param {Object} [type] A set of flags that specify the type of the batch. Batch type can alter how some of the features work
31
+ * when encountering a given `Batch` instance (for example, when a feature listens to applied operations).
32
+ * @param {Boolean} [type.isUndoable=true] Whether a batch can be undone through undo feature.
33
+ * @param {Boolean} [type.isLocal=true] Whether a batch includes operations created locally (`true`) or operations created on
34
+ * other, remote editors (`false`).
35
+ * @param {Boolean} [type.isUndo=false] Whether a batch was created by the undo feature and undoes other operations.
36
+ * @param {Boolean} [type.isTyping=false] Whether a batch includes operations connected with a typing action.
29
37
  */
30
- constructor( type = 'default' ) {
38
+ constructor( type = {} ) {
39
+ if ( typeof type === 'string' ) {
40
+ type = type === 'transparent' ? { isUndoable: false } : {};
41
+
42
+ /**
43
+ * The string value for a `type` property of the `Batch` constructor has been deprecated and will be removed in the near future.
44
+ * Please refer to the {@link module:engine/model/batch~Batch#constructor `Batch` constructor API documentation} for more
45
+ * information.
46
+ *
47
+ * @error batch-constructor-deprecated-string-type
48
+ */
49
+ logWarning( 'batch-constructor-deprecated-string-type' );
50
+ }
51
+
52
+ const { isUndoable = true, isLocal = true, isUndo = false, isTyping = false } = type;
53
+
31
54
  /**
32
55
  * An array of operations that compose this batch.
33
56
  *
@@ -37,17 +60,61 @@ export default class Batch {
37
60
  this.operations = [];
38
61
 
39
62
  /**
40
- * The type of the batch.
63
+ * Whether the batch can be undone through the undo feature.
64
+ *
65
+ * @readonly
66
+ * @type {Boolean}
67
+ */
68
+ this.isUndoable = isUndoable;
69
+
70
+ /**
71
+ * Whether the batch includes operations created locally (`true`) or operations created on other, remote editors (`false`).
72
+ *
73
+ * @readonly
74
+ * @type {Boolean}
75
+ */
76
+ this.isLocal = isLocal;
77
+
78
+ /**
79
+ * Whether the batch was created by the undo feature and undoes other operations.
41
80
  *
42
- * It can be one of the following values:
43
- * * `'default'` &ndash; All "normal" batches. This is the most commonly used type.
44
- * * `'transparent'` &ndash; A batch that should be ignored by other features, i.e. an initial batch or collaborative editing
45
- * changes.
81
+ * @readonly
82
+ * @type {Boolean}
83
+ */
84
+ this.isUndo = isUndo;
85
+
86
+ /**
87
+ * Whether the batch includes operations connected with typing.
46
88
  *
47
89
  * @readonly
48
- * @type {'transparent'|'default'}
90
+ * @type {Boolean}
49
91
  */
50
- this.type = type;
92
+ this.isTyping = isTyping;
93
+ }
94
+
95
+ /**
96
+ * The type of the batch.
97
+ *
98
+ * **This property has been deprecated and is always set to the `'default'` value.**
99
+ *
100
+ * It can be one of the following values:
101
+ * * `'default'` &ndash; All "normal" batches. This is the most commonly used type.
102
+ * * `'transparent'` &ndash; A batch that should be ignored by other features, i.e. an initial batch or collaborative editing
103
+ * changes.
104
+ *
105
+ * @deprecated
106
+ * @type {'default'}
107
+ */
108
+ get type() {
109
+ /**
110
+ * The {@link module:engine/model/batch~Batch#type `Batch#type` } property has been deprecated and will be removed in the near
111
+ * future. Use `Batch#isLocal`, `Batch#isUndoable`, `Batch#isUndo` and `Batch#isTyping` instead.
112
+ *
113
+ * @error batch-type-deprecated
114
+ */
115
+ logWarning( 'batch-type-deprecated' );
116
+
117
+ return 'default';
51
118
  }
52
119
 
53
120
  /**