@ckeditor/ckeditor5-engine 44.3.0 → 45.0.0-alpha.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 (94) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/index.js +305 -129
  3. package/dist/index.js.map +1 -1
  4. package/package.json +3 -3
  5. package/src/controller/datacontroller.js +40 -0
  6. package/src/controller/editingcontroller.js +16 -0
  7. package/src/conversion/conversion.js +6 -4
  8. package/src/conversion/conversionhelpers.js +1 -0
  9. package/src/conversion/downcastdispatcher.js +10 -0
  10. package/src/conversion/downcasthelpers.js +1 -1
  11. package/src/conversion/mapper.js +92 -95
  12. package/src/conversion/modelconsumable.js +13 -15
  13. package/src/conversion/upcastdispatcher.js +28 -24
  14. package/src/conversion/upcasthelpers.d.ts +1 -1
  15. package/src/conversion/upcasthelpers.js +2 -2
  16. package/src/conversion/viewconsumable.js +19 -20
  17. package/src/dataprocessor/htmldataprocessor.js +13 -1
  18. package/src/dataprocessor/xmldataprocessor.js +21 -1
  19. package/src/dev-utils/model.js +1 -1
  20. package/src/dev-utils/operationreplayer.js +3 -0
  21. package/src/dev-utils/utils.js +35 -1
  22. package/src/dev-utils/view.js +13 -0
  23. package/src/model/batch.js +20 -0
  24. package/src/model/differ.js +92 -88
  25. package/src/model/document.d.ts +1 -3
  26. package/src/model/document.js +38 -1
  27. package/src/model/documentfragment.js +10 -10
  28. package/src/model/documentselection.js +44 -32
  29. package/src/model/element.js +8 -4
  30. package/src/model/history.js +31 -33
  31. package/src/model/markercollection.js +25 -7
  32. package/src/model/model.js +21 -0
  33. package/src/model/node.js +22 -18
  34. package/src/model/nodelist.js +12 -12
  35. package/src/model/operation/attributeoperation.js +25 -1
  36. package/src/model/operation/detachoperation.js +8 -0
  37. package/src/model/operation/insertoperation.js +18 -0
  38. package/src/model/operation/markeroperation.js +29 -0
  39. package/src/model/operation/mergeoperation.js +16 -0
  40. package/src/model/operation/moveoperation.js +12 -0
  41. package/src/model/operation/operation.js +19 -0
  42. package/src/model/operation/renameoperation.js +12 -0
  43. package/src/model/operation/rootattributeoperation.js +20 -0
  44. package/src/model/operation/rootoperation.js +16 -0
  45. package/src/model/operation/splitoperation.js +19 -0
  46. package/src/model/operation/transform.js +5 -0
  47. package/src/model/position.js +40 -0
  48. package/src/model/range.js +8 -0
  49. package/src/model/rootelement.js +18 -10
  50. package/src/model/schema.js +25 -23
  51. package/src/model/selection.js +10 -10
  52. package/src/model/text.js +6 -0
  53. package/src/model/textproxy.js +12 -0
  54. package/src/model/treewalker.js +49 -0
  55. package/src/model/utils/insertcontent.js +60 -25
  56. package/src/model/writer.js +8 -0
  57. package/src/view/attributeelement.js +23 -23
  58. package/src/view/datatransfer.js +8 -0
  59. package/src/view/document.js +21 -4
  60. package/src/view/documentfragment.js +13 -9
  61. package/src/view/documentselection.js +4 -0
  62. package/src/view/domconverter.d.ts +6 -1
  63. package/src/view/domconverter.js +109 -48
  64. package/src/view/downcastwriter.js +14 -10
  65. package/src/view/element.js +29 -17
  66. package/src/view/matcher.js +1 -1
  67. package/src/view/node.js +9 -1
  68. package/src/view/observer/bubblingeventinfo.js +12 -0
  69. package/src/view/observer/clickobserver.js +4 -7
  70. package/src/view/observer/compositionobserver.js +14 -12
  71. package/src/view/observer/domeventdata.js +17 -1
  72. package/src/view/observer/domeventobserver.js +10 -13
  73. package/src/view/observer/fakeselectionobserver.d.ts +1 -1
  74. package/src/view/observer/fakeselectionobserver.js +5 -1
  75. package/src/view/observer/focusobserver.js +65 -14
  76. package/src/view/observer/inputobserver.js +33 -26
  77. package/src/view/observer/keyobserver.js +4 -7
  78. package/src/view/observer/mouseobserver.js +4 -7
  79. package/src/view/observer/mutationobserver.js +23 -6
  80. package/src/view/observer/observer.js +12 -4
  81. package/src/view/observer/selectionobserver.d.ts +6 -1
  82. package/src/view/observer/selectionobserver.js +94 -17
  83. package/src/view/observer/touchobserver.js +4 -7
  84. package/src/view/position.js +8 -0
  85. package/src/view/range.js +8 -0
  86. package/src/view/renderer.js +142 -70
  87. package/src/view/selection.js +16 -0
  88. package/src/view/stylesmap.js +26 -11
  89. package/src/view/text.js +6 -0
  90. package/src/view/textproxy.js +12 -0
  91. package/src/view/tokenlist.js +4 -6
  92. package/src/view/treewalker.js +42 -0
  93. package/src/view/upcastwriter.js +5 -1
  94. package/src/view/view.js +51 -33
