@@ -3,25 +3,47 @@ import EventManager from './EventManager';
3
3
import { PointerType } from '../../PointerType' ;
4
4
5
5
export default class KeyboardEventManager extends EventManager < HTMLElement > {
6
- private activationKeys = [ 'Enter' , ' ' ] ;
7
- private cancelationKeys = [ 'Tab' ] ;
6
+ private static activationKeys = [ 'Enter' , ' ' ] ;
7
+ private static cancelationKeys = [ 'Tab' ] ;
8
8
private isPressed = false ;
9
+ private static registeredStaticListeners = false ;
10
+ private static instances : Set < KeyboardEventManager > = new Set ( ) ;
11
+
12
+ private static keyUpStaticCallback = ( event : KeyboardEvent ) : void => {
13
+ // We need a global listener, as in some cases, keyUp event gets stop-propagated.
14
+ // Then, if we used only component-level listeners the gesture would never end,
15
+ // causing other gestues to fail.
16
+
17
+ if ( this . activationKeys . indexOf ( event . key ) === - 1 ) {
18
+ return ;
19
+ }
20
+
21
+ this . instances . forEach ( ( item ) => {
22
+ item . onKeyUp ( event ) ;
23
+ } ) ;
24
+ } ;
9
25
10
26
private keyDownCallback = ( event : KeyboardEvent ) : void => {
11
- if ( this . cancelationKeys . indexOf ( event . key ) !== - 1 && this . isPressed ) {
27
+ if (
28
+ KeyboardEventManager . cancelationKeys . indexOf ( event . key ) !== - 1 &&
29
+ this . isPressed
30
+ ) {
12
31
this . dispatchEvent ( event , EventTypes . CANCEL ) ;
13
32
return ;
14
33
}
15
34
16
- if ( this . activationKeys . indexOf ( event . key ) === - 1 ) {
35
+ if ( KeyboardEventManager . activationKeys . indexOf ( event . key ) === - 1 ) {
17
36
return ;
18
37
}
19
38
20
39
this . dispatchEvent ( event , EventTypes . DOWN ) ;
21
40
} ;
22
41
23
- private keyUpCallback = ( event : KeyboardEvent ) : void => {
24
- if ( this . activationKeys . indexOf ( event . key ) === - 1 || ! this . isPressed ) {
42
+ private onKeyUp = ( event : KeyboardEvent ) : void => {
43
+ if (
44
+ KeyboardEventManager . activationKeys . indexOf ( event . key ) === - 1 ||
45
+ ! this . isPressed
46
+ ) {
25
47
return ;
26
48
}
27
49
@@ -53,12 +75,32 @@ export default class KeyboardEventManager extends EventManager<HTMLElement> {
53
75
54
76
public registerListeners ( ) : void {
55
77
this . view . addEventListener ( 'keydown' , this . keyDownCallback ) ;
56
- this . view . addEventListener ( 'keyup' , this . keyUpCallback ) ;
78
+
79
+ KeyboardEventManager . instances . add ( this ) ;
80
+
81
+ if ( ! KeyboardEventManager . registeredStaticListeners ) {
82
+ KeyboardEventManager . registeredStaticListeners = true ;
83
+ document . addEventListener (
84
+ 'keyup' ,
85
+ KeyboardEventManager . keyUpStaticCallback ,
86
+ { capture : true }
87
+ ) ;
88
+ }
57
89
}
58
90
59
91
public unregisterListeners ( ) : void {
60
92
this . view . removeEventListener ( 'keydown' , this . keyDownCallback ) ;
61
- this . view . removeEventListener ( 'keyup' , this . keyUpCallback ) ;
93
+
94
+ KeyboardEventManager . instances . delete ( this ) ;
95
+
96
+ if ( KeyboardEventManager . instances . size === 0 ) {
97
+ document . removeEventListener (
98
+ 'keyup' ,
99
+ KeyboardEventManager . keyUpStaticCallback ,
100
+ { capture : true }
101
+ ) ;
102
+ KeyboardEventManager . registeredStaticListeners = false ;
103
+ }
62
104
}
63
105
64
106
protected mapEvent (
0 commit comments