declare const clearTimeout ; import { Component , ComponentRef , ElementRef , EmbeddedViewRef , Injector , ViewChild , ViewContainerRef , ViewEncapsulation , Renderer2 , TemplateRef } from '@angular/core' ; import { PromiseCompleter , supportsKey } from '../framework/utils' ; import { DialogRef } from '../models/dialog-ref' ; import { ContainerContent } from '../models/tokens' ; import { BaseDynamicComponent } from '../components/index' ; const isDoc = ! ( typeof document === 'undefined' || ! document ) ; export interface EmbedComponentConfig { component : any ; projectableNodes ? : any [ ] [ ] ; } /**
 * Represents the modal overlay.
 */ @ Component ( { selector : 'modal-overlay' , host : { '(body:keydown)' : 'documentKeypress($event)' } , encapsulation : ViewEncapsulation . None , templateUrl : './overlay.component.html' } ) export class ModalOverlay extends BaseDynamicComponent { private beforeDestroyHandlers : Array < ( ) => Promise < void > > ; @ ViewChild ( 'container' , { read : ElementRef } ) public container : ElementRef ; @ ViewChild ( 'innerView' , { read : ViewContainerRef } ) public innerVcr : ViewContainerRef ; @ ViewChild ( 'template' ) public template : TemplateRef < any > ; constructor ( private dialogRef , private vcr , el , renderer ) { super ( el , renderer ) ; this . activateAnimationListener ( ) ; } internal getProjectables < T > ( content ) { let nodes ; if ( typeof content === 'string' ) { nodes = [ [ this . renderer . createText ( `${ content }` ) ] ] ; } else if ( content instanceof TemplateRef ) { nodes = [ this . vcr . createEmbeddedView ( content , { $implicit : this . dialogRef . context , dialogRef : this . dialogRef } ) . rootNodes ] ; } else { nodes = [ this . embedComponent ( { component : content } ) . rootNodes ] ; } return nodes ; } embedComponent ( config ) { const ctx = < any > config ; return this . vcr . createEmbeddedView ( this . template , < any > { $implicit : ctx } ) ; } addComponent < T > ( type , projectableNodes = [ ] ) { return super . _addComponent < T > ( { component : type , vcRef : this . innerVcr , projectableNodes } ) ; } fullscreen ( ) { const style = { position : 'fixed' , top : 0 , left : 0 , bottom : 0 , right : 0 , 'z-index' : 1500 } ; Object . keys ( style ) . forEach ( k => this . setStyle ( k , style [ k ] ) ) ; } insideElement ( ) { const style = { position : 'absolute' , overflow : 'hidden' , width : '100%' , height : '100%' , top : 0 , left : 0 , bottom : 0 , right : 0 } ; Object . keys ( style ) . forEach ( k => this . setStyle ( k , style [ k ] ) ) ; } param prop param value setContainerStyle ( prop , value ) { this . renderer . setStyle ( this . container . nativeElement , prop , value ) ; return this ; } param element setClickBoundary ( element ) { let target ; const elListener = event => target = event . target as any ; const docListener = event => { if ( this . dialogRef . context . isBlocking || ! this . dialogRef . overlay . isTopMost ( this . dialogRef ) ) { return ; } let current = event . target ; if ( current === target ) return ; do { if ( current === element ) { return ; } } while ( current . parentNode && ( current = current . parentNode ) ) ; this . dialogRef . dismiss ( ) ; } ; if ( isDoc ) { this . dialogRef . onDestroy . subscribe ( ( ) => { element . removeEventListener ( 'click' , elListener , false ) ; element . removeEventListener ( 'touchstart' , elListener , false ) ; document . removeEventListener ( 'click' , docListener , false ) ; document . removeEventListener ( 'touchend' , docListener , false ) ; } ) ; setTimeout ( ( ) => { element . addEventListener ( 'mousedown' , elListener , false ) ; element . addEventListener ( 'touchstart' , docListener , false ) ; document . addEventListener ( 'click' , docListener , false ) ; document . addEventListener ( 'touchend' , docListener , false ) ; } ) ; } } /**
     * Temp workaround for animation where destruction of the top level component does not
     * trigger child animations. Solution should be found either in animation module or in design
     * of the modal component tree.
     */ canDestroy ( ) { const completer = new PromiseCompleter < void > ( ) ; if ( ! Array . isArray ( this . beforeDestroyHandlers ) ) { completer . resolve ( ) ; } else { let id = setTimeout ( ( ) => { id = null ; completer . reject ( ) ; } , 1000 ) ; const resolve = ( ) => { if ( id === null ) return ; clearTimeout ( id ) ; completer . resolve ( ) ; } ; Promise . all ( this . beforeDestroyHandlers . map ( fn => fn ( ) ) ) . then ( resolve ) . catch ( resolve ) ; } return completer . promise ; } param fn beforeDestroy ( fn ) { if ( ! this . beforeDestroyHandlers ) { this . beforeDestroyHandlers = [ ] ; } this . beforeDestroyHandlers . push ( fn ) ; } documentKeypress ( event ) { if ( ! this . dialogRef . overlay . isTopMost ( this . dialogRef ) ) return ; if ( supportsKey ( event . keyCode , < any > this . dialogRef . context . keyboard ) ) { this . dialogRef . dismiss ( ) ; } } ngOnDestroy ( ) { super . ngOnDestroy ( ) ; if ( this . dialogRef . destroyed !== true ) { this . dialogRef . bailOut ( ) ; } } }