@ckeditor/ckeditor5-engine 35.4.0 → 36.0.1

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 (123) hide show
  1. package/LICENSE.md +1 -1
  2. package/package.json +22 -22
  3. package/src/controller/datacontroller.js +5 -1
  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 +8 -1
  13. package/src/conversion/viewconsumable.js +1 -1
  14. package/src/dataprocessor/basichtmlwriter.js +1 -1
  15. package/src/dataprocessor/dataprocessor.js +1 -1
  16. package/src/dataprocessor/htmldataprocessor.js +1 -2
  17. package/src/dataprocessor/htmlwriter.js +1 -1
  18. package/src/dataprocessor/xmldataprocessor.js +1 -1
  19. package/src/dev-utils/model.js +1 -1
  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 +1 -1
  23. package/src/index.js +3 -2
  24. package/src/model/batch.js +9 -46
  25. package/src/model/differ.js +81 -174
  26. package/src/model/document.js +36 -92
  27. package/src/model/documentfragment.js +43 -96
  28. package/src/model/documentselection.js +151 -245
  29. package/src/model/element.js +47 -100
  30. package/src/model/history.js +15 -46
  31. package/src/model/item.js +1 -1
  32. package/src/model/liveposition.js +10 -36
  33. package/src/model/liverange.js +13 -36
  34. package/src/model/markercollection.js +40 -111
  35. package/src/model/model.js +212 -289
  36. package/src/model/node.js +35 -125
  37. package/src/model/nodelist.js +11 -39
  38. package/src/model/operation/attributeoperation.js +13 -44
  39. package/src/model/operation/detachoperation.js +3 -16
  40. package/src/model/operation/insertoperation.js +6 -34
  41. package/src/model/operation/markeroperation.js +9 -48
  42. package/src/model/operation/mergeoperation.js +8 -41
  43. package/src/model/operation/moveoperation.js +14 -37
  44. package/src/model/operation/nooperation.js +1 -7
  45. package/src/model/operation/operation.js +5 -63
  46. package/src/model/operation/operationfactory.js +3 -6
  47. package/src/model/operation/renameoperation.js +8 -28
  48. package/src/model/operation/rootattributeoperation.js +18 -47
  49. package/src/model/operation/splitoperation.js +9 -47
  50. package/src/model/operation/transform.js +109 -150
  51. package/src/model/operation/utils.js +36 -50
  52. package/src/model/position.js +117 -228
  53. package/src/model/range.js +145 -200
  54. package/src/model/rootelement.js +8 -47
  55. package/src/model/schema.js +236 -272
  56. package/src/model/selection.js +134 -192
  57. package/src/model/text.js +10 -37
  58. package/src/model/textproxy.js +15 -69
  59. package/src/model/treewalker.js +10 -101
  60. package/src/model/typecheckable.js +1 -1
  61. package/src/model/utils/autoparagraphing.js +11 -12
  62. package/src/model/utils/deletecontent.js +93 -62
  63. package/src/model/utils/findoptimalinsertionrange.js +24 -24
  64. package/src/model/utils/getselectedcontent.js +3 -6
  65. package/src/model/utils/insertcontent.js +36 -129
  66. package/src/model/utils/insertobject.js +19 -21
  67. package/src/model/utils/modifyselection.js +23 -33
  68. package/src/model/utils/selection-post-fixer.js +53 -59
  69. package/src/model/writer.js +208 -314
  70. package/src/view/attributeelement.js +1 -1
  71. package/src/view/containerelement.js +1 -1
  72. package/src/view/datatransfer.js +25 -28
  73. package/src/view/document.js +1 -17
  74. package/src/view/documentfragment.js +49 -1
  75. package/src/view/documentselection.js +1 -1
  76. package/src/view/domconverter.js +4 -3
  77. package/src/view/downcastwriter.js +1 -1
  78. package/src/view/editableelement.js +1 -1
  79. package/src/view/element.js +5 -5
  80. package/src/view/elementdefinition.js +1 -1
  81. package/src/view/emptyelement.js +1 -1
  82. package/src/view/filler.js +1 -1
  83. package/src/view/item.js +1 -1
  84. package/src/view/matcher.js +1 -1
  85. package/src/view/node.js +1 -1
  86. package/src/view/observer/arrowkeysobserver.js +1 -1
  87. package/src/view/observer/bubblingemittermixin.js +1 -1
  88. package/src/view/observer/bubblingeventinfo.js +1 -1
  89. package/src/view/observer/clickobserver.js +1 -1
  90. package/src/view/observer/compositionobserver.js +1 -1
  91. package/src/view/observer/domeventdata.js +1 -1
  92. package/src/view/observer/domeventobserver.js +1 -1
  93. package/src/view/observer/fakeselectionobserver.js +1 -1
  94. package/src/view/observer/focusobserver.js +22 -4
  95. package/src/view/observer/inputobserver.js +1 -1
  96. package/src/view/observer/keyobserver.js +1 -1
  97. package/src/view/observer/mouseobserver.js +1 -1
  98. package/src/view/observer/mutationobserver.js +1 -1
  99. package/src/view/observer/observer.js +1 -1
  100. package/src/view/observer/selectionobserver.js +13 -2
  101. package/src/view/observer/tabobserver.js +1 -1
  102. package/src/view/placeholder.js +1 -1
  103. package/src/view/position.js +1 -1
  104. package/src/view/range.js +1 -1
  105. package/src/view/rawelement.js +1 -1
  106. package/src/view/renderer.js +1 -14
  107. package/src/view/rooteditableelement.js +1 -1
  108. package/src/view/selection.js +1 -1
  109. package/src/view/styles/background.js +1 -1
  110. package/src/view/styles/border.js +1 -1
  111. package/src/view/styles/margin.js +1 -1
  112. package/src/view/styles/padding.js +1 -1
  113. package/src/view/styles/utils.js +1 -1
  114. package/src/view/stylesmap.js +1 -1
  115. package/src/view/text.js +1 -1
  116. package/src/view/textproxy.js +1 -1
  117. package/src/view/treewalker.js +1 -1
  118. package/src/view/typecheckable.js +1 -1
  119. package/src/view/uielement.js +1 -1
  120. package/src/view/upcastwriter.js +1 -1
  121. package/src/view/view.js +5 -5
  122. package/theme/placeholder.css +1 -1
  123. package/theme/renderer.css +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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,31 +1,34 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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
  /**
6
6
  * A facade over the native [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object.
7
7
  */
