8
8
9
9
import { Injectable , Inject , InjectionToken , Optional , SkipSelf , OnDestroy } from '@angular/core' ;
10
10
import { OverlayRef } from '../overlay-ref' ;
11
- import { Subscription } from 'rxjs/Subscription' ;
12
- import { filter } from 'rxjs/operators/filter' ;
13
- import { fromEvent } from 'rxjs/observable/fromEvent' ;
14
11
import { DOCUMENT } from '@angular/common' ;
15
12
16
13
/**
@@ -24,19 +21,23 @@ export class OverlayKeyboardDispatcher implements OnDestroy {
24
21
/** Currently attached overlays in the order they were attached. */
25
22
_attachedOverlays : OverlayRef [ ] = [ ] ;
26
23
27
- private _keydownEventSubscription : Subscription | null ;
24
+ private _document : Document ;
25
+ private _isAttached : boolean ;
28
26
29
- constructor ( @Inject ( DOCUMENT ) private _document : any ) { }
27
+ constructor ( @Inject ( DOCUMENT ) document : any ) {
28
+ this . _document = document ;
29
+ }
30
30
31
31
ngOnDestroy ( ) {
32
- this . _unsubscribeFromKeydownEvents ( ) ;
32
+ this . _detach ( ) ;
33
33
}
34
34
35
35
/** Add a new overlay to the list of attached overlay refs. */
36
36
add ( overlayRef : OverlayRef ) : void {
37
37
// Lazily start dispatcher once first overlay is added
38
- if ( ! this . _keydownEventSubscription ) {
39
- this . _subscribeToKeydownEvents ( ) ;
38
+ if ( ! this . _isAttached ) {
39
+ this . _document . body . addEventListener ( 'keydown' , this . _keydownListener , true ) ;
40
+ this . _isAttached = true ;
40
41
}
41
42
42
43
this . _attachedOverlays . push ( overlayRef ) ;
@@ -52,30 +53,7 @@ export class OverlayKeyboardDispatcher implements OnDestroy {
52
53
53
54
// Remove the global listener once there are no more overlays.
54
55
if ( this . _attachedOverlays . length === 0 ) {
55
- this . _unsubscribeFromKeydownEvents ( ) ;
56
- }
57
- }
58
-
59
- /**
60
- * Subscribe to keydown events that land on the body and dispatch those
61
- * events to the appropriate overlay.
62
- */
63
- private _subscribeToKeydownEvents ( ) : void {
64
- const bodyKeydownEvents = fromEvent < KeyboardEvent > ( this . _document . body , 'keydown' , true ) ;
65
-
66
- this . _keydownEventSubscription = bodyKeydownEvents . pipe (
67
- filter ( ( ) => ! ! this . _attachedOverlays . length )
68
- ) . subscribe ( event => {
69
- // Dispatch keydown event to the correct overlay.
70
- this . _selectOverlayFromEvent ( event ) . _keydownEvents . next ( event ) ;
71
- } ) ;
72
- }
73
-
74
- /** Removes the global keydown subscription. */
75
- private _unsubscribeFromKeydownEvents ( ) : void {
76
- if ( this . _keydownEventSubscription ) {
77
- this . _keydownEventSubscription . unsubscribe ( ) ;
78
- this . _keydownEventSubscription = null ;
56
+ this . _detach ( ) ;
79
57
}
80
58
}
81
59
@@ -91,6 +69,21 @@ export class OverlayKeyboardDispatcher implements OnDestroy {
91
69
return targetedOverlay || this . _attachedOverlays [ this . _attachedOverlays . length - 1 ] ;
92
70
}
93
71
72
+ /** Detaches the global keyboard event listener. */
73
+ private _detach ( ) {
74
+ if ( this . _isAttached ) {
75
+ this . _document . body . removeEventListener ( 'keydown' , this . _keydownListener , true ) ;
76
+ this . _isAttached = false ;
77
+ }
78
+ }
79
+
80
+ /** Keyboard event listener that will be attached to the body. */
81
+ private _keydownListener = ( event : KeyboardEvent ) => {
82
+ if ( this . _attachedOverlays . length ) {
83
+ // Dispatch keydown event to the correct overlay.
84
+ this . _selectOverlayFromEvent ( event ) . _keydownEvents . next ( event ) ;
85
+ }
86
+ }
94
87
}
95
88
96
89
/** @docs -private */
0 commit comments