@ckeditor/ckeditor5-engine 29.2.0 → 32.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 (118) hide show
  1. package/LICENSE.md +2 -2
  2. package/package.json +25 -23
  3. package/src/controller/datacontroller.js +60 -12
  4. package/src/controller/editingcontroller.js +1 -1
  5. package/src/conversion/conversion.js +1 -1
  6. package/src/conversion/conversionhelpers.js +1 -1
  7. package/src/conversion/downcastdispatcher.js +1 -1
  8. package/src/conversion/downcasthelpers.js +1 -1
  9. package/src/conversion/mapper.js +1 -1
  10. package/src/conversion/modelconsumable.js +1 -1
  11. package/src/conversion/upcastdispatcher.js +1 -1
  12. package/src/conversion/upcasthelpers.js +1 -1
  13. package/src/conversion/viewconsumable.js +1 -1
  14. package/src/dataprocessor/basichtmlwriter.js +1 -1
  15. package/src/dataprocessor/dataprocessor.jsdoc +1 -1
  16. package/src/dataprocessor/htmldataprocessor.js +18 -43
  17. package/src/dataprocessor/htmlwriter.js +1 -1
  18. package/src/dataprocessor/xmldataprocessor.js +13 -17
  19. package/src/dev-utils/model.js +3 -3
  20. package/src/dev-utils/operationreplayer.js +1 -1
  21. package/src/dev-utils/utils.js +1 -1
  22. package/src/dev-utils/view.js +22 -4
  23. package/src/index.js +1 -1
  24. package/src/model/batch.js +77 -10
  25. package/src/model/differ.js +1 -1
  26. package/src/model/document.js +1 -1
  27. package/src/model/documentfragment.js +1 -1
  28. package/src/model/documentselection.js +1 -1
  29. package/src/model/element.js +1 -1
  30. package/src/model/history.js +1 -1
  31. package/src/model/item.jsdoc +1 -1
  32. package/src/model/liveposition.js +1 -1
  33. package/src/model/liverange.js +1 -1
  34. package/src/model/markercollection.js +6 -5
  35. package/src/model/model.js +17 -9
  36. package/src/model/node.js +1 -1
  37. package/src/model/nodelist.js +1 -1
  38. package/src/model/operation/attributeoperation.js +1 -1
  39. package/src/model/operation/detachoperation.js +1 -1
  40. package/src/model/operation/insertoperation.js +1 -1
  41. package/src/model/operation/markeroperation.js +1 -1
  42. package/src/model/operation/mergeoperation.js +1 -1
  43. package/src/model/operation/moveoperation.js +1 -1
  44. package/src/model/operation/nooperation.js +1 -1
  45. package/src/model/operation/operation.js +1 -1
  46. package/src/model/operation/operationfactory.js +1 -1
  47. package/src/model/operation/renameoperation.js +1 -1
  48. package/src/model/operation/rootattributeoperation.js +1 -1
  49. package/src/model/operation/splitoperation.js +1 -1
  50. package/src/model/operation/transform.js +1 -1
  51. package/src/model/operation/utils.js +1 -1
  52. package/src/model/position.js +1 -1
  53. package/src/model/range.js +2 -2
  54. package/src/model/rootelement.js +1 -1
  55. package/src/model/schema.js +1 -1
  56. package/src/model/selection.js +1 -1
  57. package/src/model/text.js +1 -1
  58. package/src/model/textproxy.js +1 -1
  59. package/src/model/treewalker.js +1 -1
  60. package/src/model/utils/autoparagraphing.js +1 -1
  61. package/src/model/utils/deletecontent.js +1 -1
  62. package/src/model/utils/getselectedcontent.js +1 -1
  63. package/src/model/utils/insertcontent.js +1 -1
  64. package/src/model/utils/modifyselection.js +1 -1
  65. package/src/model/utils/selection-post-fixer.js +44 -29
  66. package/src/model/writer.js +1 -1
  67. package/src/view/attributeelement.js +1 -1
  68. package/src/view/containerelement.js +1 -1
  69. package/src/view/document.js +13 -1
  70. package/src/view/documentfragment.js +1 -1
  71. package/src/view/documentselection.js +1 -1
  72. package/src/view/domconverter.js +268 -24
  73. package/src/view/downcastwriter.js +33 -2
  74. package/src/view/editableelement.js +1 -1
  75. package/src/view/element.js +29 -1
  76. package/src/view/elementdefinition.jsdoc +1 -1
  77. package/src/view/emptyelement.js +1 -1
  78. package/src/view/filler.js +1 -1
  79. package/src/view/item.jsdoc +1 -1
  80. package/src/view/matcher.js +22 -17
  81. package/src/view/node.js +1 -1
  82. package/src/view/observer/arrowkeysobserver.js +1 -1
  83. package/src/view/observer/bubblingemittermixin.js +1 -1
  84. package/src/view/observer/bubblingeventinfo.js +1 -1
  85. package/src/view/observer/clickobserver.js +1 -1
  86. package/src/view/observer/compositionobserver.js +1 -1
  87. package/src/view/observer/domeventdata.js +1 -1
  88. package/src/view/observer/domeventobserver.js +1 -1
  89. package/src/view/observer/fakeselectionobserver.js +1 -1
  90. package/src/view/observer/focusobserver.js +1 -1
  91. package/src/view/observer/inputobserver.js +1 -1
  92. package/src/view/observer/keyobserver.js +1 -1
  93. package/src/view/observer/mouseobserver.js +1 -1
  94. package/src/view/observer/mutationobserver.js +1 -1
  95. package/src/view/observer/observer.js +1 -1
  96. package/src/view/observer/selectionobserver.js +49 -2
  97. package/src/view/placeholder.js +1 -1
  98. package/src/view/position.js +1 -1
  99. package/src/view/range.js +1 -1
  100. package/src/view/rawelement.js +4 -3
  101. package/src/view/renderer.js +94 -40
  102. package/src/view/rooteditableelement.js +1 -1
  103. package/src/view/selection.js +1 -1
  104. package/src/view/styles/background.js +1 -1
  105. package/src/view/styles/border.js +1 -1
  106. package/src/view/styles/margin.js +1 -1
  107. package/src/view/styles/padding.js +1 -1
  108. package/src/view/styles/utils.js +6 -1
  109. package/src/view/stylesmap.js +1 -1
  110. package/src/view/text.js +1 -1
  111. package/src/view/textproxy.js +1 -1
  112. package/src/view/treewalker.js +1 -1
  113. package/src/view/uielement.js +6 -3
  114. package/src/view/upcastwriter.js +1 -1
  115. package/src/view/view.js +2 -2
  116. package/theme/placeholder.css +1 -1
  117. package/theme/renderer.css +9 -0
  118. package/CHANGELOG.md +0 -823
