license import { ComponentFactoryResolver , ComponentRef , Directive , EmbeddedViewRef , EventEmitter , NgModule , OnDestroy , OnInit , Output , TemplateRef , ViewContainerRef , Inject , } from '@angular/core' ; import { DOCUMENT } from '@angular/common' ; import { BasePortalOutlet , ComponentPortal , Portal , TemplatePortal , DomPortal } from './portal' ; /**
 * Directive version of a `TemplatePortal`. Because the directive *is* a TemplatePortal,
 * the directive instance itself can be attached to a host, enabling declarative use of portals.
 */ @ Directive ( { selector : '[cdkPortal]' , exportAs : 'cdkPortal' , } ) export class CdkPortal extends TemplatePortal { constructor ( templateRef , viewContainerRef ) { super ( templateRef , viewContainerRef ) ; } } deprecated breaking-change @ Directive ( { selector : '[cdk-portal], [portal]' , exportAs : 'cdkPortal' , providers : [ { provide : CdkPortal , useExisting : TemplatePortalDirective , } , ] , } ) export class TemplatePortalDirective extends CdkPortal { } /**
 * Possible attached references to the CdkPortalOutlet.
 */ export type CdkPortalOutletAttachedRef = ComponentRef < any > | EmbeddedViewRef < any > | null ; /**
 * Directive version of a PortalOutlet. Because the directive *is* a PortalOutlet, portals can be
 * directly attached to it, enabling declarative use.
 *
 * Usage:
 * `<ng-template [cdkPortalOutlet]="greeting"></ng-template>`
 */ @ Directive ( { selector : '[cdkPortalOutlet]' , exportAs : 'cdkPortalOutlet' , inputs : [ 'portal: cdkPortalOutlet' ] , } ) export class CdkPortalOutlet extends BasePortalOutlet implements OnInit , OnDestroy { private _document : Document ; /** Whether the portal component is initialized. */ private _isInitialized = false ; /** Reference to the currently-attached component/view ref. */ private _attachedRef : CdkPortalOutletAttachedRef ; constructor ( private _componentFactoryResolver , private _viewContainerRef , deprecated breaking-change @ Inject ( DOCUMENT ) _document ? ) { super ( ) ; this . _document = _document ; } /** Portal associated with the Portal outlet. */ get portal ( ) : Portal < any > | null { return this . _attachedPortal ; } set portal ( portal ) { if ( this . hasAttached ( ) && ! portal && ! this . _isInitialized ) { return ; } if ( this . hasAttached ( ) ) { super . detach ( ) ; } if ( portal ) { super . attach ( portal ) ; } this . _attachedPortal = portal || null ; } /** Emits when a portal is attached to the outlet. */ @ Output ( ) readonly attached : EventEmitter < CdkPortalOutletAttachedRef > = new EventEmitter < CdkPortalOutletAttachedRef > ( ) ; /** Component or view reference that is attached to the portal. */ get attachedRef ( ) : CdkPortalOutletAttachedRef { return this . _attachedRef ; } ngOnInit ( ) { this . _isInitialized = true ; } ngOnDestroy ( ) { super . dispose ( ) ; this . _attachedPortal = null ; this . _attachedRef = null ; } param portal returns attachComponentPortal < T > ( portal ) { portal . setAttachedHost ( this ) ; const viewContainerRef = portal . viewContainerRef != null ? portal . viewContainerRef : this . _viewContainerRef ; const resolver = portal . componentFactoryResolver || this . _componentFactoryResolver ; const componentFactory = resolver . resolveComponentFactory ( portal . component ) ; const ref = viewContainerRef . createComponent ( componentFactory , viewContainerRef . length , portal . injector || viewContainerRef . injector ) ; if ( viewContainerRef !== this . _viewContainerRef ) { this . _getRootNode ( ) . appendChild ( ( ref . hostView as EmbeddedViewRef < any > ) . rootNodes [ 0 ] ) ; } super . setDisposeFn ( ( ) => ref . destroy ( ) ) ; this . _attachedPortal = portal ; this . _attachedRef = ref ; this . attached . emit ( ref ) ; return ref ; } param portal returns attachTemplatePortal < C > ( portal ) { portal . setAttachedHost ( this ) ; const viewRef = this . _viewContainerRef . createEmbeddedView ( portal . templateRef , portal . context ) ; super . setDisposeFn ( ( ) => this . _viewContainerRef . clear ( ) ) ; this . _attachedPortal = portal ; this . _attachedRef = viewRef ; this . attached . emit ( viewRef ) ; return viewRef ; } param portal deprecated breaking-change override attachDomPortal = ( portal ) => { if ( ! this . _document && ( typeof ngDevMode === 'undefined' || ngDevMode ) ) { throw Error ( 'Cannot attach DOM portal without _document constructor parameter' ) ; } const element = portal . element ; if ( ! element . parentNode && ( typeof ngDevMode === 'undefined' || ngDevMode ) ) { throw Error ( 'DOM portal content must be attached to a parent node.' ) ; } const anchorNode = this . _document . createComment ( 'dom-portal' ) ; portal . setAttachedHost ( this ) ; element . parentNode ! . insertBefore ( anchorNode , element ) ; this . _getRootNode ( ) . appendChild ( element ) ; this . _attachedPortal = portal ; super . setDisposeFn ( ( ) => { if ( anchorNode . parentNode ) { anchorNode . parentNode ! . replaceChild ( element , anchorNode ) ; } } ) ; } ; /** Gets the root node of the portal outlet. */ private _getRootNode ( ) { const nativeElement = this . _viewContainerRef . element . nativeElement ; return ( nativeElement . nodeType === nativeElement . ELEMENT_NODE ? nativeElement : nativeElement . parentNode ! ) as HTMLElement ; } } deprecated breaking-change @ Directive ( { selector : '[cdkPortalHost], [portalHost]' , exportAs : 'cdkPortalHost' , inputs : [ 'portal: cdkPortalHost' ] , providers : [ { provide : CdkPortalOutlet , useExisting : PortalHostDirective , } , ] , } ) export class PortalHostDirective extends CdkPortalOutlet { } @ NgModule ( { exports : [ CdkPortal , CdkPortalOutlet , TemplatePortalDirective , PortalHostDirective ] , declarations : [ CdkPortal , CdkPortalOutlet , TemplatePortalDirective , PortalHostDirective ] , } ) export class PortalModule { }