package/src/view/node.js CHANGED
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import TypeCheckable from './typecheckable.js';
9
9
  import { CKEditorError, EmitterMixin, compareArrays } from '@ckeditor/ckeditor5-utils';
10
- import { clone } from 'lodash-es';
10
+ import { clone } from 'es-toolkit/compat';
11
11
  /**
12
12
  * Abstract view node class.
13
13
  *
@@ -16,6 +16,14 @@ import { clone } from 'lodash-es';
16
16
  * to create new instances of view nodes.
17
17
  */
18
18
  export default class Node extends /* #__PURE__ */ EmitterMixin(TypeCheckable) {
19
+ /**
20
+ * The document instance to which this node belongs.
21
+ */
22
+ document;
23
+ /**
24
+ * Parent element. Null by default. Set by {@link module:engine/view/element~Element#_insertChild}.
25
+ */
26
+ parent;
19
27
  /**
20
28
  * Creates a tree view node.
21
29
  *
@@ -11,6 +11,18 @@ import { EventInfo } from '@ckeditor/ckeditor5-utils';
11
11
  * manipulate it.
12
12
  */
13
13
  export default class BubblingEventInfo extends EventInfo {
14
+ /**
15
+ * The view range that the bubbling should start from.
16
+ */
17
+ startRange;
18
+ /**
19
+ * The current event phase.
20
+ */
21
+ _eventPhase;
22
+ /**
23
+ * The current bubbling target.
24
+ */
25
+ _currentTarget;
14
26
  /**
15
27
  * @param source The emitter.
16
28
  * @param name The event name.
@@ -13,13 +13,10 @@ import DomEventObserver from './domeventobserver.js';
13
13
  * {@link module:engine/view/view~View view controller} by a {@link module:engine/view/view~View#addObserver} method.
14
14
  */
15
15
  export default class ClickObserver extends DomEventObserver {
16
- constructor() {
17
- super(...arguments);
18
- /**
19
- * @inheritDoc
20
- */
21
- this.domEventType = 'click';
22
- }
16
+ /**
17
+ * @inheritDoc
18
+ */
19
+ domEventType = 'click';
23
20
  /**
24
21
  * @inheritDoc
25
22
  */
@@ -6,7 +6,7 @@
6
6
  * @module engine/view/observer/compositionobserver
7
7
  */
8
8
  import DomEventObserver from './domeventobserver.js';
9
- // @if CK_DEBUG_TYPING // const { _debouncedLine } = require( '../../dev-utils/utils.js' );
9
+ // @if CK_DEBUG_TYPING // const { _debouncedLine, _buildLogMessage } = require( '../../dev-utils/utils.js' );
10
10
  /**
11
11
  * {@link module:engine/view/document~Document#event:compositionstart Compositionstart},
12
12
  * {@link module:engine/view/document~Document#event:compositionupdate compositionupdate} and
@@ -15,31 +15,31 @@ import DomEventObserver from './domeventobserver.js';
15
15
  * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.
16
16
  */
17
17
  export default class CompositionObserver extends DomEventObserver {
18
+ /**
19
+ * @inheritDoc
20
+ */
21
+ domEventType = ['compositionstart', 'compositionupdate', 'compositionend'];
18
22
  /**
19
23
  * @inheritDoc
20
24
  */
21
25
  constructor(view) {
22
26
  super(view);
23
- /**
24
- * @inheritDoc
25
- */
26
- this.domEventType = ['compositionstart', 'compositionupdate', 'compositionend'];
27
27
  const document = this.document;
28
28
  document.on('compositionstart', () => {
29
29
  // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
30
- // @if CK_DEBUG_TYPING // console.log( '%c[CompositionObserver] ' +
31
- // @if CK_DEBUG_TYPING // '┌───────────────────────────── isComposing = true ─────────────────────────────┐',
30
+ // @if CK_DEBUG_TYPING // console.log( ..._buildLogMessage( this, 'CompositionObserver',
31
+ // @if CK_DEBUG_TYPING // '%c┌───────────────────────────── isComposing = true ─────────────────────────────┐',
32
32
  // @if CK_DEBUG_TYPING // 'font-weight: bold; color: green'
33
- // @if CK_DEBUG_TYPING // );
33
+ // @if CK_DEBUG_TYPING // ) );
34
34
  // @if CK_DEBUG_TYPING // }
35
35
  document.isComposing = true;
36
36
  }, { priority: 'low' });
37
37
  document.on('compositionend', () => {
38
38
  // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
39
- // @if CK_DEBUG_TYPING // console.log( '%c[CompositionObserver] ' +
40
- // @if CK_DEBUG_TYPING // '└───────────────────────────── isComposing = false ─────────────────────────────┘',
39
+ // @if CK_DEBUG_TYPING // console.log( ..._buildLogMessage( this, 'CompositionObserver',
40
+ // @if CK_DEBUG_TYPING // '%c└───────────────────────────── isComposing = false ─────────────────────────────┘',
41
41
  // @if CK_DEBUG_TYPING // 'font-weight: bold; color: green'
42
- // @if CK_DEBUG_TYPING // );
42
+ // @if CK_DEBUG_TYPING // ) );
43
43
  // @if CK_DEBUG_TYPING // }
44
44
  document.isComposing = false;
45
45
  }, { priority: 'low' });
@@ -50,7 +50,9 @@ export default class CompositionObserver extends DomEventObserver {
50
50
  onDomEvent(domEvent) {
51
51
  // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
52
52
  // @if CK_DEBUG_TYPING // _debouncedLine();
53
- // @if CK_DEBUG_TYPING // console.group( `%c[CompositionObserver]%c ${ domEvent.type }`, 'color: green', '' );
53
+ // @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'CompositionObserver',
54
+ // @if CK_DEBUG_TYPING // `${ domEvent.type }`
55
+ // @if CK_DEBUG_TYPING // ) );
54
56
  // @if CK_DEBUG_TYPING // }
55
57
  this.fire(domEvent.type, domEvent, {
56
58
  data: domEvent.data
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * @module engine/view/observer/domeventdata
7
7
  */
8
- import { extend } from 'lodash-es';
8
+ import { extend } from 'es-toolkit/compat';
9
9
  /**
10
10
  * Information about a DOM event in context of the {@link module:engine/view/document~Document}.
11
11
  * It wraps the native event, which usually should not be used as the wrapper contains
@@ -14,6 +14,22 @@ import { extend } from 'lodash-es';
14
14
  * @typeParam TEvent The type of DOM Event that this class represents.
15
15
  */
16
16
  export default class DomEventData {
17
+ /**
18
+ * Instance of the view controller.
19
+ */
20
+ view;
21
+ /**
22
+ * The instance of the document.
23
+ */
24
+ document;
25
+ /**
26
+ * The DOM event.
27
+ */
28
+ domEvent;
29
+ /**
30
+ * The DOM target.
31
+ */
32
+ domTarget;
17
33
  /**
18
34
  * @param view The instance of the view controller.
19
35
  * @param domEvent The DOM event.
@@ -35,19 +35,16 @@ import DomEventData from './domeventdata.js';
35
35
  * @typeParam AdditionalData Additional data passed along with the event.
36
36
  */
37
37
  export default class DomEventObserver extends Observer {
38
- constructor() {
39
- super(...arguments);
40
- /**
41
- * If set to `true` DOM events will be listened on the capturing phase.
42
- * Default value is `false`.
43
- */
44
- this.useCapture = false;
45
- /**
46
- * If set to `true`, indicates that the function specified by listener will never call `preventDefault()`.
47
- * Default value is `false`.
48
- */
49
- this.usePassive = false;
50
- }
38
+ /**
39
+ * If set to `true` DOM events will be listened on the capturing phase.
40
+ * Default value is `false`.
41
+ */
42
+ useCapture = false;
43
+ /**
44
+ * If set to `true`, indicates that the function specified by listener will never call `preventDefault()`.
45
+ * Default value is `false`.
46
+ */
47
+ usePassive = false;
51
48
  /**
52
49
  * @inheritDoc
53
50
  */
@@ -16,7 +16,7 @@ import type View from '../view.js';
16
16
  */
17
17
  export default class FakeSelectionObserver extends Observer {
18
18
  /**
19
- * Fires debounced event `selectionChangeDone`. It uses `lodash#debounce` method to delay function call.
19
+ * Fires debounced event `selectionChangeDone`. It uses `es-toolkit#debounce` method to delay function call.
20
20
  */
21
21
  private readonly _fireSelectionChangeDoneDebounced;
22
22
  /**
@@ -8,7 +8,7 @@
8
8
  import Observer from './observer.js';
9
9
  import ViewSelection from '../selection.js';
10
10
  import { keyCodes } from '@ckeditor/ckeditor5-utils';
11
- import { debounce } from 'lodash-es';
11
+ import { debounce } from 'es-toolkit/compat';
12
12
  /**
13
13
  * Fake selection observer class. If view selection is fake it is placed in dummy DOM container. This observer listens
14
14
  * on {@link module:engine/view/document~Document#event:keydown keydown} events and handles moving fake view selection to the correct place
@@ -17,6 +17,10 @@ import { debounce } from 'lodash-es';
17
17
  * {@link module:engine/view/observer/selectionobserver~SelectionObserver SelectionObserver}.
18
18
  */
19
19
  export default class FakeSelectionObserver extends Observer {
20
+ /**
21
+ * Fires debounced event `selectionChangeDone`. It uses `es-toolkit#debounce` method to delay function call.
22
+ */
23
+ _fireSelectionChangeDoneDebounced;
20
24
  /**
21
25
  * Creates new FakeSelectionObserver instance.
22
26
  */
@@ -7,6 +7,7 @@
7
7
  */
8
8
  /* globals setTimeout, clearTimeout */
9
9
  import DomEventObserver from './domeventobserver.js';
10
+ // @if CK_DEBUG_TYPING // const { _debouncedLine, _buildLogMessage } = require( '../../dev-utils/utils.js' );
10
11
  /**
11
12
  * {@link module:engine/view/document~Document#event:focus Focus}
12
13
  * and {@link module:engine/view/document~Document#event:blur blur} events observer.
@@ -16,25 +17,25 @@ import DomEventObserver from './domeventobserver.js';
16
17
  * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.
17
18
  */
18
19
  export default class FocusObserver extends DomEventObserver {
20
+ /**
21
+ * Identifier of the timeout currently used by focus listener to delay rendering execution.
22
+ */
23
+ _renderTimeoutId = null;
24
+ /**
25
+ * Set to `true` if the document is in the process of setting the focus.
26
+ *
27
+ * The flag is used to indicate that setting the focus is in progress.
28
+ */
29
+ _isFocusChanging = false;
30
+ /**
31
+ * @inheritDoc
32
+ */
33
+ domEventType = ['focus', 'blur'];
19
34
  /**
20
35
  * @inheritDoc
21
36
  */
22
37
  constructor(view) {
23
38
  super(view);
24
- /**
25
- * Identifier of the timeout currently used by focus listener to delay rendering execution.
26
- */
27
- this._renderTimeoutId = null;
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
- this._isFocusChanging = false;
34
- /**
35
- * @inheritDoc
36
- */
37
- this.domEventType = ['focus', 'blur'];
38
39
  this.useCapture = true;
39
40
  const document = this.document;
40
41
  document.on('focus', () => this._handleFocus());
@@ -54,15 +55,43 @@ export default class FocusObserver extends DomEventObserver {
54
55
  */
55
56
  flush() {
56
57
  if (this._isFocusChanging) {
58
+ // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
59
+ // @if CK_DEBUG_TYPING // _debouncedLine();
60
+ // @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'FocusObserver',
61
+ // @if CK_DEBUG_TYPING // 'flush focus'
62
+ // @if CK_DEBUG_TYPING // ) );
63
+ // @if CK_DEBUG_TYPING // }
57
64
  this._isFocusChanging = false;
58
65
  this.document.isFocused = true;
66
+ // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
67
+ // @if CK_DEBUG_TYPING // console.groupEnd();
68
+ // @if CK_DEBUG_TYPING // }
59
69
  }
60
70
  }
61
71
  /**
62
72
  * @inheritDoc
63
73
  */
64
74
  onDomEvent(domEvent) {
75
+ // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
76
+ // @if CK_DEBUG_TYPING // _debouncedLine();
77
+ // @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'FocusObserver',
78
+ // @if CK_DEBUG_TYPING // `${ domEvent.type } event`
79
+ // @if CK_DEBUG_TYPING // ) );
80
+ // @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'FocusObserver',
81
+ // @if CK_DEBUG_TYPING // 'DOM target:',
82
+ // @if CK_DEBUG_TYPING // { target: domEvent.target, relatedTarget: domEvent.relatedTarget }
83
+ // @if CK_DEBUG_TYPING // ) );
84
+ // @if CK_DEBUG_TYPING // const domSelection = window.getSelection();
85
+ // @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'FocusObserver',
86
+ // @if CK_DEBUG_TYPING // 'DOM Selection:',
87
+ // @if CK_DEBUG_TYPING // { node: domSelection!.anchorNode, offset: domSelection!.anchorOffset },
88
+ // @if CK_DEBUG_TYPING // { node: domSelection!.focusNode, offset: domSelection!.focusOffset }
89
+ // @if CK_DEBUG_TYPING // ) );
90
+ // @if CK_DEBUG_TYPING // }
65
91
  this.fire(domEvent.type, domEvent);
92
+ // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
93
+ // @if CK_DEBUG_TYPING // console.groupEnd();
94
+ // @if CK_DEBUG_TYPING // }
66
95
  }
67
96
  /**
68
97
  * @inheritDoc
@@ -87,8 +116,16 @@ export default class FocusObserver extends DomEventObserver {
87
116
  // in a situation where `selectionchange` already caused selection change.
88
117
  this._renderTimeoutId = setTimeout(() => {
89
118
  this._renderTimeoutId = null;
119
+ // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
120
+ // @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'FocusObserver',
121
+ // @if CK_DEBUG_TYPING // 'flush on timeout'
122
+ // @if CK_DEBUG_TYPING // ) );
123
+ // @if CK_DEBUG_TYPING // }
90
124
  this.flush();
91
125
  this.view.change(() => { });
126
+ // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
127
+ // @if CK_DEBUG_TYPING // console.groupEnd();
128
+ // @if CK_DEBUG_TYPING // }
92
129
  }, 50);
93
130
  }
94
131
  /**
@@ -96,12 +133,26 @@ export default class FocusObserver extends DomEventObserver {
96
133
  */
97
134
  _handleBlur(data) {
98
135
  const selectedEditable = this.document.selection.editableElement;
136
+ // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
137
+ // @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'FocusObserver',
138
+ // @if CK_DEBUG_TYPING // 'selectedEditable:',
139
+ // @if CK_DEBUG_TYPING // { selectedEditable }
140
+ // @if CK_DEBUG_TYPING // ) );
141
+ // @if CK_DEBUG_TYPING // }
99
142
  if (selectedEditable === null || selectedEditable === data.target) {
143
+ // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
144
+ // @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'FocusObserver',
145
+ // @if CK_DEBUG_TYPING // 'document no longer focused'
146
+ // @if CK_DEBUG_TYPING // ) );
147
+ // @if CK_DEBUG_TYPING // }
100
148
  this.document.isFocused = false;
101
149
  this._isFocusChanging = false;
102
150
  // Re-render the document to update view elements
103
151
  // (changing document.isFocused already marked view as changed since last rendering).
104
152
  this.view.change(() => { });
153
+ // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
154
+ // @if CK_DEBUG_TYPING // console.groupEnd();
155
+ // @if CK_DEBUG_TYPING // }
105
156
  }
106
157
  }
107
158
  /**
@@ -8,7 +8,7 @@
8
8
  import DomEventObserver from './domeventobserver.js';
9
9
  import DataTransfer from '../datatransfer.js';
10
10
  import { env } from '@ckeditor/ckeditor5-utils';
11
- // @if CK_DEBUG_TYPING // const { _debouncedLine } = require( '../../dev-utils/utils.js' );
11
+ // @if CK_DEBUG_TYPING // const { _debouncedLine, _buildLogMessage } = require( '../../dev-utils/utils.js' );
12
12
  /**
13
13
  * Observer for events connected with data input.
14
14
  *
@@ -16,22 +16,19 @@ import { env } from '@ckeditor/ckeditor5-utils';
16
16
  * editor instances.
17
17
  */
18
18
  export default class InputObserver extends DomEventObserver {
19
- constructor() {
20
- super(...arguments);
21
- /**
22
- * @inheritDoc
23
- */
24
- this.domEventType = 'beforeinput';
25
- }
19
+ /**
20
+ * @inheritDoc
21
+ */
22
+ domEventType = 'beforeinput';
26
23
  /**
27
24
  * @inheritDoc
28
25
  */
29
26
  onDomEvent(domEvent) {
30
27
  // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
31
28
  // @if CK_DEBUG_TYPING // _debouncedLine();
32
- // @if CK_DEBUG_TYPING // console.group( `%c[InputObserver]%c ${ domEvent.type }: ${ domEvent.inputType }`,
33
- // @if CK_DEBUG_TYPING // 'color: green', 'color: default'
34
- // @if CK_DEBUG_TYPING // );
29
+ // @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'InputObserver',
30
+ // @if CK_DEBUG_TYPING // `${ domEvent.type }: ${ domEvent.inputType }`
31
+ // @if CK_DEBUG_TYPING // ) );
35
32
  // @if CK_DEBUG_TYPING // }
36
33
  const domTargetRanges = domEvent.getTargetRanges();
37
34
  const view = this.view;
@@ -45,17 +42,21 @@ export default class InputObserver extends DomEventObserver {
45
42
  if (domEvent.data !== null) {
46
43
  data = domEvent.data;
47
44
  // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
48
- // @if CK_DEBUG_TYPING // console.info( `%c[InputObserver]%c event data: %c${ JSON.stringify( data ) }`,
49
- // @if CK_DEBUG_TYPING // 'color: green; font-weight: bold', 'font-weight: bold', 'color: blue;'
50
- // @if CK_DEBUG_TYPING // );
45
+ // @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'InputObserver',
46
+ // @if CK_DEBUG_TYPING // `%cevent data: %c${ JSON.stringify( data ) }`,
47
+ // @if CK_DEBUG_TYPING // 'font-weight: bold',
48
+ // @if CK_DEBUG_TYPING // 'color: blue;'
49
+ // @if CK_DEBUG_TYPING // ) );
51
50
  // @if CK_DEBUG_TYPING // }
52
51
  }
53
52
  else if (dataTransfer) {
54
53
  data = dataTransfer.getData('text/plain');
55
54
  // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
56
- // @if CK_DEBUG_TYPING // console.info( `%c[InputObserver]%c event data transfer: %c${ JSON.stringify( data ) }`,
57
- // @if CK_DEBUG_TYPING // 'color: green; font-weight: bold', 'font-weight: bold', 'color: blue;'
58
- // @if CK_DEBUG_TYPING // );
55
+ // @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'InputObserver',
56
+ // @if CK_DEBUG_TYPING // `%cevent data transfer: %c${ JSON.stringify( data ) }`,
57
+ // @if CK_DEBUG_TYPING // 'font-weight: bold',
58
+ // @if CK_DEBUG_TYPING // 'color: blue;'
59
+ // @if CK_DEBUG_TYPING // ) );
59
60
  // @if CK_DEBUG_TYPING // }
60
61
  }
61
62
  // If the editor selection is fake (an object is selected), the DOM range does not make sense because it is anchored
@@ -64,10 +65,12 @@ export default class InputObserver extends DomEventObserver {
64
65
  // Future-proof: in case of multi-range fake selections being possible.
65
66
  targetRanges = Array.from(viewDocument.selection.getRanges());
66
67
  // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
67
- // @if CK_DEBUG_TYPING // console.info( '%c[InputObserver]%c using fake selection:',
68
- // @if CK_DEBUG_TYPING // 'color: green; font-weight: bold', 'font-weight: bold', targetRanges,
68
+ // @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'InputObserver',
69
+ // @if CK_DEBUG_TYPING // '%cusing fake selection:',
70
+ // @if CK_DEBUG_TYPING // 'font-weight: bold',
71
+ // @if CK_DEBUG_TYPING // targetRanges,
69
72
  // @if CK_DEBUG_TYPING // viewDocument.selection.isFake ? 'fake view selection' : 'fake DOM parent'
70
- // @if CK_DEBUG_TYPING // );
73
+ // @if CK_DEBUG_TYPING // ) );
71
74
  // @if CK_DEBUG_TYPING // }
72
75
  }
73
76
  else if (domTargetRanges.length) {
@@ -86,9 +89,11 @@ export default class InputObserver extends DomEventObserver {
86
89
  }
87
90
  }).filter((range) => !!range);
88
91
  // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
89
- // @if CK_DEBUG_TYPING // console.info( '%c[InputObserver]%c using target ranges:',
90
- // @if CK_DEBUG_TYPING // 'color: green; font-weight: bold', 'font-weight: bold', targetRanges
91
- // @if CK_DEBUG_TYPING // );
92
+ // @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'InputObserver',
93
+ // @if CK_DEBUG_TYPING // '%cusing target ranges:',
94
+ // @if CK_DEBUG_TYPING // 'font-weight: bold',
95
+ // @if CK_DEBUG_TYPING // targetRanges
96
+ // @if CK_DEBUG_TYPING // ) );
92
97
  // @if CK_DEBUG_TYPING // }
93
98
  }
94
99
  // For Android devices we use a fallback to the current DOM selection, Android modifies it according
@@ -97,9 +102,11 @@ export default class InputObserver extends DomEventObserver {
97
102
  const domSelection = domEvent.target.ownerDocument.defaultView.getSelection();
98
103
  targetRanges = Array.from(view.domConverter.domSelectionToView(domSelection).getRanges());
99
104
  // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
100
- // @if CK_DEBUG_TYPING // console.info( '%c[InputObserver]%c using selection ranges:',
101
- // @if CK_DEBUG_TYPING // 'color: green; font-weight: bold', 'font-weight: bold', targetRanges
102
- // @if CK_DEBUG_TYPING // );
105
+ // @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'InputObserver',
106
+ // @if CK_DEBUG_TYPING // '%cusing selection ranges:',
107
+ // @if CK_DEBUG_TYPING // 'font-weight: bold',
108
+ // @if CK_DEBUG_TYPING // targetRanges
109
+ // @if CK_DEBUG_TYPING // ) );
103
110
  // @if CK_DEBUG_TYPING // }
104
111
  }
105
112
  // Android sometimes fires insertCompositionText with a new-line character at the end of the data
@@ -13,13 +13,10 @@ import { getCode } from '@ckeditor/ckeditor5-utils';
13
13
  * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.
14
14
  */
15
15
  export default class KeyObserver extends DomEventObserver {
16
- constructor() {
17
- super(...arguments);
18
- /**
19
- * @inheritDoc
20
- */
21
- this.domEventType = ['keydown', 'keyup'];
22
- }
16
+ /**
17
+ * @inheritDoc
18
+ */
19
+ domEventType = ['keydown', 'keyup'];
23
20
  /**
24
21
  * @inheritDoc
25
22
  */
@@ -13,13 +13,10 @@ import DomEventObserver from './domeventobserver.js';
13
13
  * {@link module:engine/view/view~View} by {@link module:engine/view/view~View#addObserver} method.
14
14
  */
15
15
  export default class MouseObserver extends DomEventObserver {
16
- constructor() {
17
- super(...arguments);
18
- /**
19
- * @inheritDoc
20
- */
21
- this.domEventType = ['mousedown', 'mouseup', 'mouseover', 'mouseout'];
22
- }
16
+ /**
17
+ * @inheritDoc
18
+ */
19
+ domEventType = ['mousedown', 'mouseup', 'mouseover', 'mouseout'];
23
20
  /**
24
21
  * @inheritDoc
25
22
  */
@@ -8,8 +8,8 @@
8
8
  /* globals window */
9
9
  import Observer from './observer.js';
10
10
  import { startsWithFiller } from '../filler.js';
11
- import { isEqualWith } from 'lodash-es';
12
- // @if CK_DEBUG_TYPING // const { _debouncedLine } = require( '../../dev-utils/utils.js' );
11
+ import { isEqualWith } from 'es-toolkit/compat';
12
+ // @if CK_DEBUG_TYPING // const { _debouncedLine, _buildLogMessage } = require( '../../dev-utils/utils.js' );
13
13
  /**
14
14
  * Mutation observer's role is to watch for any DOM changes inside the editor that weren't
15
15
  * done by the editor's {@link module:engine/view/renderer~Renderer} itself and reverting these changes.
@@ -22,6 +22,22 @@ import { isEqualWith } from 'lodash-es';
22
22
  * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.
23
23
  */
24
24
  export default class MutationObserver extends Observer {
25
+ /**
26
+ * Reference to the {@link module:engine/view/view~View#domConverter}.
27
+ */
28
+ domConverter;
29
+ /**
30
+ * Native mutation observer config.
31
+ */
32
+ _config;
33
+ /**
34
+ * Observed DOM elements.
35
+ */
36
+ _domElements;
37
+ /**
38
+ * Native mutation observer.
39
+ */
40
+ _mutationObserver;
25
41
  /**
26
42
  * @inheritDoc
27
43
  */
@@ -157,9 +173,10 @@ export default class MutationObserver extends Observer {
157
173
  if (mutations.length) {
158
174
  // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
159
175
  // @if CK_DEBUG_TYPING // _debouncedLine();
160
- // @if CK_DEBUG_TYPING // console.group( '%c[MutationObserver]%c Mutations detected',
161
- // @if CK_DEBUG_TYPING // 'font-weight: bold; color: green', 'font-weight: bold'
162
- // @if CK_DEBUG_TYPING // );
176
+ // @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'MutationObserver',
177
+ // @if CK_DEBUG_TYPING // '%cMutations detected',
178
+ // @if CK_DEBUG_TYPING // 'font-weight: bold'
179
+ // @if CK_DEBUG_TYPING // ) );
163
180
  // @if CK_DEBUG_TYPING // }
164
181
  this.document.fire('mutations', { mutations });
165
182
  // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
@@ -186,7 +203,7 @@ export default class MutationObserver extends Observer {
186
203
  }
187
204
  }
188
205
  function sameNodes(child1, child2) {
189
- // First level of comparison (array of children vs array of children) – use the Lodash's default behavior.
206
+ // First level of comparison (array of children vs array of children) – use the es-toolkit's default behavior.
190
207
  if (Array.isArray(child1)) {
191
208
  return;
192
209
  }
@@ -13,15 +13,23 @@ import { DomEmitterMixin } from '@ckeditor/ckeditor5-utils';
13
13
  * which need a refresh on DOM events.
14
14
  */
15
15
  export default class Observer extends /* #__PURE__ */ DomEmitterMixin() {
16
+ /**
17
+ * An instance of the view controller.
18
+ */
19
+ view;
20
+ /**
21
+ * A reference to the {@link module:engine/view/document~Document} object.
22
+ */
23
+ document;
24
+ /**
25
+ * The state of the observer. If it is disabled, no events will be fired.
26
+ */
27
+ _isEnabled = false;
16
28
  /**
17
29
  * Creates an instance of the observer.
18
30
  */
19
31
  constructor(view) {
20
32
  super();
21
- /**
22
- * The state of the observer. If it is disabled, no events will be fired.
23
- */
24
- this._isEnabled = false;
25
33
  this.view = view;
26
34
  this.document = view.document;
27
35
  }
@@ -50,7 +50,7 @@ export default class SelectionObserver extends Observer {
50
50
  */
51
51
  private readonly _documents;
52
52
  /**
53
- * Fires debounced event `selectionChangeDone`. It uses `lodash#debounce` method to delay function call.
53
+ * Fires debounced event `selectionChangeDone`. It uses `es-toolkit#debounce` method to delay function call.
54
54
  */
55
55
  private readonly _fireSelectionChangeDoneDebounced;
56
56
  /**
@@ -69,6 +69,11 @@ export default class SelectionObserver extends Observer {
69
69
  * Private property to check if the code does not enter infinite loop.
70
70
  */
71
71
  private _loopbackCounter;
72
+ /**
73
+ * A set of DOM documents that have a pending selection change.
74
+ * Pending selection change is recorded while selection change event is detected on non focused editable.
75
+ */
76
+ private _pendingSelectionChange;
72
77
  constructor(view: View);
73
78
  /**
74
79
  * @inheritDoc