@@ -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
 
@@ -186,6 +186,8 @@ export default class DowncastWriter {
186
186
  * @param {Object} [options] Element's options.
187
187
  * @param {Number} [options.priority] Element's {@link module:engine/view/attributeelement~AttributeElement#priority priority}.
188
188
  * @param {Number|String} [options.id] Element's {@link module:engine/view/attributeelement~AttributeElement#id id}.
189
+ * @param {Array.<String>} [options.renderUnsafeAttributes] A list of attribute names that should be rendered in the editing
190
+ * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.
189
191
  * @returns {module:engine/view/attributeelement~AttributeElement} Created element.
190
192
  */
191
193
  createAttributeElement( name, attributes, options = {} ) {
@@ -199,6 +201,10 @@ export default class DowncastWriter {
199
201
  attributeElement._id = options.id;
200
202
  }
201
203
 
204
+ if ( options.renderUnsafeAttributes ) {
205
+ attributeElement._unsafeAttributesToRender.push( ...options.renderUnsafeAttributes );
206
+ }
207
+
202
208
  return attributeElement;
203
209
  }
204
210
 
@@ -222,6 +228,8 @@ export default class DowncastWriter {
222
228
  * @param {Boolean} [options.isAllowedInsideAttributeElement=false] Whether an element is
223
229
  * {@link module:engine/view/element~Element#isAllowedInsideAttributeElement allowed inside an AttributeElement} and can be wrapped
224
230
  * with {@link module:engine/view/attributeelement~AttributeElement} by {@link module:engine/view/downcastwriter~DowncastWriter}.
231
+ * @param {Array.<String>} [options.renderUnsafeAttributes] A list of attribute names that should be rendered in the editing
232
+ * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.
225
233
  * @returns {module:engine/view/containerelement~ContainerElement} Created element.
226
234
  */
227
235
  createContainerElement( name, attributes, options = {} ) {
@@ -231,6 +239,10 @@ export default class DowncastWriter {
231
239
  containerElement._isAllowedInsideAttributeElement = options.isAllowedInsideAttributeElement;
232
240
  }
233
241
 
242
+ if ( options.renderUnsafeAttributes ) {
243
+ containerElement._unsafeAttributesToRender.push( ...options.renderUnsafeAttributes );
244
+ }
245
+
234
246
  return containerElement;
235
247
  }
236
248
 
@@ -245,12 +257,19 @@ export default class DowncastWriter {
245
257
  *
246
258
  * @param {String} name Name of the element.
247
259
  * @param {Object} [attributes] Elements attributes.
260
+ * @param {Object} [options] Element's options.
261
+ * @param {Array.<String>} [options.renderUnsafeAttributes] A list of attribute names that should be rendered in the editing
262
+ * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.
248
263
  * @returns {module:engine/view/editableelement~EditableElement} Created element.
249
264
  */
250
- createEditableElement( name, attributes ) {
265
+ createEditableElement( name, attributes, options = {} ) {
251
266
  const editableElement = new EditableElement( this.document, name, attributes );
252
267
  editableElement._document = this.document;
253
268
 
269
+ if ( options.renderUnsafeAttributes ) {
270
+ editableElement._unsafeAttributesToRender.push( ...options.renderUnsafeAttributes );
271
+ }
272
+
254
273
  return editableElement;
255
274
  }
256
275
 
@@ -266,6 +285,8 @@ export default class DowncastWriter {
266
285
  * @param {Boolean} [options.isAllowedInsideAttributeElement=true] Whether an element is
267
286
  * {@link module:engine/view/element~Element#isAllowedInsideAttributeElement allowed inside an AttributeElement} and can be wrapped
268
287
  * with {@link module:engine/view/attributeelement~AttributeElement} by {@link module:engine/view/downcastwriter~DowncastWriter}.
288
+ * @param {Array.<String>} [options.renderUnsafeAttributes] A list of attribute names that should be rendered in the editing
289
+ * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.
269
290
  * @returns {module:engine/view/emptyelement~EmptyElement} Created element.
270
291
  */
271
292
  createEmptyElement( name, attributes, options = {} ) {
@@ -275,6 +296,10 @@ export default class DowncastWriter {
275
296
  emptyElement._isAllowedInsideAttributeElement = options.isAllowedInsideAttributeElement;
276
297
  }
277
298
 
299
+ if ( options.renderUnsafeAttributes ) {
300
+ emptyElement._unsafeAttributesToRender.push( ...options.renderUnsafeAttributes );
301
+ }
302
+
278
303
  return emptyElement;
279
304
  }
280
305
 
@@ -347,6 +372,8 @@ export default class DowncastWriter {
347
372
  * @param {Boolean} [options.isAllowedInsideAttributeElement=true] Whether an element is
348
373
  * {@link module:engine/view/element~Element#isAllowedInsideAttributeElement allowed inside an AttributeElement} and can be wrapped
349
374
  * with {@link module:engine/view/attributeelement~AttributeElement} by {@link module:engine/view/downcastwriter~DowncastWriter}.
375
+ * @param {Array.<String>} [options.renderUnsafeAttributes] A list of attribute names that should be rendered in the editing
376
+ * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.
350
377
  * @returns {module:engine/view/rawelement~RawElement} The created element.
351
378
  */
352
379
  createRawElement( name, attributes, renderFunction, options = {} ) {
@@ -358,6 +385,10 @@ export default class DowncastWriter {
358
385
  rawElement._isAllowedInsideAttributeElement = options.isAllowedInsideAttributeElement;
359
386
  }
360
387
 
388
+ if ( options.renderUnsafeAttributes ) {
389
+ rawElement._unsafeAttributesToRender.push( ...options.renderUnsafeAttributes );
390
+ }
391
+
361
392
  return rawElement;
362
393
  }
363
394
 
@@ -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
 
@@ -138,6 +138,21 @@ export default class Element extends Node {
138
138
  * @member {Boolean}
139
139
  */
140
140
  this._isAllowedInsideAttributeElement = false;
141
+
142
+ /**
143
+ * A list of attribute names that should be rendered in the editing pipeline even though filtering mechanisms
144
+ * implemented in the {@link module:engine/view/domconverter~DomConverter} (for instance,
145
+ * {@link module:engine/view/domconverter~DomConverter#shouldRenderAttribute}) would filter them out.
146
+ *
147
+ * These attributes can be specified as an option when the element is created by
148
+ * the {@link module:engine/view/downcastwriter~DowncastWriter}. To check whether an unsafe an attribute should
149
+ * be permitted, use the {@link #shouldRenderUnsafeAttribute} method.
150
+ *
151
+ * @private
152
+ * @readonly
153
+ * @member {Array.<String>}
154
+ */
155
+ this._unsafeAttributesToRender = [];
141
156
  }
142
157
 
143
158
  /**
@@ -572,6 +587,19 @@ export default class Element extends Node {
572
587
  ( attributes == '' ? '' : ` ${ attributes }` );
573
588
  }
574
589
 
590
+ /**
591
+ * Decides whether an unsafe attribute is whitelisted and should be rendered in the editing pipeline even though filtering mechanisms
592
+ * like {@link module:engine/view/domconverter~DomConverter#shouldRenderAttribute} say it should not.
593
+ *
594
+ * Unsafe attribute names can be specified when creating an element via {@link module:engine/view/downcastwriter~DowncastWriter}.
595
+ *
596
+ * @param {String} attributeName The name of the attribute to be checked.
597
+ * @returns {Boolean}
598
+ */
599
+ shouldRenderUnsafeAttribute( attributeName ) {
600
+ return this._unsafeAttributesToRender.includes( attributeName );
601
+ }
602
+
575
603
  /**
576
604
  * Clones provided element.
577
605
  *
@@ -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
 
@@ -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
 
@@ -235,7 +235,7 @@ function isElementMatching( element, pattern ) {
235
235
  function matchName( pattern, name ) {
236
236
  // If pattern is provided as RegExp - test against this regexp.
237
237
  if ( pattern instanceof RegExp ) {
238
- return pattern.test( name );
238
+ return !!name.match( pattern );
239
239
  }
240
240
 
241
241
  return pattern === name;
@@ -394,7 +394,7 @@ function normalizePatterns( patterns ) {
394
394
  function isKeyMatched( patternKey, itemKey ) {
395
395
  return patternKey === true ||
396
396
  patternKey === itemKey ||
397
- patternKey instanceof RegExp && patternKey.test( itemKey );
397
+ patternKey instanceof RegExp && itemKey.match( patternKey );
398
398
  }
399
399
 
400
400
  // @param {String|RegExp} patternValue A pattern representing a value we want to match.
@@ -408,7 +408,11 @@ function isValueMatched( patternValue, itemKey, valueGetter ) {
408
408
 
409
409
  const itemValue = valueGetter( itemKey );
410
410
 
411
- return patternValue === itemValue || patternValue instanceof RegExp && patternValue.test( itemValue );
411
+ // For now, the reducers are not returning the full tree of properties.
412
+ // Casting to string preserves the old behavior until the root cause is fixed.
413
+ // More can be found in https://github.com/ckeditor/ckeditor5/issues/10399.
414
+ return patternValue === itemValue ||
415
+ patternValue instanceof RegExp && !!String( itemValue ).match( patternValue );
412
416
  }
413
417
 
414
418
  // Checks if attributes of provided element can be matched against provided patterns.
@@ -527,7 +531,7 @@ function matchStyles( patterns, element ) {
527
531
  * name: 'figure',
528
532
  * attributes: [
529
533
  * 'title', // Match `title` attribute (can be empty).
530
- * /^data-*$/, // Match attributes starting with `data-` e.g. `data-foo` with any value (can be empty).
534
+ * /^data-*$/ // Match attributes starting with `data-` e.g. `data-foo` with any value (can be empty).
531
535
  * ]
532
536
  * };
533
537
  *
@@ -537,7 +541,8 @@ function matchStyles( patterns, element ) {
537
541
  * attributes: [
538
542
  * {
539
543
  * key: 'type', // Match `type` as an attribute key.
540
- * value: /^(text|number|date)$/ }, // Match `text`, `number` or `date` values.
544
+ * value: /^(text|number|date)$/ // Match `text`, `number` or `date` values.
545
+ * },
541
546
  * {
542
547
  * key: /^data-.*$/, // Match attributes starting with `data-` e.g. `data-foo`.
543
548
  * value: true // Match any value (can be empty).
@@ -568,7 +573,7 @@ function matchStyles( patterns, element ) {
568
573
  * // Match view element which has matching styles (Object).
569
574
  * const pattern = {
570
575
  * name: 'p',
571
- * attributes: {
576
+ * styles: {
572
577
  * color: /rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)/, // Match `color` in RGB format only.
573
578
  * 'font-weight': 600, // Match `font-weight` only if it's `600`.
574
579
  * 'text-decoration': true // Match any text decoration.
@@ -578,19 +583,20 @@ function matchStyles( patterns, element ) {
578
583
  * // Match view element which has matching styles (Array).
579
584
  * const pattern = {
580
585
  * name: 'p',
581
- * attributes: [
586
+ * styles: [
582
587
  * 'color', // Match `color` with any value.
583
- * /^border.*$/, // Match all border properties.
588
+ * /^border.*$/ // Match all border properties.
584
589
  * ]
585
590
  * };
586
591
  *
587
592
  * // Match view element which has matching styles (key-value pairs).
588
593
  * const pattern = {
589
594
  * name: 'p',
590
- * attributes: [
595
+ * styles: [
591
596
  * {
592
- * key: 'color', // Match `color` as an property key.
593
- * value: /rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)/, // Match RGB format only.
597
+ * key: 'color', // Match `color` as an property key.
598
+ * value: /rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)/ // Match RGB format only.
599
+ * },
594
600
  * {
595
601
  * key: /^border.*$/, // Match any border style.
596
602
  * value: true // Match any value.
@@ -643,6 +649,7 @@ function matchStyles( patterns, element ) {
643
649
  * {
644
650
  * key: 'image', // Match `image` class.
645
651
  * value: true
652
+ * },
646
653
  * {
647
654
  * key: /^image-side-(left|right)$/, // Match `image-side-left` or `image-side-right` class.
648
655
  * value: true
@@ -696,11 +703,9 @@ function matchStyles( patterns, element ) {
696
703
  * @typedef {String|RegExp|Object|Function} module:engine/view/matcher~MatcherPattern
697
704
  *
698
705
  * @property {String|RegExp} [name] View element name to match.
699
- * @property {String|RegExp|Array.<String|RegExp>} [classes] View element's class name(s) to match.
700
- * @property {Object} [styles] Object with key-value pairs representing styles to match.
701
- * Each object key represents style name. Value can be given as `String` or `RegExp`.
702
- * @property {Object} [attributes] Object with key-value pairs representing attributes to match.
703
- * Each object key represents attribute name. Value can be given as `String` or `RegExp`.
706
+ * @property {Boolean|String|RegExp|Object|Array.<String|RegExp|Object>} [classes] View element's classes to match.
707
+ * @property {Boolean|String|RegExp|Object|Array.<String|RegExp|Object>} [styles] View element's styles to match.
708
+ * @property {Boolean|String|RegExp|Object|Array.<String|RegExp|Object>} [attributes] View element's attributes to match.
704
709
  */
705
710
 
706
711
  /**
package/src/view/node.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
 
@@ -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,6 +1,6 @@
1
1
 
2
2
  /**
3
- * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
3
+ * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
4
4
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
5
5
  */
6
6
 
@@ -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
 
@@ -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.
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
 
@@ -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
 
@@ -20,6 +20,8 @@ import { debounce } from 'lodash-es';
20
20
  * {@link module:engine/view/document~Document#event:selectionChange} event only if a selection change was the only change in the document
21
21
  * and the DOM selection is different then the view selection.
22
22
  *
23
+ * This observer also manages the {@link module:engine/view/document~Document#isSelecting} property of the view document.
24
+ *
23
25
  * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.
24
26
  *
25
27
  * @see module:engine/view/observer/mutationobserver~MutationObserver
@@ -78,8 +80,26 @@ export default class SelectionObserver extends Observer {
78
80
  */
79
81
  this._fireSelectionChangeDoneDebounced = debounce( data => this.document.fire( 'selectionChangeDone', data ), 200 );
80
82
 
83
+ /**
84
+ * When called, starts clearing the {@link #_loopbackCounter} counter in time intervals. When the number of selection
85
+ * changes exceeds a certain limit within the interval of time, the observer will not fire `selectionChange` but warn about
86
+ * possible infinite selection loop.
87
+ *
88
+ * @private
89
+ * @member {Number} #_clearInfiniteLoopInterval
90
+ */
81
91
  this._clearInfiniteLoopInterval = setInterval( () => this._clearInfiniteLoop(), 1000 );
82
92
 
93
+ /**
94
+ * Unlocks the `isSelecting` state of the view document in case the selection observer did not record this fact
95
+ * correctly (for whatever reason). It is a safeguard (paranoid check), that returns document to the normal state
96
+ * after a certain period of time (debounced, postponed by each selectionchange event).
97
+ *
98
+ * @private
99
+ * @method #_documentIsSelectingInactivityTimeoutDebounced
100
+ */
101
+ this._documentIsSelectingInactivityTimeoutDebounced = debounce( () => ( this.document.isSelecting = false ), 5000 );
102
+
83
103
  /**
84
104
  * Private property to check if the code does not enter infinite loop.
85
105
  *
@@ -95,13 +115,39 @@ export default class SelectionObserver extends Observer {
95
115
  observe( domElement ) {
96
116
  const domDocument = domElement.ownerDocument;
97
117
 
98
- // Add listener once per each document.
118
+ const startDocumentIsSelecting = () => {
119
+ this.document.isSelecting = true;
120
+
121
+ // Let's activate the safety timeout each time the document enters the "is selecting" state.
122
+ this._documentIsSelectingInactivityTimeoutDebounced();
123
+ };
124
+
125
+ const endDocumentIsSelecting = () => {
126
+ this.document.isSelecting = false;
127
+
128
+ // The safety timeout can be canceled when the document leaves the "is selecting" state.
129
+ this._documentIsSelectingInactivityTimeoutDebounced.cancel();
130
+ };
131
+
132
+ // The document has the "is selecting" state while the user keeps making (extending) the selection
133
+ // (e.g. by holding the mouse button and moving the cursor). The state resets when they either released
134
+ // the mouse button or interrupted the process by pressing or releasing any key.
135
+ this.listenTo( domElement, 'selectstart', startDocumentIsSelecting, { priority: 'highest' } );
136
+ this.listenTo( domElement, 'keydown', endDocumentIsSelecting, { priority: 'highest' } );
137
+ this.listenTo( domElement, 'keyup', endDocumentIsSelecting, { priority: 'highest' } );
138
+
139
+ // Add document-wide listeners only once. This method could be called for multiple editing roots.
99
140
  if ( this._documents.has( domDocument ) ) {
100
141
  return;
101
142
  }
102
143
 
144
+ this.listenTo( domDocument, 'mouseup', endDocumentIsSelecting, { priority: 'highest' } );
103
145
  this.listenTo( domDocument, 'selectionchange', ( evt, domEvent ) => {
104
146
  this._handleSelectionChange( domEvent, domDocument );
147
+
148
+ // Defer the safety timeout when the selection changes (e.g. the user keeps extending the selection
149
+ // using their mouse).
150
+ this._documentIsSelectingInactivityTimeoutDebounced();
105
151
  } );
106
152
 
107
153
  this._documents.add( domDocument );
@@ -115,6 +161,7 @@ export default class SelectionObserver extends Observer {
115
161
 
116
162
  clearInterval( this._clearInfiniteLoopInterval );
117
163
  this._fireSelectionChangeDoneDebounced.cancel();
164
+ this._documentIsSelectingInactivityTimeoutDebounced.cancel();
118
165
  }
119
166
 
120
167
  /**
@@ -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/view/range.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
 
@@ -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
 
@@ -131,12 +131,13 @@ export default class RawElement extends Element {
131
131
  *
132
132
  * const myRawElement = downcastWriter.createRawElement( 'div' );
133
133
  *
134
- * myRawElement.render = function( domElement ) {
135
- * domElement.innerHTML = '<b>This is the raw content of myRawElement.</b>';
134
+ * myRawElement.render = function( domElement, domConverter ) {
135
+ * domConverter.setContentOf( domElement, '<b>This is the raw content of myRawElement.</b>' );
136
136
  * };
137
137
  *
138
138
  * @method #render
139
139
  * @param {HTMLElement} domElement The native DOM element representing the raw view element.
140
+ * @param {module:engine/view/domconverter~DomConverter} domConverter Instance of the DomConverter used to optimize the output.
140
141
  */
141
142
  }
142
143