@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.
- package/LICENSE.md +1 -1
- package/dist/index.js +305 -129
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/controller/datacontroller.js +40 -0
- package/src/controller/editingcontroller.js +16 -0
- package/src/conversion/conversion.js +6 -4
- package/src/conversion/conversionhelpers.js +1 -0
- package/src/conversion/downcastdispatcher.js +10 -0
- package/src/conversion/downcasthelpers.js +1 -1
- package/src/conversion/mapper.js +92 -95
- package/src/conversion/modelconsumable.js +13 -15
- package/src/conversion/upcastdispatcher.js +28 -24
- package/src/conversion/upcasthelpers.d.ts +1 -1
- package/src/conversion/upcasthelpers.js +2 -2
- package/src/conversion/viewconsumable.js +19 -20
- package/src/dataprocessor/htmldataprocessor.js +13 -1
- package/src/dataprocessor/xmldataprocessor.js +21 -1
- package/src/dev-utils/model.js +1 -1
- package/src/dev-utils/operationreplayer.js +3 -0
- package/src/dev-utils/utils.js +35 -1
- package/src/dev-utils/view.js +13 -0
- package/src/model/batch.js +20 -0
- package/src/model/differ.js +92 -88
- package/src/model/document.d.ts +1 -3
- package/src/model/document.js +38 -1
- package/src/model/documentfragment.js +10 -10
- package/src/model/documentselection.js +44 -32
- package/src/model/element.js +8 -4
- package/src/model/history.js +31 -33
- package/src/model/markercollection.js +25 -7
- package/src/model/model.js +21 -0
- package/src/model/node.js +22 -18
- package/src/model/nodelist.js +12 -12
- package/src/model/operation/attributeoperation.js +25 -1
- package/src/model/operation/detachoperation.js +8 -0
- package/src/model/operation/insertoperation.js +18 -0
- package/src/model/operation/markeroperation.js +29 -0
- package/src/model/operation/mergeoperation.js +16 -0
- package/src/model/operation/moveoperation.js +12 -0
- package/src/model/operation/operation.js +19 -0
- package/src/model/operation/renameoperation.js +12 -0
- package/src/model/operation/rootattributeoperation.js +20 -0
- package/src/model/operation/rootoperation.js +16 -0
- package/src/model/operation/splitoperation.js +19 -0
- package/src/model/operation/transform.js +5 -0
- package/src/model/position.js +40 -0
- package/src/model/range.js +8 -0
- package/src/model/rootelement.js +18 -10
- package/src/model/schema.js +25 -23
- package/src/model/selection.js +10 -10
- package/src/model/text.js +6 -0
- package/src/model/textproxy.js +12 -0
- package/src/model/treewalker.js +49 -0
- package/src/model/utils/insertcontent.js +60 -25
- package/src/model/writer.js +8 -0
- package/src/view/attributeelement.js +23 -23
- package/src/view/datatransfer.js +8 -0
- package/src/view/document.js +21 -4
- package/src/view/documentfragment.js +13 -9
- package/src/view/documentselection.js +4 -0
- package/src/view/domconverter.d.ts +6 -1
- package/src/view/domconverter.js +109 -48
- package/src/view/downcastwriter.js +14 -10
- package/src/view/element.js +29 -17
- package/src/view/matcher.js +1 -1
- package/src/view/node.js +9 -1
- package/src/view/observer/bubblingeventinfo.js +12 -0
- package/src/view/observer/clickobserver.js +4 -7
- package/src/view/observer/compositionobserver.js +14 -12
- package/src/view/observer/domeventdata.js +17 -1
- package/src/view/observer/domeventobserver.js +10 -13
- package/src/view/observer/fakeselectionobserver.d.ts +1 -1
- package/src/view/observer/fakeselectionobserver.js +5 -1
- package/src/view/observer/focusobserver.js +65 -14
- package/src/view/observer/inputobserver.js +33 -26
- package/src/view/observer/keyobserver.js +4 -7
- package/src/view/observer/mouseobserver.js +4 -7
- package/src/view/observer/mutationobserver.js +23 -6
- package/src/view/observer/observer.js +12 -4
- package/src/view/observer/selectionobserver.d.ts +6 -1
- package/src/view/observer/selectionobserver.js +94 -17
- package/src/view/observer/touchobserver.js +4 -7
- package/src/view/position.js +8 -0
- package/src/view/range.js +8 -0
- package/src/view/renderer.js +142 -70
- package/src/view/selection.js +16 -0
- package/src/view/stylesmap.js +26 -11
- package/src/view/text.js +6 -0
- package/src/view/textproxy.js +12 -0
- package/src/view/tokenlist.js +4 -6
- package/src/view/treewalker.js +42 -0
- package/src/view/upcastwriter.js +5 -1
- package/src/view/view.js +51 -33
|
@@ -10,7 +10,7 @@ import Observer from './observer.js';
|
|
|
10
10
|
import MutationObserver from './mutationobserver.js';
|
|
11
11
|
import FocusObserver from './focusobserver.js';
|
|
12
12
|
import { env } from '@ckeditor/ckeditor5-utils';
|
|
13
|
-
import { debounce } from '
|
|
13
|
+
import { debounce } from 'es-toolkit/compat';
|
|
14
14
|
/**
|
|
15
15
|
* Selection observer class observes selection changes in the document. If a selection changes on the document this
|
|
16
16
|
* observer checks if the DOM selection is different from the {@link module:engine/view/document~Document#selection view selection}.
|
|
@@ -22,19 +22,81 @@ import { debounce } 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 SelectionObserver extends Observer {
|
|
25
|
+
/**
|
|
26
|
+
* Instance of the mutation observer. Selection observer calls
|
|
27
|
+
* {@link module:engine/view/observer/mutationobserver~MutationObserver#flush} to ensure that the mutations will be handled
|
|
28
|
+
* before the {@link module:engine/view/document~Document#event:selectionChange} event is fired.
|
|
29
|
+
*/
|
|
30
|
+
mutationObserver;
|
|
31
|
+
/**
|
|
32
|
+
* Instance of the focus observer. Focus observer calls
|
|
33
|
+
* {@link module:engine/view/observer/focusobserver~FocusObserver#flush} to mark the latest focus change as complete.
|
|
34
|
+
*/
|
|
35
|
+
focusObserver;
|
|
36
|
+
/**
|
|
37
|
+
* Reference to the view {@link module:engine/view/documentselection~DocumentSelection} object used to compare
|
|
38
|
+
* new selection with it.
|
|
39
|
+
*/
|
|
40
|
+
selection;
|
|
41
|
+
/**
|
|
42
|
+
* Reference to the {@link module:engine/view/view~View#domConverter}.
|
|
43
|
+
*/
|
|
44
|
+
domConverter;
|
|
45
|
+
/**
|
|
46
|
+
* A set of documents which have added `selectionchange` listener to avoid adding a listener twice to the same
|
|
47
|
+
* document.
|
|
48
|
+
*/
|
|
49
|
+
_documents = new WeakSet();
|
|
50
|
+
/**
|
|
51
|
+
* Fires debounced event `selectionChangeDone`. It uses `es-toolkit#debounce` method to delay function call.
|
|
52
|
+
*/
|
|
53
|
+
_fireSelectionChangeDoneDebounced;
|
|
54
|
+
/**
|
|
55
|
+
* When called, starts clearing the {@link #_loopbackCounter} counter in time intervals. When the number of selection
|
|
56
|
+
* changes exceeds a certain limit within the interval of time, the observer will not fire `selectionChange` but warn about
|
|
57
|
+
* possible infinite selection loop.
|
|
58
|
+
*/
|
|
59
|
+
_clearInfiniteLoopInterval;
|
|
60
|
+
/**
|
|
61
|
+
* Unlocks the `isSelecting` state of the view document in case the selection observer did not record this fact
|
|
62
|
+
* correctly (for whatever reason). It is a safeguard (paranoid check), that returns document to the normal state
|
|
63
|
+
* after a certain period of time (debounced, postponed by each selectionchange event).
|
|
64
|
+
*/
|
|
65
|
+
_documentIsSelectingInactivityTimeoutDebounced;
|
|
66
|
+
/**
|
|
67
|
+
* Private property to check if the code does not enter infinite loop.
|
|
68
|
+
*/
|
|
69
|
+
_loopbackCounter = 0;
|
|
70
|
+
/**
|
|
71
|
+
* A set of DOM documents that have a pending selection change.
|
|
72
|
+
* Pending selection change is recorded while selection change event is detected on non focused editable.
|
|
73
|
+
*/
|
|
74
|
+
_pendingSelectionChange = new Set();
|
|
25
75
|
constructor(view) {
|
|
26
76
|
super(view);
|
|
27
77
|
this.mutationObserver = view.getObserver(MutationObserver);
|
|
28
78
|
this.focusObserver = view.getObserver(FocusObserver);
|
|
29
79
|
this.selection = this.document.selection;
|
|
30
80
|
this.domConverter = view.domConverter;
|
|
31
|
-
this._documents = new WeakSet();
|
|
32
81
|
this._fireSelectionChangeDoneDebounced = debounce(data => {
|
|
33
82
|
this.document.fire('selectionChangeDone', data);
|
|
34
83
|
}, 200);
|
|
35
84
|
this._clearInfiniteLoopInterval = setInterval(() => this._clearInfiniteLoop(), 1000);
|
|
36
85
|
this._documentIsSelectingInactivityTimeoutDebounced = debounce(() => (this.document.isSelecting = false), 5000);
|
|
37
|
-
this.
|
|
86
|
+
this.view.document.on('change:isFocused', (evt, name, isFocused) => {
|
|
87
|
+
if (isFocused && this._pendingSelectionChange.size) {
|
|
88
|
+
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
89
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'SelectionObserver',
|
|
90
|
+
// @if CK_DEBUG_TYPING // 'Flush pending selection change'
|
|
91
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
92
|
+
// @if CK_DEBUG_TYPING // }
|
|
93
|
+
// Iterate over a copy of set because it is modified in selection change handler.
|
|
94
|
+
for (const domDocument of Array.from(this._pendingSelectionChange)) {
|
|
95
|
+
this._handleSelectionChange(domDocument);
|
|
96
|
+
}
|
|
97
|
+
this._pendingSelectionChange.clear();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
38
100
|
}
|
|
39
101
|
/**
|
|
40
102
|
* @inheritDoc
|
|
@@ -74,20 +136,22 @@ export default class SelectionObserver extends Observer {
|
|
|
74
136
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
75
137
|
// @if CK_DEBUG_TYPING // _debouncedLine();
|
|
76
138
|
// @if CK_DEBUG_TYPING // const domSelection = domDocument.defaultView!.getSelection();
|
|
77
|
-
// @if CK_DEBUG_TYPING // console.group(
|
|
78
|
-
// @if CK_DEBUG_TYPING //
|
|
79
|
-
// @if CK_DEBUG_TYPING //
|
|
139
|
+
// @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'SelectionObserver',
|
|
140
|
+
// @if CK_DEBUG_TYPING // 'selectionchange'
|
|
141
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
142
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'SelectionObserver',
|
|
143
|
+
// @if CK_DEBUG_TYPING // 'DOM Selection:',
|
|
80
144
|
// @if CK_DEBUG_TYPING // { node: domSelection!.anchorNode, offset: domSelection!.anchorOffset },
|
|
81
145
|
// @if CK_DEBUG_TYPING // { node: domSelection!.focusNode, offset: domSelection!.focusOffset }
|
|
82
|
-
// @if CK_DEBUG_TYPING // );
|
|
146
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
83
147
|
// @if CK_DEBUG_TYPING // }
|
|
84
148
|
// The Renderer is disabled while composing on non-android browsers, so we can't update the view selection
|
|
85
149
|
// because the DOM and view tree drifted apart. Position mapping could fail because of it.
|
|
86
150
|
if (this.document.isComposing && !env.isAndroid) {
|
|
87
151
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
88
|
-
// @if CK_DEBUG_TYPING // console.info(
|
|
89
|
-
// @if CK_DEBUG_TYPING //
|
|
90
|
-
// @if CK_DEBUG_TYPING //
|
|
152
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'SelectionObserver',
|
|
153
|
+
// @if CK_DEBUG_TYPING // 'Selection change ignored (isComposing)'
|
|
154
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
91
155
|
// @if CK_DEBUG_TYPING // console.groupEnd();
|
|
92
156
|
// @if CK_DEBUG_TYPING // }
|
|
93
157
|
return;
|
|
@@ -106,12 +170,14 @@ export default class SelectionObserver extends Observer {
|
|
|
106
170
|
this.listenTo(this.view.document, 'compositionstart', () => {
|
|
107
171
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
108
172
|
// @if CK_DEBUG_TYPING // const domSelection = domDocument.defaultView!.getSelection();
|
|
109
|
-
// @if CK_DEBUG_TYPING // console.group(
|
|
110
|
-
// @if CK_DEBUG_TYPING //
|
|
111
|
-
// @if CK_DEBUG_TYPING //
|
|
173
|
+
// @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'SelectionObserver',
|
|
174
|
+
// @if CK_DEBUG_TYPING // 'update selection on compositionstart'
|
|
175
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
176
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'SelectionObserver',
|
|
177
|
+
// @if CK_DEBUG_TYPING // 'DOM Selection:',
|
|
112
178
|
// @if CK_DEBUG_TYPING // { node: domSelection!.anchorNode, offset: domSelection!.anchorOffset },
|
|
113
179
|
// @if CK_DEBUG_TYPING // { node: domSelection!.focusNode, offset: domSelection!.focusOffset }
|
|
114
|
-
// @if CK_DEBUG_TYPING // );
|
|
180
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
115
181
|
// @if CK_DEBUG_TYPING // }
|
|
116
182
|
this._handleSelectionChange(domDocument);
|
|
117
183
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
@@ -171,6 +237,17 @@ export default class SelectionObserver extends Observer {
|
|
|
171
237
|
this.view.hasDomSelection = true;
|
|
172
238
|
// Mark the latest focus change as complete (we got new selection after the focus so the selection is in the focused element).
|
|
173
239
|
this.focusObserver.flush();
|
|
240
|
+
// Ignore selection change as the editable is not focused.
|
|
241
|
+
if (!this.view.document.isFocused) {
|
|
242
|
+
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
243
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'SelectionObserver',
|
|
244
|
+
// @if CK_DEBUG_TYPING // 'Ignore selection change while editable is not focused'
|
|
245
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
246
|
+
// @if CK_DEBUG_TYPING // }
|
|
247
|
+
this._pendingSelectionChange.add(domDocument);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
this._pendingSelectionChange.delete(domDocument);
|
|
174
251
|
if (this.selection.isEqual(newViewSelection) && this.domConverter.isDomSelectionCorrect(domSelection)) {
|
|
175
252
|
return;
|
|
176
253
|
}
|
|
@@ -197,10 +274,10 @@ export default class SelectionObserver extends Observer {
|
|
|
197
274
|
domSelection
|
|
198
275
|
};
|
|
199
276
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
200
|
-
// @if CK_DEBUG_TYPING // console.info(
|
|
201
|
-
// @if CK_DEBUG_TYPING // '
|
|
277
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'SelectionObserver',
|
|
278
|
+
// @if CK_DEBUG_TYPING // 'Fire selection change:',
|
|
202
279
|
// @if CK_DEBUG_TYPING // newViewSelection.getFirstRange()
|
|
203
|
-
// @if CK_DEBUG_TYPING // );
|
|
280
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
204
281
|
// @if CK_DEBUG_TYPING // }
|
|
205
282
|
// Prepare data for new selection and fire appropriate events.
|
|
206
283
|
this.document.fire('selectionChange', data);
|
|
@@ -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 TouchObserver extends DomEventObserver {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*/
|
|
21
|
-
this.domEventType = ['touchstart', 'touchend', 'touchmove'];
|
|
22
|
-
}
|
|
16
|
+
/**
|
|
17
|
+
* @inheritDoc
|
|
18
|
+
*/
|
|
19
|
+
domEventType = ['touchstart', 'touchend', 'touchmove'];
|
|
23
20
|
/**
|
|
24
21
|
* @inheritDoc
|
|
25
22
|
*/
|
package/src/view/position.js
CHANGED
|
@@ -19,6 +19,14 @@ import { default as TreeWalker } from './treewalker.js';
|
|
|
19
19
|
* * {@link module:engine/view/upcastwriter~UpcastWriter}
|
|
20
20
|
*/
|
|
21
21
|
export default class Position extends TypeCheckable {
|
|
22
|
+
/**
|
|
23
|
+
* Position parent.
|
|
24
|
+
*/
|
|
25
|
+
parent;
|
|
26
|
+
/**
|
|
27
|
+
* Position offset.
|
|
28
|
+
*/
|
|
29
|
+
offset;
|
|
22
30
|
/**
|
|
23
31
|
* Creates a position.
|
|
24
32
|
*
|
package/src/view/range.js
CHANGED
|
@@ -18,6 +18,14 @@ import { default as TreeWalker } from './treewalker.js';
|
|
|
18
18
|
* * {@link module:engine/view/upcastwriter~UpcastWriter}
|
|
19
19
|
*/
|
|
20
20
|
export default class Range extends TypeCheckable {
|
|
21
|
+
/**
|
|
22
|
+
* Start position.
|
|
23
|
+
*/
|
|
24
|
+
start;
|
|
25
|
+
/**
|
|
26
|
+
* End position.
|
|
27
|
+
*/
|
|
28
|
+
end;
|
|
21
29
|
/**
|
|
22
30
|
* Creates a range spanning from `start` position to `end` position.
|
|
23
31
|
*
|
package/src/view/renderer.js
CHANGED
|
@@ -9,6 +9,7 @@ import ViewText from './text.js';
|
|
|
9
9
|
import ViewPosition from './position.js';
|
|
10
10
|
import { INLINE_FILLER, INLINE_FILLER_LENGTH, startsWithFiller, isInlineFiller } from './filler.js';
|
|
11
11
|
import { CKEditorError, ObservableMixin, diff, env, fastDiff, insertAt, isComment, isNode, isText, remove, indexOf } from '@ckeditor/ckeditor5-utils';
|
|
12
|
+
// @if CK_DEBUG_TYPING // const { _buildLogMessage } = require( '../dev-utils/utils.js' );
|
|
12
13
|
import '../../theme/renderer.css';
|
|
13
14
|
/**
|
|
14
15
|
* Renderer is responsible for updating the DOM structure and the DOM selection based on
|
|
@@ -24,6 +25,38 @@ import '../../theme/renderer.css';
|
|
|
24
25
|
* to and from the DOM.
|
|
25
26
|
*/
|
|
26
27
|
export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
28
|
+
/**
|
|
29
|
+
* Set of DOM Documents instances.
|
|
30
|
+
*/
|
|
31
|
+
domDocuments = new Set();
|
|
32
|
+
/**
|
|
33
|
+
* Converter instance.
|
|
34
|
+
*/
|
|
35
|
+
domConverter;
|
|
36
|
+
/**
|
|
37
|
+
* Set of nodes which attributes changed and may need to be rendered.
|
|
38
|
+
*/
|
|
39
|
+
markedAttributes = new Set();
|
|
40
|
+
/**
|
|
41
|
+
* Set of elements which child lists changed and may need to be rendered.
|
|
42
|
+
*/
|
|
43
|
+
markedChildren = new Set();
|
|
44
|
+
/**
|
|
45
|
+
* Set of text nodes which text data changed and may need to be rendered.
|
|
46
|
+
*/
|
|
47
|
+
markedTexts = new Set();
|
|
48
|
+
/**
|
|
49
|
+
* View selection. Renderer updates DOM selection based on the view selection.
|
|
50
|
+
*/
|
|
51
|
+
selection;
|
|
52
|
+
/**
|
|
53
|
+
* The text node in which the inline filler was rendered.
|
|
54
|
+
*/
|
|
55
|
+
_inlineFiller = null;
|
|
56
|
+
/**
|
|
57
|
+
* DOM element containing fake selection.
|
|
58
|
+
*/
|
|
59
|
+
_fakeSelectionContainer = null;
|
|
27
60
|
/**
|
|
28
61
|
* Creates a renderer instance.
|
|
29
62
|
*
|
|
@@ -32,30 +65,6 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
32
65
|
*/
|
|
33
66
|
constructor(domConverter, selection) {
|
|
34
67
|
super();
|
|
35
|
-
/**
|
|
36
|
-
* Set of DOM Documents instances.
|
|
37
|
-
*/
|
|
38
|
-
this.domDocuments = new Set();
|
|
39
|
-
/**
|
|
40
|
-
* Set of nodes which attributes changed and may need to be rendered.
|
|
41
|
-
*/
|
|
42
|
-
this.markedAttributes = new Set();
|
|
43
|
-
/**
|
|
44
|
-
* Set of elements which child lists changed and may need to be rendered.
|
|
45
|
-
*/
|
|
46
|
-
this.markedChildren = new Set();
|
|
47
|
-
/**
|
|
48
|
-
* Set of text nodes which text data changed and may need to be rendered.
|
|
49
|
-
*/
|
|
50
|
-
this.markedTexts = new Set();
|
|
51
|
-
/**
|
|
52
|
-
* The text node in which the inline filler was rendered.
|
|
53
|
-
*/
|
|
54
|
-
this._inlineFiller = null;
|
|
55
|
-
/**
|
|
56
|
-
* DOM element containing fake selection.
|
|
57
|
-
*/
|
|
58
|
-
this._fakeSelectionContainer = null;
|
|
59
68
|
this.domConverter = domConverter;
|
|
60
69
|
this.selection = selection;
|
|
61
70
|
this.set('isFocused', false);
|
|
@@ -133,16 +142,18 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
133
142
|
// and we should not do it because the difference between view and DOM could lead to position mapping problems.
|
|
134
143
|
if (this.isComposing && !env.isAndroid) {
|
|
135
144
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
136
|
-
// @if CK_DEBUG_TYPING // console.info(
|
|
137
|
-
// @if CK_DEBUG_TYPING // '
|
|
138
|
-
// @if CK_DEBUG_TYPING //
|
|
145
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
146
|
+
// @if CK_DEBUG_TYPING // '%cRendering aborted while isComposing.',
|
|
147
|
+
// @if CK_DEBUG_TYPING // 'font-style: italic'
|
|
148
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
139
149
|
// @if CK_DEBUG_TYPING // }
|
|
140
150
|
return;
|
|
141
151
|
}
|
|
142
152
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
143
|
-
// @if CK_DEBUG_TYPING // console.group( '
|
|
144
|
-
// @if CK_DEBUG_TYPING // '
|
|
145
|
-
// @if CK_DEBUG_TYPING //
|
|
153
|
+
// @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'Renderer',
|
|
154
|
+
// @if CK_DEBUG_TYPING // '%cRendering',
|
|
155
|
+
// @if CK_DEBUG_TYPING // 'font-weight: bold'
|
|
156
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
146
157
|
// @if CK_DEBUG_TYPING // }
|
|
147
158
|
let inlineFillerPosition = null;
|
|
148
159
|
const isInlineFillerRenderingPossible = env.isBlink && !env.isAndroid ? !this.isSelecting : true;
|
|
@@ -426,9 +437,10 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
426
437
|
expectedText = INLINE_FILLER + expectedText;
|
|
427
438
|
}
|
|
428
439
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
429
|
-
// @if CK_DEBUG_TYPING // console.group(
|
|
430
|
-
// @if CK_DEBUG_TYPING // '
|
|
431
|
-
// @if CK_DEBUG_TYPING //
|
|
440
|
+
// @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'Renderer',
|
|
441
|
+
// @if CK_DEBUG_TYPING // '%cUpdate text',
|
|
442
|
+
// @if CK_DEBUG_TYPING // 'font-weight: normal'
|
|
443
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
432
444
|
// @if CK_DEBUG_TYPING // }
|
|
433
445
|
this._updateTextNode(domText, expectedText);
|
|
434
446
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
@@ -485,9 +497,10 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
485
497
|
return;
|
|
486
498
|
}
|
|
487
499
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
488
|
-
// @if CK_DEBUG_TYPING // console.group(
|
|
489
|
-
// @if CK_DEBUG_TYPING // '
|
|
490
|
-
// @if CK_DEBUG_TYPING //
|
|
500
|
+
// @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'Renderer',
|
|
501
|
+
// @if CK_DEBUG_TYPING // '%cUpdate children',
|
|
502
|
+
// @if CK_DEBUG_TYPING // 'font-weight: normal'
|
|
503
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
491
504
|
// @if CK_DEBUG_TYPING // }
|
|
492
505
|
// IME on Android inserts a new text node while typing after a link
|
|
493
506
|
// instead of updating an existing text node that follows the link.
|
|
@@ -517,9 +530,10 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
517
530
|
// The composition and different "language" browser extensions are fragile to text node being completely replaced.
|
|
518
531
|
const actions = this._findUpdateActions(diff, actualDomChildren, expectedDomChildren, areTextNodes);
|
|
519
532
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping && actions.every( a => a == 'equal' ) ) {
|
|
520
|
-
// @if CK_DEBUG_TYPING // console.info(
|
|
521
|
-
// @if CK_DEBUG_TYPING // '
|
|
522
|
-
// @if CK_DEBUG_TYPING //
|
|
533
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
534
|
+
// @if CK_DEBUG_TYPING // '%cNothing to update.',
|
|
535
|
+
// @if CK_DEBUG_TYPING // 'font-style: italic'
|
|
536
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
523
537
|
// @if CK_DEBUG_TYPING // }
|
|
524
538
|
let i = 0;
|
|
525
539
|
const nodesToUnbind = new Set();
|
|
@@ -534,19 +548,20 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
534
548
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
535
549
|
// @if CK_DEBUG_TYPING // const node = actualDomChildren[ i ];
|
|
536
550
|
// @if CK_DEBUG_TYPING // if ( isText( node ) ) {
|
|
537
|
-
// @if CK_DEBUG_TYPING // console.info(
|
|
551
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
552
|
+
// @if CK_DEBUG_TYPING // '%cRemove text node' +
|
|
538
553
|
// @if CK_DEBUG_TYPING // `${ this.isComposing ? ' while composing (may break composition)' : '' }: ` +
|
|
539
554
|
// @if CK_DEBUG_TYPING // `%c${ _escapeTextNodeData( node.data ) }%c (${ node.data.length })`,
|
|
540
|
-
// @if CK_DEBUG_TYPING // 'color:
|
|
541
|
-
// @if CK_DEBUG_TYPING //
|
|
542
|
-
// @if CK_DEBUG_TYPING // );
|
|
555
|
+
// @if CK_DEBUG_TYPING // this.isComposing ? 'color: red; font-weight: bold' : '',
|
|
556
|
+
// @if CK_DEBUG_TYPING // 'color: blue', ''
|
|
557
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
543
558
|
// @if CK_DEBUG_TYPING // } else {
|
|
544
|
-
// @if CK_DEBUG_TYPING // console.info(
|
|
559
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
560
|
+
// @if CK_DEBUG_TYPING // '%cRemove element' +
|
|
545
561
|
// @if CK_DEBUG_TYPING // `${ this.isComposing ? ' while composing (may break composition)' : '' }: `,
|
|
546
|
-
// @if CK_DEBUG_TYPING // 'color: green; font-weight: bold',
|
|
547
562
|
// @if CK_DEBUG_TYPING // this.isComposing ? 'color: red; font-weight: bold' : '',
|
|
548
563
|
// @if CK_DEBUG_TYPING // node
|
|
549
|
-
// @if CK_DEBUG_TYPING // );
|
|
564
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
550
565
|
// @if CK_DEBUG_TYPING // }
|
|
551
566
|
// @if CK_DEBUG_TYPING // }
|
|
552
567
|
nodesToUnbind.add(actualDomChildren[i]);
|
|
@@ -562,18 +577,20 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
562
577
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
563
578
|
// @if CK_DEBUG_TYPING // const node = expectedDomChildren[ i ];
|
|
564
579
|
// @if CK_DEBUG_TYPING // if ( isText( node ) ) {
|
|
565
|
-
// @if CK_DEBUG_TYPING // console.info(
|
|
580
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
581
|
+
// @if CK_DEBUG_TYPING // '%cInsert text node' +
|
|
566
582
|
// @if CK_DEBUG_TYPING // `${ this.isComposing ? ' while composing (may break composition)' : '' }: ` +
|
|
567
583
|
// @if CK_DEBUG_TYPING // `%c${ _escapeTextNodeData( node.data ) }%c (${ node.data.length })`,
|
|
568
|
-
// @if CK_DEBUG_TYPING // 'color: green; font-weight: bold',
|
|
569
584
|
// @if CK_DEBUG_TYPING // this.isComposing ? 'color: red; font-weight: bold' : '',
|
|
570
|
-
// @if CK_DEBUG_TYPING // 'color: blue',
|
|
571
|
-
// @if CK_DEBUG_TYPING //
|
|
585
|
+
// @if CK_DEBUG_TYPING // 'color: blue',
|
|
586
|
+
// @if CK_DEBUG_TYPING // ''
|
|
587
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
572
588
|
// @if CK_DEBUG_TYPING // } else {
|
|
573
|
-
// @if CK_DEBUG_TYPING // console.info(
|
|
574
|
-
// @if CK_DEBUG_TYPING // '
|
|
589
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
590
|
+
// @if CK_DEBUG_TYPING // '%cInsert element:',
|
|
591
|
+
// @if CK_DEBUG_TYPING // 'font-weight: normal',
|
|
575
592
|
// @if CK_DEBUG_TYPING // node
|
|
576
|
-
// @if CK_DEBUG_TYPING // );
|
|
593
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
577
594
|
// @if CK_DEBUG_TYPING // }
|
|
578
595
|
// @if CK_DEBUG_TYPING // }
|
|
579
596
|
insertAt(domElement, i, expectedDomChildren[i]);
|
|
@@ -672,10 +689,13 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
672
689
|
const actualText = domText.data;
|
|
673
690
|
if (actualText == expectedText) {
|
|
674
691
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
675
|
-
// @if CK_DEBUG_TYPING // console.info(
|
|
692
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
693
|
+
// @if CK_DEBUG_TYPING // '%cText node does not need update:%c ' +
|
|
676
694
|
// @if CK_DEBUG_TYPING // `${ _escapeTextNodeData( actualText ) }%c (${ actualText.length })`,
|
|
677
|
-
// @if CK_DEBUG_TYPING // '
|
|
678
|
-
// @if CK_DEBUG_TYPING //
|
|
695
|
+
// @if CK_DEBUG_TYPING // 'font-style: italic',
|
|
696
|
+
// @if CK_DEBUG_TYPING // 'color: blue',
|
|
697
|
+
// @if CK_DEBUG_TYPING // ''
|
|
698
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
679
699
|
// @if CK_DEBUG_TYPING // }
|
|
680
700
|
return;
|
|
681
701
|
}
|
|
@@ -685,22 +705,31 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
685
705
|
// See: https://github.com/ckeditor/ckeditor5/issues/13994.
|
|
686
706
|
if (env.isAndroid && this.isComposing && actualText.replace(/\u00A0/g, ' ') == expectedText.replace(/\u00A0/g, ' ')) {
|
|
687
707
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
688
|
-
// @if CK_DEBUG_TYPING // console.info(
|
|
689
|
-
// @if CK_DEBUG_TYPING //
|
|
690
|
-
// @if CK_DEBUG_TYPING //
|
|
691
|
-
// @if CK_DEBUG_TYPING //
|
|
692
|
-
// @if CK_DEBUG_TYPING //
|
|
708
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
709
|
+
// @if CK_DEBUG_TYPING // '%cText node ignore NBSP changes while composing: ' +
|
|
710
|
+
// @if CK_DEBUG_TYPING // `%c${ _escapeTextNodeData( actualText ) }%c (${ actualText.length }) -> ` +
|
|
711
|
+
// @if CK_DEBUG_TYPING // `%c${ _escapeTextNodeData( expectedText ) }%c (${ expectedText.length })`,
|
|
712
|
+
// @if CK_DEBUG_TYPING // 'font-style: italic',
|
|
713
|
+
// @if CK_DEBUG_TYPING // 'color: blue',
|
|
714
|
+
// @if CK_DEBUG_TYPING // '',
|
|
715
|
+
// @if CK_DEBUG_TYPING // 'color: blue',
|
|
716
|
+
// @if CK_DEBUG_TYPING // ''
|
|
717
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
693
718
|
// @if CK_DEBUG_TYPING // }
|
|
694
719
|
return;
|
|
695
720
|
}
|
|
696
721
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
697
|
-
// @if CK_DEBUG_TYPING // console.info(
|
|
722
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
723
|
+
// @if CK_DEBUG_TYPING // '%cUpdate text node' +
|
|
698
724
|
// @if CK_DEBUG_TYPING // `${ this.isComposing ? ' while composing (may break composition)' : '' }: ` +
|
|
699
|
-
// @if CK_DEBUG_TYPING // `%c${ _escapeTextNodeData( actualText ) }%c (${ actualText.length })
|
|
700
|
-
// @if CK_DEBUG_TYPING //
|
|
701
|
-
// @if CK_DEBUG_TYPING //
|
|
702
|
-
// @if CK_DEBUG_TYPING // 'color: blue',
|
|
703
|
-
// @if CK_DEBUG_TYPING //
|
|
725
|
+
// @if CK_DEBUG_TYPING // `%c${ _escapeTextNodeData( actualText ) }%c (${ actualText.length }) -> ` +
|
|
726
|
+
// @if CK_DEBUG_TYPING // `%c${ _escapeTextNodeData( expectedText ) }%c (${ expectedText.length })`,
|
|
727
|
+
// @if CK_DEBUG_TYPING // this.isComposing ? 'color: red; font-weight: bold' : '',
|
|
728
|
+
// @if CK_DEBUG_TYPING // 'color: blue',
|
|
729
|
+
// @if CK_DEBUG_TYPING // '',
|
|
730
|
+
// @if CK_DEBUG_TYPING // 'color: blue',
|
|
731
|
+
// @if CK_DEBUG_TYPING // ''
|
|
732
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
704
733
|
// @if CK_DEBUG_TYPING // }
|
|
705
734
|
this._updateTextNodeInternal(domText, expectedText);
|
|
706
735
|
}
|
|
@@ -751,6 +780,11 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
751
780
|
}
|
|
752
781
|
// If there is no selection - remove DOM and fake selections.
|
|
753
782
|
if (this.selection.rangeCount === 0) {
|
|
783
|
+
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
784
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
785
|
+
// @if CK_DEBUG_TYPING // 'Update DOM selection: remove all ranges'
|
|
786
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
787
|
+
// @if CK_DEBUG_TYPING // }
|
|
754
788
|
this._removeDomSelection();
|
|
755
789
|
this._removeFakeSelection();
|
|
756
790
|
return;
|
|
@@ -758,8 +792,19 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
758
792
|
const domRoot = this.domConverter.mapViewToDom(this.selection.editableElement);
|
|
759
793
|
// Do nothing if there is no focus, or there is no DOM element corresponding to selection's editable element.
|
|
760
794
|
if (!this.isFocused || !domRoot) {
|
|
795
|
+
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
796
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
797
|
+
// @if CK_DEBUG_TYPING // 'Skip updating DOM selection:',
|
|
798
|
+
// @if CK_DEBUG_TYPING // `isFocused: ${ this.isFocused }, hasDomRoot: ${ !!domRoot }`
|
|
799
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
800
|
+
// @if CK_DEBUG_TYPING // }
|
|
761
801
|
return;
|
|
762
802
|
}
|
|
803
|
+
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
804
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
805
|
+
// @if CK_DEBUG_TYPING // 'Update DOM selection'
|
|
806
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
807
|
+
// @if CK_DEBUG_TYPING // }
|
|
763
808
|
// Render fake selection - create the fake selection container (if needed) and move DOM selection to it.
|
|
764
809
|
if (this.selection.isFake) {
|
|
765
810
|
this._updateFakeSelection(domRoot);
|
|
@@ -798,6 +843,11 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
798
843
|
domRoot.appendChild(container);
|
|
799
844
|
}
|
|
800
845
|
container.textContent = this.selection.fakeSelectionLabel || '\u00A0';
|
|
846
|
+
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
847
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
848
|
+
// @if CK_DEBUG_TYPING // 'Set DOM fake selection'
|
|
849
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
850
|
+
// @if CK_DEBUG_TYPING // }
|
|
801
851
|
const domSelection = domDocument.getSelection();
|
|
802
852
|
const domRange = domDocument.createRange();
|
|
803
853
|
domSelection.removeAllRanges();
|
|
@@ -813,6 +863,12 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
813
863
|
const domSelection = domRoot.ownerDocument.defaultView.getSelection();
|
|
814
864
|
// Let's check whether DOM selection needs updating at all.
|
|
815
865
|
if (!this._domSelectionNeedsUpdate(domSelection)) {
|
|
866
|
+
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
867
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
868
|
+
// @if CK_DEBUG_TYPING // '%cDOM selection is already correct',
|
|
869
|
+
// @if CK_DEBUG_TYPING // 'font-style: italic;'
|
|
870
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
871
|
+
// @if CK_DEBUG_TYPING // }
|
|
816
872
|
return;
|
|
817
873
|
}
|
|
818
874
|
// Multi-range selection is not available in most browsers, and, at least in Chrome, trying to
|
|
@@ -823,9 +879,11 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
823
879
|
const anchor = this.domConverter.viewPositionToDom(this.selection.anchor);
|
|
824
880
|
const focus = this.domConverter.viewPositionToDom(this.selection.focus);
|
|
825
881
|
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
826
|
-
// @if CK_DEBUG_TYPING // console.info(
|
|
827
|
-
// @if CK_DEBUG_TYPING // '
|
|
828
|
-
// @if CK_DEBUG_TYPING //
|
|
882
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
883
|
+
// @if CK_DEBUG_TYPING // 'Update DOM selection:',
|
|
884
|
+
// @if CK_DEBUG_TYPING // anchor,
|
|
885
|
+
// @if CK_DEBUG_TYPING // focus
|
|
886
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
829
887
|
// @if CK_DEBUG_TYPING // }
|
|
830
888
|
domSelection.setBaseAndExtent(anchor.parent, anchor.offset, focus.parent, focus.offset);
|
|
831
889
|
// Firefox–specific hack (https://github.com/ckeditor/ckeditor5-engine/issues/1439).
|
|
@@ -902,12 +960,26 @@ export default class Renderer extends /* #__PURE__ */ ObservableMixin() {
|
|
|
902
960
|
* Checks if focus needs to be updated and possibly updates it.
|
|
903
961
|
*/
|
|
904
962
|
_updateFocus() {
|
|
963
|
+
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
964
|
+
// @if CK_DEBUG_TYPING // console.group( ..._buildLogMessage( this, 'Renderer',
|
|
965
|
+
// @if CK_DEBUG_TYPING // `update focus: ${ this.isFocused ? 'focused' : 'not focused' }`
|
|
966
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
967
|
+
// @if CK_DEBUG_TYPING // }
|
|
905
968
|
if (this.isFocused) {
|
|
906
969
|
const editable = this.selection.editableElement;
|
|
970
|
+
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
971
|
+
// @if CK_DEBUG_TYPING // console.info( ..._buildLogMessage( this, 'Renderer',
|
|
972
|
+
// @if CK_DEBUG_TYPING // 'focus editable:',
|
|
973
|
+
// @if CK_DEBUG_TYPING // { editable }
|
|
974
|
+
// @if CK_DEBUG_TYPING // ) );
|
|
975
|
+
// @if CK_DEBUG_TYPING // }
|
|
907
976
|
if (editable) {
|
|
908
977
|
this.domConverter.focus(editable);
|
|
909
978
|
}
|
|
910
979
|
}
|
|
980
|
+
// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {
|
|
981
|
+
// @if CK_DEBUG_TYPING // console.groupEnd();
|
|
982
|
+
// @if CK_DEBUG_TYPING // }
|
|
911
983
|
}
|
|
912
984
|
}
|
|
913
985
|
/**
|
package/src/view/selection.js
CHANGED
|
@@ -24,6 +24,22 @@ import { CKEditorError, EmitterMixin, count, isIterable } from '@ckeditor/ckedit
|
|
|
24
24
|
* the {@link module:engine/view/selection~Selection#setTo `Selection#setTo()`} method.
|
|
25
25
|
*/
|
|
26
26
|
export default class Selection extends /* #__PURE__ */ EmitterMixin(TypeCheckable) {
|
|
27
|
+
/**
|
|
28
|
+
* Stores all ranges that are selected.
|
|
29
|
+
*/
|
|
30
|
+
_ranges;
|
|
31
|
+
/**
|
|
32
|
+
* Specifies whether the last added range was added as a backward or forward range.
|
|
33
|
+
*/
|
|
34
|
+
_lastRangeBackward;
|
|
35
|
+
/**
|
|
36
|
+
* Specifies whether selection instance is fake.
|
|
37
|
+
*/
|
|
38
|
+
_isFake;
|
|
39
|
+
/**
|
|
40
|
+
* Fake selection's label.
|
|
41
|
+
*/
|
|
42
|
+
_fakeSelectionLabel;
|
|
27
43
|
/**
|
|
28
44
|
* Creates new selection instance.
|
|
29
45
|
*
|