import { Component , ComponentFactoryResolver , ElementRef , Inject , InjectionToken , OnInit , Renderer , ViewChild , ViewContainerRef } from '@angular/core' ; import { App } from './app' ; import { assert } from '../../util/util' ; import { Config } from '../../config/config' ; import { Ion } from '../ion' ; import { OverlayPortal } from './overlay-portal' ; import { Platform } from '../../platform/platform' ; import * as Constants from './app-constants' ; export const AppRootToken = new InjectionToken < any > ( 'USERROOT' ) ; hidden @ Component ( { selector : 'ion-app' , template : '<div #viewport app-viewport></div>' + '<div #modalPortal overlay-portal></div>' + '<div #overlayPortal overlay-portal></div>' + '<div #loadingPortal class="loading-portal" overlay-portal></div>' + '<div #toastPortal class="toast-portal" [overlay-portal]="10000"></div>' + '<div class="click-block"></div>' } ) export class IonicApp extends Ion implements OnInit { private _stopScrollPlugin : any ; private _tmr : number ; @ ViewChild ( 'viewport' , { read : ViewContainerRef } ) _viewport : ViewContainerRef ; @ ViewChild ( 'modalPortal' , { read : OverlayPortal } ) _modalPortal : OverlayPortal ; @ ViewChild ( 'overlayPortal' , { read : OverlayPortal } ) _overlayPortal : OverlayPortal ; @ ViewChild ( 'loadingPortal' , { read : OverlayPortal } ) _loadingPortal : OverlayPortal ; @ ViewChild ( 'toastPortal' , { read : OverlayPortal } ) _toastPortal : OverlayPortal ; constructor ( @ Inject ( AppRootToken ) private _userCmp , private _cfr , elementRef , renderer , config , private _plt , app ) { super ( config , elementRef , renderer , 'app-root' ) ; app . _appRoot = this ; this . _stopScrollPlugin = ( < any > window ) [ 'IonicStopScroll' ] ; } ngOnInit ( ) { const factory = this . _cfr . resolveComponentFactory ( this . _userCmp ) ; const componentRef = this . _viewport . createComponent ( factory ) ; this . _renderer . setElementClass ( componentRef . location . nativeElement , 'app-root' , true ) ; componentRef . changeDetectorRef . detectChanges ( ) ; this . setElementClass ( this . _config . get ( 'mode' ) , true ) ; const versions = this . _plt . versions ( ) ; this . _plt . platforms ( ) . forEach ( platformName => { let platformClass = 'platform-' + platformName ; this . setElementClass ( platformClass , true ) ; let platformVersion = versions [ platformName ] ; if ( platformVersion ) { platformClass += platformVersion . major ; this . setElementClass ( platformClass , true ) ; this . setElementClass ( platformClass + '_' + platformVersion . minor , true ) ; } } ) ; if ( this . _config . getBoolean ( 'hoverCSS' , true ) ) { this . setElementClass ( 'enable-hover' , true ) ; } this . _plt . prepareReady ( ) ; } hidden _getPortal ( portal ? ) { if ( portal === Constants . PORTAL_LOADING ) { return this . _loadingPortal ; } if ( portal === Constants . PORTAL_TOAST ) { return this . _toastPortal ; } if ( portal === Constants . PORTAL_MODAL ) { return this . _modalPortal ; } return this . _overlayPortal ; } _getActivePortal ( ) { const defaultPortal = this . _overlayPortal ; const modalPortal = this . _modalPortal ; const hasModal = modalPortal . length ( ) > 0 ; const hasDefault = defaultPortal . length ( ) > 0 ; if ( ! hasModal && ! hasDefault ) { return null ; } else if ( hasModal && hasDefault ) { var defaultIndex = defaultPortal . getActive ( ) . getZIndex ( ) ; var modalIndex = modalPortal . getActive ( ) . getZIndex ( ) ; if ( defaultIndex > modalIndex ) { return defaultPortal ; } else { assert ( modalIndex > defaultIndex , 'modal and default zIndex can not be equal' ) ; return modalPortal ; } } if ( hasModal ) { return modalPortal ; } else if ( hasDefault ) { return defaultPortal ; } } _disableScroll ( shouldDisableScroll ) { if ( shouldDisableScroll ) { this . stopScroll ( ) . then ( ( ) => { this . _tmr = this . _plt . timeout ( ( ) => { console . debug ( 'App Root: adding .disable-scroll' ) ; this . setElementClass ( 'disable-scroll' , true ) ; } , 32 ) ; } ) ; } else { let plugin = this . _stopScrollPlugin ; if ( plugin && plugin . cancel ) { plugin . cancel ( ) ; } clearTimeout ( this . _tmr ) ; console . debug ( 'App Root: removing .disable-scroll' ) ; this . setElementClass ( 'disable-scroll' , false ) ; /**
             * On iOS 12.2 there is a bug that
             * prevents pointer-events from being
             * re-enabled when removing the
             * disable-scroll class.
             */ const plaform = this . _plt ; plaform . raf ( ( ) => { this . setElementStyle ( 'z-index' , '1' ) ; plaform . raf ( ( ) => { this . setElementStyle ( 'z-index' , null ) ; } ) ; } ) ; } } stopScroll ( ) { if ( this . _stopScrollPlugin ) { return new Promise ( ( resolve ) => { this . _stopScrollPlugin . stop ( ( ) => resolve ( true ) ) ; } ) ; } else { return Promise . resolve ( false ) ; } } }