license import { DOCUMENT } from '@angular/common' ; import { Inject , Injectable , InjectionToken , OnDestroy , Optional , SkipSelf , } from '@angular/core' ; import { OverlayRef } from '../overlay-ref' ; /**
 * Service for dispatching keyboard events that land on the body to appropriate overlay ref,
 * if any. It maintains a list of attached overlays to determine best suited overlay based
 * on event target and order of overlay opens.
 */ @ Injectable ( { providedIn : 'root' } ) export class OverlayKeyboardDispatcher implements OnDestroy { /** Currently attached overlays in the order they were attached. */ _attachedOverlays : OverlayRef [ ] = [ ] ; private _document : Document ; private _isAttached : boolean ; constructor ( @ Inject ( DOCUMENT ) document ) { this . _document = document ; } ngOnDestroy ( ) { this . _detach ( ) ; } /** Add a new overlay to the list of attached overlay refs. */ add ( overlayRef ) { this . remove ( overlayRef ) ; if ( ! this . _isAttached ) { this . _document . body . addEventListener ( 'keydown' , this . _keydownListener ) ; this . _isAttached = true ; } this . _attachedOverlays . push ( overlayRef ) ; } /** Remove an overlay from the list of attached overlay refs. */ remove ( overlayRef ) { const index = this . _attachedOverlays . indexOf ( overlayRef ) ; if ( index > - 1 ) { this . _attachedOverlays . splice ( index , 1 ) ; } if ( this . _attachedOverlays . length === 0 ) { this . _detach ( ) ; } } /** Detaches the global keyboard event listener. */ private _detach ( ) { if ( this . _isAttached ) { this . _document . body . removeEventListener ( 'keydown' , this . _keydownListener ) ; this . _isAttached = false ; } } /** Keyboard event listener that will be attached to the body. */ private _keydownListener = ( event ) => { const overlays = this . _attachedOverlays ; for ( let i = overlays . length - 1 ; i > - 1 ; i -- ) { if ( overlays [ i ] . _keydownEventSubscriptions > 0 ) { overlays [ i ] . _keydownEvents . next ( event ) ; break ; } } } ; } docs-private deprecated breaking-change export function OVERLAY_KEYBOARD_DISPATCHER_PROVIDER_FACTORY ( dispatcher , _document ) { return dispatcher || new OverlayKeyboardDispatcher ( _document ) ; } docs-private deprecated breaking-change export const OVERLAY_KEYBOARD_DISPATCHER_PROVIDER = { provide : OverlayKeyboardDispatcher , deps : [ [ new Optional ( ) , new SkipSelf ( ) , OverlayKeyboardDispatcher ] , DOCUMENT as InjectionToken < any > ] , useFactory : OVERLAY_KEYBOARD_DISPATCHER_PROVIDER_FACTORY } ;