8
8
  export default class DataTransfer {
9
- constructor(nativeDataTransfer) {
10
- /**
11
- * The array of files created from the native `DataTransfer#files` or `DataTransfer#items`.
12
- *
13
- * @readonly
14
- * @member {Array.<File>} #files
15
- */
16
- this.files = getFiles(nativeDataTransfer);
17
- /**
18
- * The native DataTransfer object.
19
- *
20
- * @private
21
- * @member {DataTransfer} #_native
22
- */
9
+ /**
10
+ * @param nativeDataTransfer The native [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object.
11
+ * @param options.cacheFiles Whether `files` list should be initialized in the constructor.
12
+ */
13
+ constructor(nativeDataTransfer, options = {}) {
14
+ // We should store references to the File instances in case someone would like to process this files
15
+ // outside the event handler. Files are stored only for `drop` and `paste` events because they are not usable
16
+ // in other events and are generating a huge delay on Firefox while dragging.
17
+ // See https://github.com/ckeditor/ckeditor5/issues/13366.
18
+ this._files = options.cacheFiles ? getFiles(nativeDataTransfer) : null;
23
19
  this._native = nativeDataTransfer;
24
20
  }
21
+ /**
22
+ * The array of files created from the native `DataTransfer#files` or `DataTransfer#items`.
23
+ */
24
+ get files() {
25
+ if (!this._files) {
26
+ this._files = getFiles(this._native);
27
+ }
28
+ return this._files;
29
+ }
25
30
  /**
26
31
  * Returns an array of available native content types.
27
- *
28
- * @returns {Array.<String>}
29
32
  */
30
33
  get types() {
31
34
  return this._native.types;
@@ -33,10 +36,11 @@ export default class DataTransfer {
33
36
  /**
34
37
  * Gets the data from the data transfer by its MIME type.
35
38
  *
36
- * dataTransfer.getData( 'text/plain' );
39
+ * ```ts
40
+ * dataTransfer.getData( 'text/plain' );
41
+ * ```
37
42
  *
38
- * @param {String} type The MIME type. E.g. `text/html` or `text/plain`.
39
- * @returns {String}
43
+ * @param type The MIME type. E.g. `text/html` or `text/plain`.
40
44
  */
41
45
  getData(type) {
42
46
  return this._native.getData(type);
@@ -44,16 +48,13 @@ export default class DataTransfer {
44
48
  /**
45
49
  * Sets the data in the data transfer.
46
50
  *
47
- * @param {String} type The MIME type. E.g. `text/html` or `text/plain`.
48
- * @param {String} data
51
+ * @param type The MIME type. E.g. `text/html` or `text/plain`.
49
52
  */
50
53
  setData(type, data) {
51
54
  this._native.setData(type, data);
52
55
  }
53
56
  /**
54
57
  * The effect that is allowed for a drag operation.
55
- *
56
- * @param {String} value
57
58
  */
58
59
  set effectAllowed(value) {
59
60
  this._native.effectAllowed = value;
@@ -63,8 +64,6 @@ export default class DataTransfer {
63
64
  }
64
65
  /**
65
66
  * The actual drop effect.
66
- *
67
- * @param {String} value
68
67
  */
69
68
  set dropEffect(value) {
70
69
  this._native.dropEffect = value;
@@ -74,8 +73,6 @@ export default class DataTransfer {
74
73
  }
75
74
  /**
76
75
  * Whether the dragging operation was canceled.
77
- *
78
- * @returns {Boolean}
79
76
  */
80
77
  get isCanceled() {
81
78
  return this._native.dropEffect == 'none' || !!this._native.mozUserCancelled;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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
  /**
@@ -71,22 +71,6 @@ export default class Document extends BubblingEmitterMixin(ObservableMixin()) {
71
71
  */
72
72
  this.set('isFocused', false);
73
73
  /**
74
- * Set to `true` if the document is in the process of setting the focus.
75
- *
76
- * To be precise, there are two browser events that we care about: `focus` and `selectionchange`.
77
- *
78
- * Different browsers handle them differently. Chromium sends the `focus` event before the
79
- * `selectionchange` event, which leads to rendering with the old selection state.
80
- *
81
- * The flag is used to prevent rendering when setting the focus is in progress
82
- * and we are waiting for the new value.
83
- *
84
- * @internal
85
- * @observable
86
- * @member {Boolean} module:engine/view/document~Document#_isFocusChanging
87
- */
88
- this.set('_isFocusChanging', false);
89
- /** @
90
74
  * `true` while the user is making a selection in the document (e.g. holding the mouse button and moving the cursor).
91
75
  * When they stop selecting, the property goes back to `false`.
92
76
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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
  /**
@@ -44,6 +44,14 @@ export default class DocumentFragment extends EmitterMixin(TypeCheckable) {
44
44
  if (children) {
45
45
  this._insertChild(0, children);
46
46
  }
47
+ /**
48
+ * Map of custom properties.
49
+ * Custom properties can be added to document fragment instance.
50
+ *
51
+ * @protected
52
+ * @member {Map}
53
+ */
54
+ this._customProperties = new Map();
47
55
  }
48
56
  /**
49
57
  * Iterable interface.
@@ -91,6 +99,24 @@ export default class DocumentFragment extends EmitterMixin(TypeCheckable) {
91
99
  get parent() {
92
100
  return null;
93
101
  }
102
+ /**
103
+ * Returns the custom property value for the given key.
104
+ *
105
+ * @param {String|Symbol} key
106
+ * @returns {*}
107
+ */
108
+ getCustomProperty(key) {
109
+ return this._customProperties.get(key);
110
+ }
111
+ /**
112
+ * Returns an iterator which iterates over this document fragment's custom properties.
113
+ * Iterator provides `[ key, value ]` pairs for each stored property.
114
+ *
115
+ * @returns {Iterable.<*>}
116
+ */
117
+ *getCustomProperties() {
118
+ yield* this._customProperties.entries();
119
+ }
94
120
  /**
95
121
  * {@link module:engine/view/documentfragment~DocumentFragment#_insertChild Insert} a child node or a list of child nodes at the end
96
122
  * and sets the parent of these nodes to this fragment.
@@ -177,6 +203,28 @@ export default class DocumentFragment extends EmitterMixin(TypeCheckable) {
177
203
  _fireChange(type, node) {
178
204
  this.fire('change:' + type, node);
179
205
  }
206
+ /**
207
+ * Sets a custom property. They can be used to add special data to elements.
208
+ *
209
+ * @see module:engine/view/downcastwriter~DowncastWriter#setCustomProperty
210
+ * @protected
211
+ * @param {String|Symbol} key
212
+ * @param {*} value
213
+ */
214
+ _setCustomProperty(key, value) {
215
+ this._customProperties.set(key, value);
216
+ }
217
+ /**
218
+ * Removes the custom property stored under the given key.
219
+ *
220
+ * @see module:engine/view/downcastwriter~DowncastWriter#removeCustomProperty
221
+ * @protected
222
+ * @param {String|Symbol} key
223
+ * @returns {Boolean} Returns true if property was removed.
224
+ */
225
+ _removeCustomProperty(key) {
226
+ return this._customProperties.delete(key);
227
+ }
180
228
  }
181
229
  /**
182
230
  * Checks whether this object is of the given type.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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
  /**
@@ -16,7 +16,7 @@ import ViewDocumentFragment from './documentfragment';
16
16
  import ViewTreeWalker from './treewalker';
17
17
  import { default as Matcher } from './matcher';
18
18
  import { BR_FILLER, INLINE_FILLER_LENGTH, NBSP_FILLER, MARKED_NBSP_FILLER, getDataWithoutFiller, isInlineFiller, startsWithFiller } from './filler';
19
- import { global, logWarning, indexOf, getAncestors, isText, isComment } from '@ckeditor/ckeditor5-utils';
19
+ import { global, logWarning, indexOf, getAncestors, isText, isComment, first } from '@ckeditor/ckeditor5-utils';
20
20
  const BR_FILLER_REF = BR_FILLER(global.document); // eslint-disable-line new-cap
21
21
  const NBSP_FILLER_REF = NBSP_FILLER(global.document); // eslint-disable-line new-cap
22
22
  const MARKED_NBSP_FILLER_REF = MARKED_NBSP_FILLER(global.document); // eslint-disable-line new-cap
@@ -433,7 +433,8 @@ export default class DomConverter {
433
433
  yield this._getBlockFiller();
434
434
  }
435
435
  const transparentRendering = childView.is('element') &&
436
- childView.getCustomProperty('dataPipeline:transparentRendering');
436
+ !!childView.getCustomProperty('dataPipeline:transparentRendering') &&
437
+ !first(childView.getAttributes());
437
438
  if (transparentRendering && this.renderingMode == 'data') {
438
439
  yield* this.viewChildrenToDom(childView, options);
439
440
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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
  /**
@@ -579,16 +579,16 @@ export default class Element extends Node {
579
579
  * @fires module:engine/view/node~Node#change
580
580
  */
581
581
  _setAttribute(key, value) {
582
- value = String(value);
582
+ const stringValue = String(value);
583
583
  this._fireChange('attributes', this);
584
584
  if (key == 'class') {
585
- parseClasses(this._classes, value);
585
+ parseClasses(this._classes, stringValue);
586
586
  }
587
587
  else if (key == 'style') {
588
- this._styles.setTo(value);
588
+ this._styles.setTo(stringValue);
589
589
  }
590
590
  else {
591
- this._attrs.set(key, value);
591
+ this._attrs.set(key, stringValue);
592
592
  }
593
593
  }
594
594
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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
  export {};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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
  import { keyCodes, isText } from '@ckeditor/ckeditor5-utils';
package/src/view/item.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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
  export {};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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
  import { isPlainObject } from 'lodash-es';
package/src/view/node.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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,12 +20,20 @@ import DomEventObserver from './domeventobserver';
20
20
  export default class FocusObserver extends DomEventObserver {
21
21
  constructor(view) {
22
22
  super(view);
23
+ this._isFocusChanging = false;
23
24
  this.domEventType = ['focus', 'blur'];
24
25
  this.useCapture = true;
25
26
  const document = this.document;
26
27
  document.on('focus', () => {
27
- document.isFocused = true;
28
- document._isFocusChanging = true;
28
+ /**
29
+ * Set to `true` if the document is in the process of setting the focus.
30
+ *
31
+ * The flag is used to indicate that setting the focus is in progress.
32
+ *
33
+ * @internal
34
+ * @type {Boolean} module:engine/view/observer/focusobserver#_isFocusChanging
35
+ */
36
+ this._isFocusChanging = true;
29
37
  // Unfortunately native `selectionchange` event is fired asynchronously.
30
38
  // We need to wait until `SelectionObserver` handle the event and then render. Otherwise rendering will
31
39
  // overwrite new DOM selection with selection from the view.
@@ -35,7 +43,7 @@ export default class FocusObserver extends DomEventObserver {
35
43
  // Using `view.change()` instead of `view.forceRender()` to prevent double rendering
36
44
  // in a situation where `selectionchange` already caused selection change.
37
45
  this._renderTimeoutId = setTimeout(() => {
38
- document._isFocusChanging = false;
46
+ this.flush();
39
47
  view.change(() => { });
40
48
  }, 50);
41
49
  });
@@ -43,6 +51,7 @@ export default class FocusObserver extends DomEventObserver {
43
51
  const selectedEditable = document.selection.editableElement;
44
52
  if (selectedEditable === null || selectedEditable === data.target) {
45
53
  document.isFocused = false;
54
+ this._isFocusChanging = false;
46
55
  // Re-render the document to update view elements
47
56
  // (changing document.isFocused already marked view as changed since last rendering).
48
57
  view.change(() => { });
@@ -55,6 +64,15 @@ export default class FocusObserver extends DomEventObserver {
55
64
  * @member {Number} #_renderTimeoutId
56
65
  */
57
66
  }
67
+ /**
68
+ * Finishes setting the document focus state.
69
+ */
70
+ flush() {
71
+ if (this._isFocusChanging) {
72
+ this._isFocusChanging = false;
73
+ this.document.isFocused = true;
74
+ }
75
+ }
58
76
  onDomEvent(domEvent) {
59
77
  this.fire(domEvent.type, domEvent);
60
78
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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
  /**
@@ -10,6 +10,7 @@ import Observer from './observer';
10
10
  import MutationObserver from './mutationobserver';
11
11
  import { env } from '@ckeditor/ckeditor5-utils';
12
12
  import { debounce } from 'lodash-es';
13
+ import FocusObserver from './focusobserver';
13
14
  /**
14
15
  * Selection observer class observes selection changes in the document. If a selection changes on the document this
15
16
  * observer checks if the DOM selection is different from the {@link module:engine/view/document~Document#selection view selection}.
@@ -35,6 +36,15 @@ export default class SelectionObserver extends Observer {
35
36
  * module:engine/view/observer/selectionobserver~SelectionObserver#mutationObserver
36
37
  */
37
38
  this.mutationObserver = view.getObserver(MutationObserver);
39
+ /**
40
+ * Instance of the focus observer. Selection observer calls
41
+ * {@link module:engine/view/observer/focusobserver~FocusObserver#flush} to mark the latest focus change as complete.
42
+ *
43
+ * @readonly
44
+ * @member {module:engine/view/observer/focusobserver~FocusObserver}
45
+ * module:engine/view/observer/focusobserver~FocusObserver#focusObserver
46
+ */
47
+ this.focusObserver = view.getObserver(FocusObserver);
38
48
  /**
39
49
  * Reference to the view {@link module:engine/view/documentselection~DocumentSelection} object used to compare
40
50
  * new selection with it.
@@ -221,6 +231,8 @@ export default class SelectionObserver extends Observer {
221
231
  // @if CK_DEBUG // this._reportInfiniteLoop();
222
232
  return;
223
233
  }
234
+ // Mark the latest focus change as complete (we got new selection after the focus so the selection is in the focused element).
235
+ this.focusObserver.flush();
224
236
  if (this.selection.isSimilar(newViewSelection)) {
225
237
  // If selection was equal and we are at this point of algorithm, it means that it was incorrect.
226
238
  // Just re-render it, no need to fire any events, etc.
@@ -238,7 +250,6 @@ export default class SelectionObserver extends Observer {
238
250
  // @if CK_DEBUG_TYPING // newViewSelection.getFirstRange()
239
251
  // @if CK_DEBUG_TYPING // );
240
252
  // @if CK_DEBUG_TYPING // }
241
- this.document._isFocusChanging = false;
242
253
  // Prepare data for new selection and fire appropriate events.
243
254
  this.document.fire('selectionChange', data);
244
255
  // Call `#_fireSelectionChangeDoneDebounced` every time when `selectionChange` event is fired.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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
  import Observer from './observer';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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-2022, CKSource Holding sp. z o.o. All rights reserved.
2
+ * @license Copyright (c) 2003-2023, 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
  /**
@@ -82,14 +82,6 @@ export default class Renderer extends ObservableMixin() {
82
82
  * @observable
83
83
  */
84
84
  this.set('isFocused', false);
85
- /**
86
- * Indicates if the view document is changing the focus (`true`) and selection rendering should be prevented.
87
- *
88
- * @internal
89
- * @observable
90
- * @member {Boolean}
91
- */
92
- this.set('_isFocusChanging', false);
93
85
  /**
94
86
  * Indicates whether the user is making a selection in the document (e.g. holding the mouse button and moving the cursor).
95
87
  * When they stop selecting, the property goes back to `false`.
@@ -758,11 +750,6 @@ export default class Renderer extends ObservableMixin() {
758
750
  if (env.isBlink && !env.isAndroid && this.isSelecting && !this.markedChildren.size) {
759
751
  return;
760
752
  }
761
- // The focus is still in progress and we are waiting for new values from `selectionchange` event.
762
- // In that case, we need to prevent update selection since it would be updated using old values.
763
- if (this._isFocusChanging) {
764
- return;
765
- }
766
753
  // If there is no selection - remove DOM and fake selections.
767
754
  if (this.selection.rangeCount === 0) {
768
755
  this._removeDomSelection();