import { ComponentRef , EmbeddedViewRef , Inject , Injectable , InjectionToken , Injector , OnDestroy , Optional , SkipSelf } from '@angular/core' ; import { Overlay , OverlayRef } from '@angular-mdc/web/overlay' ; import { ComponentPortal , ComponentType , PortalInjector } from '@angular/cdk/portal' ; import { MdcSnackbarComponent } from './snackbar.component' ; import { MDC_SNACKBAR_DATA , MdcSnackbarConfig } from './snackbar-config' ; import { MdcSnackbarContainer } from './snackbar-container' ; import { MdcSnackbarModule } from './module' ; import { MdcSnackbarRef } from './snackbar-ref' ; /** Injection token that can be used to specify default snackbar. */ export const MDC_SNACKBAR_DEFAULT_OPTIONS = new InjectionToken < MdcSnackbarConfig > ( 'mdc-snackbar-default-options' , { providedIn : 'root' , factory : MDC_SNACKBAR_DEFAULT_OPTIONS_FACTORY , } ) ; docs-private export function MDC_SNACKBAR_DEFAULT_OPTIONS_FACTORY ( ) { return new MdcSnackbarConfig ( ) ; } @ Injectable ( { providedIn : MdcSnackbarModule } ) export class MdcSnackbar implements OnDestroy { /**
     * Reference to the current snackbar in the view *at this level* (in the Angular injector tree).
     * If there is a parent snack-bar service, all operations should delegate to that parent
     * via `_openedSnackbarRef`.
     */ private _snackbarRefAtThisLevel : MdcSnackbarRef < any > | null = null ; /** Reference to the currently opened snackbar at *any* level. */ get _openedSnackbarRef ( ) : MdcSnackbarRef < any > | null { const parent = this . _parentSnackbar ; return parent ? parent . _openedSnackbarRef : this . _snackbarRefAtThisLevel ; } set _openedSnackbarRef ( value ) { if ( this . _parentSnackbar ) { this . _parentSnackbar . _openedSnackbarRef = value ; } else { this . _snackbarRefAtThisLevel = value ; } } constructor ( private _overlay , private _injector , @ Optional ( ) @ SkipSelf ( ) private _parentSnackbar , @ Inject ( MDC_SNACKBAR_DEFAULT_OPTIONS ) private _defaultConfig ) { } param component param config openFromComponent < T > ( component , config ? ) { return this . _attach ( component , config ) as MdcSnackbarRef < T > ; } param message param action param config open ( message , action ? , config ? ) { const _config = { ... this . _defaultConfig , ... config } ; _config . data = { message , action } ; return this . openFromComponent ( MdcSnackbarComponent , _config ) ; } /**
     * Dismisses the currently-visible snackbar.
     */ dismiss ( ) { if ( this . _openedSnackbarRef ) { if ( this . _openedSnackbarRef . instance instanceof MdcSnackbarComponent ) { ( < MdcSnackbarComponent > this . _openedSnackbarRef . instance ) . close ( ) ; } this . _openedSnackbarRef . dismiss ( ) ; } } ngOnDestroy ( ) { this . _snackbarRefAtThisLevel ?. dismiss ( ) ; } /**
     * Attaches the snackbar container component to the overlay.
     */ private _attachSnackbarContainer ( overlayRef , config ) { const userInjector = config && config . viewContainerRef && config . viewContainerRef . injector ; const injector = new PortalInjector ( userInjector || this . _injector , new WeakMap ( [ [ MdcSnackbarConfig , config ] ] ) ) ; const containerPortal = new ComponentPortal ( MdcSnackbarContainer , config . viewContainerRef , injector ) ; const containerRef = overlayRef . attach ( containerPortal ) ; containerRef . instance . snackbarConfig = config ; return containerRef . instance ; } /**
     * Places a new component or a template as the content of the snackbar container.
     */ private _attach < T > ( content , userConfig ? ) { const config = { ... new MdcSnackbarConfig ( ) , ... this . _defaultConfig , ... userConfig } ; const overlayRef = this . _createOverlay ( ) ; const container = this . _attachSnackbarContainer ( overlayRef , config ) ; const snackbarRef = new MdcSnackbarRef < T | EmbeddedViewRef < any > > ( container , overlayRef ) ; const injector = this . _createInjector ( config , snackbarRef ) ; const portal = new ComponentPortal ( content , undefined , injector ) ; const contentRef = container . attachComponentPortal < T > ( portal ) ; snackbarRef . instance = contentRef . instance ; this . _loadListeners ( snackbarRef ) ; this . _openedSnackbarRef = snackbarRef ; if ( snackbarRef . instance instanceof MdcSnackbarComponent ) { ( < MdcSnackbarComponent > snackbarRef . instance ) . open ( ) ; } return this . _openedSnackbarRef ; } private _loadListeners ( snackbarRef ) { snackbarRef . afterDismiss ( ) . subscribe ( ( ) => { if ( this . _openedSnackbarRef === snackbarRef ) { this . _openedSnackbarRef = null ; } } ) ; this . _openedSnackbarRef ?. dismiss ( ) ; } param config private _createOverlay ( ) { return this . _overlay . create ( ) ; } param config param snackbarRef private _createInjector < T > ( config , snackbarRef ) { const userInjector = config && config . viewContainerRef && config . viewContainerRef . injector ; return new PortalInjector ( userInjector || this . _injector , new WeakMap < any , any > ( [ [ MdcSnackbarRef , snackbarRef ] , [ MDC_SNACKBAR_DATA , config . data ] ] ) ) ; } }