@ckeditor/ckeditor5-utils 43.2.0 → 43.3.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/dist/focustracker.d.ts +78 -17
- package/dist/index.d.ts +1 -1
- package/dist/index.js +239 -27
- package/dist/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +3 -2
- package/src/focustracker.d.ts +78 -17
- package/src/focustracker.js +251 -22
- package/src/index.d.ts +1 -1
- package/src/index.js +1 -1
- package/src/version.d.ts +1 -1
- package/src/version.js +2 -2
package/dist/focustracker.d.ts
CHANGED
|
@@ -6,12 +6,14 @@
|
|
|
6
6
|
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
7
7
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
|
8
8
|
*/
|
|
9
|
+
import { type View } from '@ckeditor/ckeditor5-ui';
|
|
9
10
|
declare const FocusTracker_base: import("./mix.js").Mixed<{
|
|
10
11
|
new (): import("./observablemixin.js").Observable;
|
|
11
12
|
prototype: import("./observablemixin.js").Observable;
|
|
12
13
|
}, import("./dom/emittermixin.js").DomEmitter>;
|
|
13
14
|
/**
|
|
14
|
-
* Allows observing a group of `Element`s whether at least one of them
|
|
15
|
+
* Allows observing a group of DOM `Element`s or {@link module:ui/view~View view instances} whether at least one of them (or their child)
|
|
16
|
+
* is focused.
|
|
15
17
|
*
|
|
16
18
|
* Used by the {@link module:core/editor/editor~Editor} in order to track whether the focus is still within the application,
|
|
17
19
|
* or were used outside of its UI.
|
|
@@ -24,7 +26,7 @@ declare const FocusTracker_base: import("./mix.js").Mixed<{
|
|
|
24
26
|
*/
|
|
25
27
|
export default class FocusTracker extends /* #__PURE__ */ FocusTracker_base {
|
|
26
28
|
/**
|
|
27
|
-
* True when one of the registered elements is focused.
|
|
29
|
+
* True when one of the registered {@link #elements} or {@link #externalViews} is focused.
|
|
28
30
|
*
|
|
29
31
|
* @readonly
|
|
30
32
|
* @observable
|
|
@@ -33,51 +35,110 @@ export default class FocusTracker extends /* #__PURE__ */ FocusTracker_base {
|
|
|
33
35
|
/**
|
|
34
36
|
* The currently focused element.
|
|
35
37
|
*
|
|
36
|
-
* While {@link #isFocused `isFocused`} remains `true`, the focus can
|
|
37
|
-
* move between different UI elements. This property tracks those
|
|
38
|
+
* While {@link #isFocused `isFocused`} remains `true`, the focus can move between different UI elements. This property tracks those
|
|
38
39
|
* elements and tells which one is currently focused.
|
|
39
40
|
*
|
|
41
|
+
* **Note**: The values of this property are restricted to {@link #elements} or {@link module:ui/view~View#element elements}
|
|
42
|
+
* registered in {@link #externalViews}.
|
|
43
|
+
*
|
|
40
44
|
* @readonly
|
|
41
45
|
* @observable
|
|
42
46
|
*/
|
|
43
47
|
focusedElement: Element | null;
|
|
44
48
|
/**
|
|
45
|
-
* List of registered elements.
|
|
49
|
+
* List of registered DOM elements.
|
|
46
50
|
*
|
|
47
51
|
* @internal
|
|
48
52
|
*/
|
|
49
53
|
_elements: Set<Element>;
|
|
50
54
|
/**
|
|
51
|
-
*
|
|
55
|
+
* List of views with external focus trackers that contribute to the state of this focus tracker.
|
|
56
|
+
*
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
_externalViews: Set<ViewWithFocusTracker>;
|
|
60
|
+
/**
|
|
61
|
+
* Asynchronous blur event timeout.
|
|
52
62
|
*/
|
|
53
|
-
private
|
|
63
|
+
private _blurTimeout;
|
|
54
64
|
constructor();
|
|
55
65
|
/**
|
|
56
|
-
* List of registered elements.
|
|
66
|
+
* List of registered DOM elements.
|
|
67
|
+
*
|
|
68
|
+
* **Note**: The list does do not include elements from {@link #externalViews}.
|
|
57
69
|
*/
|
|
58
70
|
get elements(): Array<Element>;
|
|
59
71
|
/**
|
|
60
|
-
*
|
|
72
|
+
* List of external focusable views that contribute to the state of this focus tracker. See {@link #add} to learn more.
|
|
73
|
+
*/
|
|
74
|
+
get externalViews(): Array<ViewWithFocusTracker>;
|
|
75
|
+
/**
|
|
76
|
+
* Starts tracking a specified DOM element or a {@link module:ui/view~View} instance.
|
|
77
|
+
*
|
|
78
|
+
* * If a DOM element is passed, the focus tracker listens to the `focus` and `blur` events on this element.
|
|
79
|
+
* Tracked elements are listed in {@link #elements}.
|
|
80
|
+
* * If a {@link module:ui/view~View} instance is passed that has a `FocusTracker` instance ({@link ~ViewWithFocusTracker}),
|
|
81
|
+
* the external focus tracker's state ({@link #isFocused}, {@link #focusedElement}) starts contributing to the current tracker instance.
|
|
82
|
+
* This allows for increasing the "reach" of a focus tracker instance, by connecting two or more focus trackers together when DOM
|
|
83
|
+
* elements they track are located in different subtrees in DOM. External focus trackers are listed in {@link #externalViews}.
|
|
84
|
+
* * If a {@link module:ui/view~View} instance is passed that has no `FocusTracker` (**not** a {@link ~ViewWithFocusTracker}),
|
|
85
|
+
* its {@link module:ui/view~View#element} is used to track focus like any other DOM element.
|
|
86
|
+
*/
|
|
87
|
+
add(elementOrView: Element | View): void;
|
|
88
|
+
/**
|
|
89
|
+
* Stops tracking focus in the specified DOM element or a {@link module:ui/view~View view instance}. See {@link #add} to learn more.
|
|
90
|
+
*/
|
|
91
|
+
remove(elementOrView: Element | View): void;
|
|
92
|
+
/**
|
|
93
|
+
* Adds a DOM element to the focus tracker and starts listening to the `focus` and `blur` events on it.
|
|
94
|
+
*/
|
|
95
|
+
private _addElement;
|
|
96
|
+
/**
|
|
97
|
+
* Removes a DOM element from the focus tracker.
|
|
61
98
|
*/
|
|
62
|
-
|
|
99
|
+
private _removeElement;
|
|
63
100
|
/**
|
|
64
|
-
*
|
|
101
|
+
* Adds an external {@link module:ui/view~View view instance} to this focus tracker and makes it contribute to this focus tracker's
|
|
102
|
+
* state either by its `View#element` or by its `View#focusTracker` instance.
|
|
65
103
|
*/
|
|
66
|
-
|
|
104
|
+
private _addView;
|
|
105
|
+
/**
|
|
106
|
+
* Removes an external {@link module:ui/view~View view instance} from this focus tracker.
|
|
107
|
+
*/
|
|
108
|
+
private _removeView;
|
|
67
109
|
/**
|
|
68
110
|
* Destroys the focus tracker by:
|
|
69
|
-
* - Disabling all event listeners attached to tracked elements.
|
|
70
|
-
* - Removing all tracked elements that were previously added.
|
|
111
|
+
* - Disabling all event listeners attached to tracked elements or external views.
|
|
112
|
+
* - Removing all tracked elements and views that were previously added.
|
|
71
113
|
*/
|
|
72
114
|
destroy(): void;
|
|
73
115
|
/**
|
|
74
|
-
* Stores currently focused element and
|
|
116
|
+
* Stores currently focused element as {@link #focusedElement} and sets {@link #isFocused} `true`.
|
|
75
117
|
*/
|
|
76
118
|
private _focus;
|
|
77
119
|
/**
|
|
78
|
-
* Clears currently
|
|
79
|
-
*
|
|
120
|
+
* Clears currently {@link #focusedElement} and sets {@link #isFocused} `false`.
|
|
121
|
+
*
|
|
122
|
+
* This method uses `setTimeout()` to change order of `blur` and `focus` events calls, ensuring that moving focus between
|
|
123
|
+
* two elements within a single focus tracker's scope, will not cause `[ blurA, focusB ]` sequence but just `[ focusB ]`.
|
|
124
|
+
* The former would cause a momentary change of `#isFocused` to `false` which is not desired because any logic listening to
|
|
125
|
+
* a focus tracker state would experience UI flashes and glitches as the user focus travels across the UI.
|
|
80
126
|
*/
|
|
81
127
|
private _blur;
|
|
128
|
+
/**
|
|
129
|
+
* Clears the asynchronous blur event timeout on demand. See {@link #_blur} to learn more.
|
|
130
|
+
*/
|
|
131
|
+
private _clearBlurTimeout;
|
|
82
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* A {@link module:ui/view~View} instance with a {@link module:utils/focustracker~FocusTracker} instance exposed
|
|
135
|
+
* at the `#focusTracker` property.
|
|
136
|
+
*/
|
|
137
|
+
export type ViewWithFocusTracker = View & {
|
|
138
|
+
focusTracker: FocusTracker;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Checks whether a view is an instance of {@link ~ViewWithFocusTracker}.
|
|
142
|
+
*/
|
|
143
|
+
export declare function isViewWithFocusTracker(view: any): view is ViewWithFocusTracker;
|
|
83
144
|
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -53,7 +53,7 @@ export * from './language.js';
|
|
|
53
53
|
export { default as Locale, type LocaleTranslate, type Translations } from './locale.js';
|
|
54
54
|
export { default as Collection, type CollectionAddEvent, type CollectionChangeEvent, type CollectionRemoveEvent } from './collection.js';
|
|
55
55
|
export { default as first } from './first.js';
|
|
56
|
-
export { default as FocusTracker } from './focustracker.js';
|
|
56
|
+
export { default as FocusTracker, type ViewWithFocusTracker, isViewWithFocusTracker } from './focustracker.js';
|
|
57
57
|
export { default as KeystrokeHandler, type KeystrokeHandlerOptions } from './keystrokehandler.js';
|
|
58
58
|
export { default as toArray, type ArrayOrItem, type ReadonlyArrayOrItem } from './toarray.js';
|
|
59
59
|
export { default as toMap } from './tomap.js';
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @license Copyright (c) 2003-2024, 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
|
-
import { isObject, isString, isPlainObject, cloneDeepWith, isElement, isFunction, merge } from 'lodash-es';
|
|
5
|
+
import { isObject, isString, isPlainObject, cloneDeepWith, isElement as isElement$1, isFunction, merge } from 'lodash-es';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
@@ -953,9 +953,9 @@ diff.fastDiff = fastDiff;
|
|
|
953
953
|
];
|
|
954
954
|
}
|
|
955
955
|
|
|
956
|
-
const version = '43.
|
|
956
|
+
const version = '43.3.0-alpha.1';
|
|
957
957
|
// The second argument is not a month. It is `monthIndex` and starts from `0`.
|
|
958
|
-
const releaseDate = new Date(2024, 9,
|
|
958
|
+
const releaseDate = new Date(2024, 9, 25);
|
|
959
959
|
/* istanbul ignore next -- @preserve */ if (globalThis.CKEDITOR_VERSION) {
|
|
960
960
|
/**
|
|
961
961
|
* This error is thrown when, due to a mistake in the way CKEditor 5 was installed,
|
|
@@ -2449,7 +2449,7 @@ function initObservable(observable) {
|
|
|
2449
2449
|
* In case if it's a DOM Element it will leave references to DOM Elements instead of cloning them.
|
|
2450
2450
|
* If it's a function it will leave reference to actuall function.
|
|
2451
2451
|
*/ function leaveItemReferences(value) {
|
|
2452
|
-
return isElement(value) || typeof value === 'function' ? value : undefined;
|
|
2452
|
+
return isElement$1(value) || typeof value === 'function' ? value : undefined;
|
|
2453
2453
|
}
|
|
2454
2454
|
|
|
2455
2455
|
/**
|
|
@@ -5343,7 +5343,8 @@ function getNumberOfLanguages(translations) {
|
|
|
5343
5343
|
}
|
|
5344
5344
|
|
|
5345
5345
|
/**
|
|
5346
|
-
* Allows observing a group of `Element`s whether at least one of them
|
|
5346
|
+
* Allows observing a group of DOM `Element`s or {@link module:ui/view~View view instances} whether at least one of them (or their child)
|
|
5347
|
+
* is focused.
|
|
5347
5348
|
*
|
|
5348
5349
|
* Used by the {@link module:core/editor/editor~Editor} in order to track whether the focus is still within the application,
|
|
5349
5350
|
* or were used outside of its UI.
|
|
@@ -5355,26 +5356,88 @@ function getNumberOfLanguages(translations) {
|
|
|
5355
5356
|
* Check out the {@glink framework/deep-dive/ui/focus-tracking "Deep dive into focus tracking"} guide to learn more.
|
|
5356
5357
|
*/ class FocusTracker extends /* #__PURE__ */ DomEmitterMixin(/* #__PURE__ */ ObservableMixin()) {
|
|
5357
5358
|
/**
|
|
5358
|
-
* List of registered elements.
|
|
5359
|
+
* List of registered DOM elements.
|
|
5359
5360
|
*
|
|
5360
5361
|
* @internal
|
|
5361
5362
|
*/ _elements = new Set();
|
|
5362
5363
|
/**
|
|
5363
|
-
*
|
|
5364
|
-
|
|
5364
|
+
* List of views with external focus trackers that contribute to the state of this focus tracker.
|
|
5365
|
+
*
|
|
5366
|
+
* @internal
|
|
5367
|
+
*/ _externalViews = new Set();
|
|
5368
|
+
/**
|
|
5369
|
+
* Asynchronous blur event timeout.
|
|
5370
|
+
*/ _blurTimeout = null;
|
|
5371
|
+
// @if CK_DEBUG_FOCUSTRACKER // public _label?: string;
|
|
5365
5372
|
constructor(){
|
|
5366
5373
|
super();
|
|
5367
5374
|
this.set('isFocused', false);
|
|
5368
5375
|
this.set('focusedElement', null);
|
|
5376
|
+
// @if CK_DEBUG_FOCUSTRACKER // FocusTracker._instances.push( this );
|
|
5369
5377
|
}
|
|
5370
5378
|
/**
|
|
5371
|
-
* List of registered elements.
|
|
5379
|
+
* List of registered DOM elements.
|
|
5380
|
+
*
|
|
5381
|
+
* **Note**: The list does do not include elements from {@link #externalViews}.
|
|
5372
5382
|
*/ get elements() {
|
|
5373
5383
|
return Array.from(this._elements.values());
|
|
5374
5384
|
}
|
|
5375
5385
|
/**
|
|
5376
|
-
*
|
|
5377
|
-
*/
|
|
5386
|
+
* List of external focusable views that contribute to the state of this focus tracker. See {@link #add} to learn more.
|
|
5387
|
+
*/ get externalViews() {
|
|
5388
|
+
return Array.from(this._externalViews.values());
|
|
5389
|
+
}
|
|
5390
|
+
/**
|
|
5391
|
+
* Starts tracking a specified DOM element or a {@link module:ui/view~View} instance.
|
|
5392
|
+
*
|
|
5393
|
+
* * If a DOM element is passed, the focus tracker listens to the `focus` and `blur` events on this element.
|
|
5394
|
+
* Tracked elements are listed in {@link #elements}.
|
|
5395
|
+
* * If a {@link module:ui/view~View} instance is passed that has a `FocusTracker` instance ({@link ~ViewWithFocusTracker}),
|
|
5396
|
+
* the external focus tracker's state ({@link #isFocused}, {@link #focusedElement}) starts contributing to the current tracker instance.
|
|
5397
|
+
* This allows for increasing the "reach" of a focus tracker instance, by connecting two or more focus trackers together when DOM
|
|
5398
|
+
* elements they track are located in different subtrees in DOM. External focus trackers are listed in {@link #externalViews}.
|
|
5399
|
+
* * If a {@link module:ui/view~View} instance is passed that has no `FocusTracker` (**not** a {@link ~ViewWithFocusTracker}),
|
|
5400
|
+
* its {@link module:ui/view~View#element} is used to track focus like any other DOM element.
|
|
5401
|
+
*/ add(elementOrView) {
|
|
5402
|
+
if (isElement(elementOrView)) {
|
|
5403
|
+
this._addElement(elementOrView);
|
|
5404
|
+
} else {
|
|
5405
|
+
if (isViewWithFocusTracker(elementOrView)) {
|
|
5406
|
+
this._addView(elementOrView);
|
|
5407
|
+
} else {
|
|
5408
|
+
if (!elementOrView.element) {
|
|
5409
|
+
/**
|
|
5410
|
+
* The {@link module:ui/view~View} added to the {@link module:utils/focustracker~FocusTracker} does not have an
|
|
5411
|
+
* {@link module:ui/view~View#element}. Make sure the view is {@link module:ui/view~View#render} before adding
|
|
5412
|
+
* it to the focus tracker.
|
|
5413
|
+
*
|
|
5414
|
+
* @error focustracker-add-view-missing-element
|
|
5415
|
+
*/ throw new CKEditorError('focustracker-add-view-missing-element', {
|
|
5416
|
+
focusTracker: this,
|
|
5417
|
+
view: elementOrView
|
|
5418
|
+
});
|
|
5419
|
+
}
|
|
5420
|
+
this._addElement(elementOrView.element);
|
|
5421
|
+
}
|
|
5422
|
+
}
|
|
5423
|
+
}
|
|
5424
|
+
/**
|
|
5425
|
+
* Stops tracking focus in the specified DOM element or a {@link module:ui/view~View view instance}. See {@link #add} to learn more.
|
|
5426
|
+
*/ remove(elementOrView) {
|
|
5427
|
+
if (isElement(elementOrView)) {
|
|
5428
|
+
this._removeElement(elementOrView);
|
|
5429
|
+
} else {
|
|
5430
|
+
if (isViewWithFocusTracker(elementOrView)) {
|
|
5431
|
+
this._removeView(elementOrView);
|
|
5432
|
+
} else {
|
|
5433
|
+
// Assuming that if the view was successfully added, it must have come with an existing #element.
|
|
5434
|
+
this._removeElement(elementOrView.element);
|
|
5435
|
+
}
|
|
5436
|
+
}
|
|
5437
|
+
}
|
|
5438
|
+
/**
|
|
5439
|
+
* Adds a DOM element to the focus tracker and starts listening to the `focus` and `blur` events on it.
|
|
5440
|
+
*/ _addElement(element) {
|
|
5378
5441
|
if (this._elements.has(element)) {
|
|
5379
5442
|
/**
|
|
5380
5443
|
* This element is already tracked by {@link module:utils/focustracker~FocusTracker}.
|
|
@@ -5382,50 +5445,199 @@ function getNumberOfLanguages(translations) {
|
|
|
5382
5445
|
* @error focustracker-add-element-already-exist
|
|
5383
5446
|
*/ throw new CKEditorError('focustracker-add-element-already-exist', this);
|
|
5384
5447
|
}
|
|
5385
|
-
this.listenTo(element, 'focus', ()=>
|
|
5448
|
+
this.listenTo(element, 'focus', ()=>{
|
|
5449
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.log( `"${ getName( this ) }": Focus with useCapture on DOM element` );
|
|
5450
|
+
const externalFocusedViewInSubtree = this.externalViews.find((view)=>isExternalViewSubtreeFocused(element, view));
|
|
5451
|
+
if (externalFocusedViewInSubtree) {
|
|
5452
|
+
this._focus(externalFocusedViewInSubtree.element);
|
|
5453
|
+
} else {
|
|
5454
|
+
this._focus(element);
|
|
5455
|
+
}
|
|
5456
|
+
}, {
|
|
5386
5457
|
useCapture: true
|
|
5387
5458
|
});
|
|
5388
|
-
this.listenTo(element, 'blur', ()=>
|
|
5459
|
+
this.listenTo(element, 'blur', ()=>{
|
|
5460
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.log( `"${ getName( this ) }": Blur with useCapture on DOM element` );
|
|
5461
|
+
this._blur();
|
|
5462
|
+
}, {
|
|
5389
5463
|
useCapture: true
|
|
5390
5464
|
});
|
|
5391
5465
|
this._elements.add(element);
|
|
5392
5466
|
}
|
|
5393
5467
|
/**
|
|
5394
|
-
*
|
|
5395
|
-
*/
|
|
5396
|
-
if (element === this.focusedElement) {
|
|
5397
|
-
this._blur();
|
|
5398
|
-
}
|
|
5468
|
+
* Removes a DOM element from the focus tracker.
|
|
5469
|
+
*/ _removeElement(element) {
|
|
5399
5470
|
if (this._elements.has(element)) {
|
|
5400
5471
|
this.stopListening(element);
|
|
5401
5472
|
this._elements.delete(element);
|
|
5402
5473
|
}
|
|
5474
|
+
if (element === this.focusedElement) {
|
|
5475
|
+
this._blur();
|
|
5476
|
+
}
|
|
5477
|
+
}
|
|
5478
|
+
/**
|
|
5479
|
+
* Adds an external {@link module:ui/view~View view instance} to this focus tracker and makes it contribute to this focus tracker's
|
|
5480
|
+
* state either by its `View#element` or by its `View#focusTracker` instance.
|
|
5481
|
+
*/ _addView(view) {
|
|
5482
|
+
if (view.element) {
|
|
5483
|
+
this._addElement(view.element);
|
|
5484
|
+
}
|
|
5485
|
+
this.listenTo(view.focusTracker, 'change:focusedElement', ()=>{
|
|
5486
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.log(
|
|
5487
|
+
// @if CK_DEBUG_FOCUSTRACKER // `"${ getName( this ) }": Related "${ getName( view.focusTracker ) }"#focusedElement = `,
|
|
5488
|
+
// @if CK_DEBUG_FOCUSTRACKER // view.focusTracker.focusedElement
|
|
5489
|
+
// @if CK_DEBUG_FOCUSTRACKER // );
|
|
5490
|
+
if (view.focusTracker.focusedElement) {
|
|
5491
|
+
if (view.element) {
|
|
5492
|
+
this._focus(view.element);
|
|
5493
|
+
}
|
|
5494
|
+
} else {
|
|
5495
|
+
this._blur();
|
|
5496
|
+
}
|
|
5497
|
+
});
|
|
5498
|
+
this._externalViews.add(view);
|
|
5499
|
+
}
|
|
5500
|
+
/**
|
|
5501
|
+
* Removes an external {@link module:ui/view~View view instance} from this focus tracker.
|
|
5502
|
+
*/ _removeView(view) {
|
|
5503
|
+
if (view.element) {
|
|
5504
|
+
this._removeElement(view.element);
|
|
5505
|
+
}
|
|
5506
|
+
this.stopListening(view.focusTracker);
|
|
5507
|
+
this._externalViews.delete(view);
|
|
5403
5508
|
}
|
|
5404
5509
|
/**
|
|
5405
5510
|
* Destroys the focus tracker by:
|
|
5406
|
-
* - Disabling all event listeners attached to tracked elements.
|
|
5407
|
-
* - Removing all tracked elements that were previously added.
|
|
5511
|
+
* - Disabling all event listeners attached to tracked elements or external views.
|
|
5512
|
+
* - Removing all tracked elements and views that were previously added.
|
|
5408
5513
|
*/ destroy() {
|
|
5409
5514
|
this.stopListening();
|
|
5515
|
+
this._elements.clear();
|
|
5516
|
+
this._externalViews.clear();
|
|
5517
|
+
this.isFocused = false;
|
|
5518
|
+
this.focusedElement = null;
|
|
5410
5519
|
}
|
|
5411
5520
|
/**
|
|
5412
|
-
* Stores currently focused element and
|
|
5521
|
+
* Stores currently focused element as {@link #focusedElement} and sets {@link #isFocused} `true`.
|
|
5413
5522
|
*/ _focus(element) {
|
|
5414
|
-
|
|
5523
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.log( `"${ getName( this ) }": _focus() on element`, element );
|
|
5524
|
+
this._clearBlurTimeout();
|
|
5415
5525
|
this.focusedElement = element;
|
|
5416
5526
|
this.isFocused = true;
|
|
5417
5527
|
}
|
|
5418
5528
|
/**
|
|
5419
|
-
* Clears currently
|
|
5420
|
-
*
|
|
5529
|
+
* Clears currently {@link #focusedElement} and sets {@link #isFocused} `false`.
|
|
5530
|
+
*
|
|
5531
|
+
* This method uses `setTimeout()` to change order of `blur` and `focus` events calls, ensuring that moving focus between
|
|
5532
|
+
* two elements within a single focus tracker's scope, will not cause `[ blurA, focusB ]` sequence but just `[ focusB ]`.
|
|
5533
|
+
* The former would cause a momentary change of `#isFocused` to `false` which is not desired because any logic listening to
|
|
5534
|
+
* a focus tracker state would experience UI flashes and glitches as the user focus travels across the UI.
|
|
5421
5535
|
*/ _blur() {
|
|
5422
|
-
|
|
5423
|
-
|
|
5536
|
+
const isAnyElementFocused = this.elements.find((element)=>element.contains(document.activeElement));
|
|
5537
|
+
// Avoid blurs originating from external FTs when the focus still remains in one of the #elements.
|
|
5538
|
+
if (isAnyElementFocused) {
|
|
5539
|
+
return;
|
|
5540
|
+
}
|
|
5541
|
+
const isAnyExternalViewFocused = this.externalViews.find((view)=>{
|
|
5542
|
+
// Do not consider external views's focus trackers as focused if there's a blur timeout pending.
|
|
5543
|
+
return view.focusTracker.isFocused && !view.focusTracker._blurTimeout;
|
|
5544
|
+
});
|
|
5545
|
+
// Avoid unnecessary DOM blurs coming from #elements when the focus still remains in one of #externalViews.
|
|
5546
|
+
if (isAnyExternalViewFocused) {
|
|
5547
|
+
return;
|
|
5548
|
+
}
|
|
5549
|
+
this._clearBlurTimeout();
|
|
5550
|
+
this._blurTimeout = setTimeout(()=>{
|
|
5551
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.log( `"${ getName( this ) }": Blur.` );
|
|
5424
5552
|
this.focusedElement = null;
|
|
5425
5553
|
this.isFocused = false;
|
|
5426
5554
|
}, 0);
|
|
5427
5555
|
}
|
|
5556
|
+
/**
|
|
5557
|
+
* Clears the asynchronous blur event timeout on demand. See {@link #_blur} to learn more.
|
|
5558
|
+
*/ _clearBlurTimeout() {
|
|
5559
|
+
clearTimeout(this._blurTimeout);
|
|
5560
|
+
this._blurTimeout = null;
|
|
5561
|
+
}
|
|
5562
|
+
}
|
|
5563
|
+
/**
|
|
5564
|
+
* Checks whether a view is an instance of {@link ~ViewWithFocusTracker}.
|
|
5565
|
+
*/ function isViewWithFocusTracker(view) {
|
|
5566
|
+
return 'focusTracker' in view && view.focusTracker instanceof FocusTracker;
|
|
5428
5567
|
}
|
|
5568
|
+
function isElement(value) {
|
|
5569
|
+
return isElement$1(value);
|
|
5570
|
+
}
|
|
5571
|
+
function isExternalViewSubtreeFocused(subTreeRoot, view) {
|
|
5572
|
+
if (isFocusedView(subTreeRoot, view)) {
|
|
5573
|
+
return true;
|
|
5574
|
+
}
|
|
5575
|
+
return !!view.focusTracker.externalViews.find((view)=>isFocusedView(subTreeRoot, view));
|
|
5576
|
+
}
|
|
5577
|
+
function isFocusedView(subTreeRoot, view) {
|
|
5578
|
+
// Note: You cannot depend on externalView.focusTracker.focusedElement because blurs are asynchronous and the value may
|
|
5579
|
+
// be outdated when moving focus between two elements. Using document.activeElement instead.
|
|
5580
|
+
return !!view.element && view.element.contains(document.activeElement) && subTreeRoot.contains(view.element);
|
|
5581
|
+
} // @if CK_DEBUG_FOCUSTRACKER // declare global {
|
|
5582
|
+
// @if CK_DEBUG_FOCUSTRACKER // interface Window {
|
|
5583
|
+
// @if CK_DEBUG_FOCUSTRACKER // logFocusTrackers: Function;
|
|
5584
|
+
// @if CK_DEBUG_FOCUSTRACKER // }
|
|
5585
|
+
// @if CK_DEBUG_FOCUSTRACKER // }
|
|
5586
|
+
// @if CK_DEBUG_FOCUSTRACKER //
|
|
5587
|
+
// @if CK_DEBUG_FOCUSTRACKER // function getName( focusTracker: FocusTracker ): string {
|
|
5588
|
+
// @if CK_DEBUG_FOCUSTRACKER // return focusTracker._label || 'Unknown';
|
|
5589
|
+
// @if CK_DEBUG_FOCUSTRACKER // }
|
|
5590
|
+
// @if CK_DEBUG_FOCUSTRACKER //
|
|
5591
|
+
// @if CK_DEBUG_FOCUSTRACKER // function logState(
|
|
5592
|
+
// @if CK_DEBUG_FOCUSTRACKER // focusTracker: FocusTracker,
|
|
5593
|
+
// @if CK_DEBUG_FOCUSTRACKER // keysToLog: Array<string> = [ 'isFocused', 'focusedElement' ]
|
|
5594
|
+
// @if CK_DEBUG_FOCUSTRACKER // ): string {
|
|
5595
|
+
// @if CK_DEBUG_FOCUSTRACKER // keysToLog.forEach( key => { console.log( `${ key }=`, focusTracker[ key ] ) } );
|
|
5596
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.log( 'elements', focusTracker.elements );
|
|
5597
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.log( 'externalViews', focusTracker.externalViews );
|
|
5598
|
+
// @if CK_DEBUG_FOCUSTRACKER // }
|
|
5599
|
+
// @if CK_DEBUG_FOCUSTRACKER //
|
|
5600
|
+
// @if CK_DEBUG_FOCUSTRACKER // window.logFocusTrackers = (
|
|
5601
|
+
// @if CK_DEBUG_FOCUSTRACKER // filter = () => true,
|
|
5602
|
+
// @if CK_DEBUG_FOCUSTRACKER // keysToLog: Array<string>
|
|
5603
|
+
// @if CK_DEBUG_FOCUSTRACKER // ): void => {
|
|
5604
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.group( 'FocusTrackers' );
|
|
5605
|
+
// @if CK_DEBUG_FOCUSTRACKER //
|
|
5606
|
+
// @if CK_DEBUG_FOCUSTRACKER // for ( const focusTracker of FocusTracker._instances ) {
|
|
5607
|
+
// @if CK_DEBUG_FOCUSTRACKER // if ( filter( focusTracker ) ) {
|
|
5608
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.group( `"${ getName( focusTracker ) }"` );
|
|
5609
|
+
// @if CK_DEBUG_FOCUSTRACKER // logState( focusTracker, keysToLog );
|
|
5610
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.groupEnd();
|
|
5611
|
+
// @if CK_DEBUG_FOCUSTRACKER // }
|
|
5612
|
+
// @if CK_DEBUG_FOCUSTRACKER // }
|
|
5613
|
+
// @if CK_DEBUG_FOCUSTRACKER //
|
|
5614
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.groupEnd();
|
|
5615
|
+
// @if CK_DEBUG_FOCUSTRACKER // };
|
|
5616
|
+
// @if CK_DEBUG_FOCUSTRACKER //
|
|
5617
|
+
// @if CK_DEBUG_FOCUSTRACKER // window.logFocusTrackerTree = (
|
|
5618
|
+
// @if CK_DEBUG_FOCUSTRACKER // rootFocusTracker: FocusTracker,
|
|
5619
|
+
// @if CK_DEBUG_FOCUSTRACKER // filter = () => true,
|
|
5620
|
+
// @if CK_DEBUG_FOCUSTRACKER // keysToLog: Array<string>
|
|
5621
|
+
// @if CK_DEBUG_FOCUSTRACKER // ): void => {
|
|
5622
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.group( 'FocusTrackers tree' );
|
|
5623
|
+
// @if CK_DEBUG_FOCUSTRACKER //
|
|
5624
|
+
// @if CK_DEBUG_FOCUSTRACKER // logBranch( rootFocusTracker, filter );
|
|
5625
|
+
// @if CK_DEBUG_FOCUSTRACKER //
|
|
5626
|
+
// @if CK_DEBUG_FOCUSTRACKER // function logBranch( focusTracker, filter ) {
|
|
5627
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.group( `"${ getName( focusTracker ) }"` );
|
|
5628
|
+
// @if CK_DEBUG_FOCUSTRACKER // logState( focusTracker, keysToLog );
|
|
5629
|
+
// @if CK_DEBUG_FOCUSTRACKER //
|
|
5630
|
+
// @if CK_DEBUG_FOCUSTRACKER // for ( const externalView of focusTracker.externalViews ) {
|
|
5631
|
+
// @if CK_DEBUG_FOCUSTRACKER // if ( filter( externalView.focusTracker ) ) {
|
|
5632
|
+
// @if CK_DEBUG_FOCUSTRACKER // logBranch( externalView.focusTracker, filter );
|
|
5633
|
+
// @if CK_DEBUG_FOCUSTRACKER // }
|
|
5634
|
+
// @if CK_DEBUG_FOCUSTRACKER // }
|
|
5635
|
+
// @if CK_DEBUG_FOCUSTRACKER //
|
|
5636
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.groupEnd();
|
|
5637
|
+
// @if CK_DEBUG_FOCUSTRACKER // }
|
|
5638
|
+
// @if CK_DEBUG_FOCUSTRACKER //
|
|
5639
|
+
// @if CK_DEBUG_FOCUSTRACKER // console.groupEnd();
|
|
5640
|
+
// @if CK_DEBUG_FOCUSTRACKER // };
|
|
5429
5641
|
|
|
5430
5642
|
/**
|
|
5431
5643
|
* Keystroke handler allows registering callbacks for given keystrokes.
|
|
@@ -5863,5 +6075,5 @@ function buildEmojiRegexp() {
|
|
|
5863
6075
|
return new RegExp(sequence, 'ug');
|
|
5864
6076
|
}
|
|
5865
6077
|
|
|
5866
|
-
export { CKEditorError, Collection, Config, DomEmitterMixin, ElementReplacer, EmitterMixin, EventInfo, FocusTracker, KeystrokeHandler, Locale, ObservableMixin, Rect, ResizeObserver, abortableDebounce, compareArrays, count, createElement, delay, diff, diffToChanges, env, exponentialDelay, fastDiff, findClosestScrollableAncestor, first, getAncestors, getBorderWidths, getCode, getDataFromElement, getEnvKeystrokeText, getLanguageDirection, getLocalizedArrowKeyCodeDirection, getOptimalPosition, getRangeFromMouseEvent, global, indexOf, insertAt, insertToPriorityArray, isArrowKeyCode, isCombiningMark, isComment, isForwardArrowKeyCode, isHighSurrogateHalf, isInsideCombinedSymbol, isInsideEmojiSequence, isInsideSurrogatePair, isIterable, isLowSurrogateHalf, isNode, isRange, isText, isValidAttributeName, isVisible, keyCodes, logError, logWarning, mix, parseKeystroke, priorities, releaseDate, remove, retry, scrollAncestorsToShowTarget, scrollViewportToShowTarget, setDataInElement, spliceArray, toArray, toMap, toUnit, uid, verifyLicense, version, wait };
|
|
6078
|
+
export { CKEditorError, Collection, Config, DomEmitterMixin, ElementReplacer, EmitterMixin, EventInfo, FocusTracker, KeystrokeHandler, Locale, ObservableMixin, Rect, ResizeObserver, abortableDebounce, compareArrays, count, createElement, delay, diff, diffToChanges, env, exponentialDelay, fastDiff, findClosestScrollableAncestor, first, getAncestors, getBorderWidths, getCode, getDataFromElement, getEnvKeystrokeText, getLanguageDirection, getLocalizedArrowKeyCodeDirection, getOptimalPosition, getRangeFromMouseEvent, global, indexOf, insertAt, insertToPriorityArray, isArrowKeyCode, isCombiningMark, isComment, isForwardArrowKeyCode, isHighSurrogateHalf, isInsideCombinedSymbol, isInsideEmojiSequence, isInsideSurrogatePair, isIterable, isLowSurrogateHalf, isNode, isRange, isText, isValidAttributeName, isViewWithFocusTracker, isVisible, keyCodes, logError, logWarning, mix, parseKeystroke, priorities, releaseDate, remove, retry, scrollAncestorsToShowTarget, scrollViewportToShowTarget, setDataInElement, spliceArray, toArray, toMap, toUnit, uid, verifyLicense, version, wait };
|
|
5867
6079
|
//# sourceMappingURL=index.js.map
|