import { ElementRef, Directive, TemplateRef, ViewContainerRef, EventEmitter, ComponentFactoryResolver, Inject, Output, NgModule } from '@angular/core';
import { DOCUMENT } from '@angular/common';
/**
* @fileoverview added by tsickle
* Generated from: src/cdk/portal/portal-errors.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Throws an exception when attempting to attach a null portal to a host.
* \@docs-private
* @return {?}
*/
function throwNullPortalError() {
throw Error('Must provide a portal to attach');
}
/**
* Throws an exception when attempting to attach a portal to a host that is already attached.
* \@docs-private
* @return {?}
*/
function throwPortalAlreadyAttachedError() {
throw Error('Host already has a portal attached');
}
/**
* Throws an exception when attempting to attach a portal to an already-disposed host.
* \@docs-private
* @return {?}
*/
function throwPortalOutletAlreadyDisposedError() {
throw Error('This PortalOutlet has already been disposed');
}
/**
* Throws an exception when attempting to attach an unknown portal type.
* \@docs-private
* @return {?}
*/
function throwUnknownPortalTypeError() {
throw Error('Attempting to attach an unknown Portal type. BasePortalOutlet accepts either ' +
'a ComponentPortal or a TemplatePortal.');
}
/**
* Throws an exception when attempting to attach a portal to a null host.
* \@docs-private
* @return {?}
*/
function throwNullPortalOutletError() {
throw Error('Attempting to attach a portal to a null PortalOutlet');
}
/**
* Throws an exception when attempting to detach a portal that is not attached.
* \@docs-private
* @return {?}
*/
function throwNoPortalAttachedError() {
throw Error('Attempting to detach a portal that is not attached to a host');
}
/**
* @fileoverview added by tsickle
* Generated from: src/cdk/portal/portal.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Interface that can be used to generically type a class.
* @record
* @template T
*/
function ComponentType() { }
/**
* A `Portal` is something that you want to render somewhere else.
* It can be attach to / detached from a `PortalOutlet`.
* @abstract
* @template T
*/
class Portal {
/**
* Attach this portal to a host.
* @param {?} host
* @return {?}
*/
attach(host) {
if (host == null) {
throwNullPortalOutletError();
}
if (host.hasAttached()) {
throwPortalAlreadyAttachedError();
}
this._attachedHost = host;
return (/** @type {?} */ (host.attach(this)));
}
/**
* Detach this portal from its host
* @return {?}
*/
detach() {
/** @type {?} */
let host = this._attachedHost;
if (host == null) {
throwNoPortalAttachedError();
}
else {
this._attachedHost = null;
host.detach();
}
}
/**
* Whether this portal is attached to a host.
* @return {?}
*/
get isAttached() {
return this._attachedHost != null;
}
/**
* Sets the PortalOutlet reference without performing `attach()`. This is used directly by
* the PortalOutlet when it is performing an `attach()` or `detach()`.
* @param {?} host
* @return {?}
*/
setAttachedHost(host) {
this._attachedHost = host;
}
}
if (false) {
/**
* @type {?}
* @private
*/
Portal.prototype._attachedHost;
}
/**
* A `ComponentPortal` is a portal that instantiates some Component upon attachment.
* @template T
*/
class ComponentPortal extends Portal {
/**
* @param {?} component
* @param {?=} viewContainerRef
* @param {?=} injector
* @param {?=} componentFactoryResolver
*/
constructor(component, viewContainerRef, injector, componentFactoryResolver) {
super();
this.component = component;
this.viewContainerRef = viewContainerRef;
this.injector = injector;
this.componentFactoryResolver = componentFactoryResolver;
}
}
if (false) {
/**
* The type of the component that will be instantiated for attachment.
* @type {?}
*/
ComponentPortal.prototype.component;
/**
* [Optional] Where the attached component should live in Angular's *logical* component tree.
* This is different from where the component *renders*, which is determined by the PortalOutlet.
* The origin is necessary when the host is outside of the Angular application context.
* @type {?}
*/
ComponentPortal.prototype.viewContainerRef;
/**
* [Optional] Injector used for the instantiation of the component.
* @type {?}
*/
ComponentPortal.prototype.injector;
/**
* Alternate `ComponentFactoryResolver` to use when resolving the associated component.
* Defaults to using the resolver from the outlet that the portal is attached to.
* @type {?}
*/
ComponentPortal.prototype.componentFactoryResolver;
}
/**
* A `TemplatePortal` is a portal that represents some embedded template (TemplateRef).
* @template C
*/
class TemplatePortal extends Portal {
/**
* @param {?} template
* @param {?} viewContainerRef
* @param {?=} context
*/
constructor(template, viewContainerRef, context) {
super();
this.templateRef = template;
this.viewContainerRef = viewContainerRef;
this.context = context;
}
/**
* @return {?}
*/
get origin() {
return this.templateRef.elementRef;
}
/**
* Attach the portal to the provided `PortalOutlet`.
* When a context is provided it will override the `context` property of the `TemplatePortal`
* instance.
* @param {?} host
* @param {?=} context
* @return {?}
*/
attach(host, context = this.context) {
this.context = context;
return super.attach(host);
}
/**
* @return {?}
*/
detach() {
this.context = undefined;
return super.detach();
}
}
if (false) {
/**
* The embedded template that will be used to instantiate an embedded View in the host.
* @type {?}
*/
TemplatePortal.prototype.templateRef;
/**
* Reference to the ViewContainer into which the template will be stamped out.
* @type {?}
*/
TemplatePortal.prototype.viewContainerRef;
/**
* Contextual data to be passed in to the embedded view.
* @type {?}
*/
TemplatePortal.prototype.context;
}
/**
* A `DomPortal` is a portal whose DOM element will be taken from its current position
* in the DOM and moved into a portal outlet, when it is attached. On detach, the content
* will be restored to its original position.
* @template T
*/
class DomPortal extends Portal {
/**
* @param {?} element
*/
constructor(element) {
super();
this.element = element instanceof ElementRef ? element.nativeElement : element;
}
}
if (false) {
/**
* DOM node hosting the portal's content.
* @type {?}
*/
DomPortal.prototype.element;
}
/**
* A `PortalOutlet` is an space that can contain a single `Portal`.
* @record
*/
function PortalOutlet() { }
if (false) {
/**
* Attaches a portal to this outlet.
* @param {?} portal
* @return {?}
*/
PortalOutlet.prototype.attach = function (portal) { };
/**
* Detaches the currently attached portal from this outlet.
* @return {?}
*/
PortalOutlet.prototype.detach = function () { };
/**
* Performs cleanup before the outlet is destroyed.
* @return {?}
*/
PortalOutlet.prototype.dispose = function () { };
/**
* Whether there is currently a portal attached to this outlet.
* @return {?}
*/
PortalOutlet.prototype.hasAttached = function () { };
}
/**
* Partial implementation of PortalOutlet that handles attaching
* ComponentPortal and TemplatePortal.
* @abstract
*/
class BasePortalOutlet {
constructor() {
/**
* Whether this host has already been permanently disposed.
*/
this._isDisposed = false;
// @breaking-change 10.0.0 `attachDomPortal` to become a required abstract method.
this.attachDomPortal = null;
}
/**
* Whether this host has an attached portal.
* @return {?}
*/
hasAttached() {
return !!this._attachedPortal;
}
/**
* Attaches a portal.
* @param {?} portal
* @return {?}
*/
attach(portal) {
if (!portal) {
throwNullPortalError();
}
if (this.hasAttached()) {
throwPortalAlreadyAttachedError();
}
if (this._isDisposed) {
throwPortalOutletAlreadyDisposedError();
}
if (portal instanceof ComponentPortal) {
this._attachedPortal = portal;
return this.attachComponentPortal(portal);
}
else if (portal instanceof TemplatePortal) {
this._attachedPortal = portal;
return this.attachTemplatePortal(portal);
// @breaking-change 10.0.0 remove null check for `this.attachDomPortal`.
}
else if (this.attachDomPortal && portal instanceof DomPortal) {
this._attachedPortal = portal;
return this.attachDomPortal(portal);
}
throwUnknownPortalTypeError();
}
/**
* Detaches a previously attached portal.
* @return {?}
*/
detach() {
if (this._attachedPortal) {
this._attachedPortal.setAttachedHost(null);
this._attachedPortal = null;
}
this._invokeDisposeFn();
}
/**
* Permanently dispose of this portal host.
* @return {?}
*/
dispose() {
if (this.hasAttached()) {
this.detach();
}
this._invokeDisposeFn();
this._isDisposed = true;
}
/**
* \@docs-private
* @param {?} fn
* @return {?}
*/
setDisposeFn(fn) {
this._disposeFn = fn;
}
/**
* @private
* @return {?}
*/
_invokeDisposeFn() {
if (this._disposeFn) {
this._disposeFn();
this._disposeFn = null;
}
}
}
if (false) {
/**
* The portal currently attached to the host.
* @type {?}
* @protected
*/
BasePortalOutlet.prototype._attachedPortal;
/**
* A function that will permanently dispose this host.
* @type {?}
* @private
*/
BasePortalOutlet.prototype._disposeFn;
/**
* Whether this host has already been permanently disposed.
* @type {?}
* @private
*/
BasePortalOutlet.prototype._isDisposed;
/** @type {?} */
BasePortalOutlet.prototype.attachDomPortal;
/**
* @abstract
* @template T
* @param {?} portal
* @return {?}
*/
BasePortalOutlet.prototype.attachComponentPortal = function (portal) { };
/**
* @abstract
* @template C
* @param {?} portal
* @return {?}
*/
BasePortalOutlet.prototype.attachTemplatePortal = function (portal) { };
}
/**
* @deprecated Use `BasePortalOutlet` instead.
* \@breaking-change 9.0.0
* @abstract
*/
class BasePortalHost extends BasePortalOutlet {
}
/**
* @fileoverview added by tsickle
* Generated from: src/cdk/portal/dom-portal-outlet.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* A PortalOutlet for attaching portals to an arbitrary DOM element outside of the Angular
* application context.
*/
class DomPortalOutlet extends BasePortalOutlet {
/**
* @param {?} outletElement
* @param {?} _componentFactoryResolver
* @param {?} _appRef
* @param {?} _defaultInjector
* @param {?=} _document
*/
constructor(outletElement, _componentFactoryResolver, _appRef, _defaultInjector,
/**
* @deprecated `_document` Parameter to be made required.
* @breaking-change 10.0.0
*/
_document) {
super();
this.outletElement = outletElement;
this._componentFactoryResolver = _componentFactoryResolver;
this._appRef = _appRef;
this._defaultInjector = _defaultInjector;
/**
* Attaches a DOM portal by transferring its content into the outlet.
* @param portal Portal to be attached.
* @deprecated To be turned into a method.
* \@breaking-change 10.0.0
*/
this.attachDomPortal = (/**
* @param {?} portal
* @return {?}
*/
(portal) => {
// @breaking-change 10.0.0 Remove check and error once the
// `_document` constructor parameter is required.
if (!this._document) {
throw Error('Cannot attach DOM portal without _document constructor parameter');
}
/** @type {?} */
const element = portal.element;
if (!element.parentNode) {
throw Error('DOM portal content must be attached to a parent node.');
}
// Anchor used to save the element's previous position so
// that we can restore it when the portal is detached.
/** @type {?} */
const anchorNode = this._document.createComment('dom-portal');
element.parentNode.insertBefore(anchorNode, element);
this.outletElement.appendChild(element);
super.setDisposeFn((/**
* @return {?}
*/
() => {
// We can't use `replaceWith` here because IE doesn't support it.
if (anchorNode.parentNode) {
anchorNode.parentNode.replaceChild(element, anchorNode);
}
}));
});
this._document = _document;
}
/**
* Attach the given ComponentPortal to DOM element using the ComponentFactoryResolver.
* @template T
* @param {?} portal Portal to be attached
* @return {?} Reference to the created component.
*/
attachComponentPortal(portal) {
/** @type {?} */
const resolver = portal.componentFactoryResolver || this._componentFactoryResolver;
/** @type {?} */
const componentFactory = resolver.resolveComponentFactory(portal.component);
/** @type {?} */
let componentRef;
// If the portal specifies a ViewContainerRef, we will use that as the attachment point
// for the component (in terms of Angular's component tree, not rendering).
// When the ViewContainerRef is missing, we use the factory to create the component directly
// and then manually attach the view to the application.
if (portal.viewContainerRef) {
componentRef = portal.viewContainerRef.createComponent(componentFactory, portal.viewContainerRef.length, portal.injector || portal.viewContainerRef.injector);
this.setDisposeFn((/**
* @return {?}
*/
() => componentRef.destroy()));
}
else {
componentRef = componentFactory.create(portal.injector || this._defaultInjector);
this._appRef.attachView(componentRef.hostView);
this.setDisposeFn((/**
* @return {?}
*/
() => {
this._appRef.detachView(componentRef.hostView);
componentRef.destroy();
}));
}
// At this point the component has been instantiated, so we move it to the location in the DOM
// where we want it to be rendered.
this.outletElement.appendChild(this._getComponentRootNode(componentRef));
return componentRef;
}
/**
* Attaches a template portal to the DOM as an embedded view.
* @template C
* @param {?} portal Portal to be attached.
* @return {?} Reference to the created embedded view.
*/
attachTemplatePortal(portal) {
/** @type {?} */
let viewContainer = portal.viewContainerRef;
/** @type {?} */
let viewRef = viewContainer.createEmbeddedView(portal.templateRef, portal.context);
viewRef.detectChanges();
// The method `createEmbeddedView` will add the view as a child of the viewContainer.
// But for the DomPortalOutlet the view can be added everywhere in the DOM
// (e.g Overlay Container) To move the view to the specified host element. We just
// re-append the existing root nodes.
viewRef.rootNodes.forEach((/**
* @param {?} rootNode
* @return {?}
*/
rootNode => this.outletElement.appendChild(rootNode)));
this.setDisposeFn(((/**
* @return {?}
*/
() => {
/** @type {?} */
let index = viewContainer.indexOf(viewRef);
if (index !== -1) {
viewContainer.remove(index);
}
})));
// TODO(jelbourn): Return locals from view.
return viewRef;
}
/**
* Clears out a portal from the DOM.
* @return {?}
*/
dispose() {
super.dispose();
if (this.outletElement.parentNode != null) {
this.outletElement.parentNode.removeChild(this.outletElement);
}
}
/**
* Gets the root HTMLElement for an instantiated component.
* @private
* @param {?} componentRef
* @return {?}
*/
_getComponentRootNode(componentRef) {
return (/** @type {?} */ (((/** @type {?} */ (componentRef.hostView))).rootNodes[0]));
}
}
if (false) {
/**
* @type {?}
* @private
*/
DomPortalOutlet.prototype._document;
/**
* Attaches a DOM portal by transferring its content into the outlet.
* \@param portal Portal to be attached.
* @deprecated To be turned into a method.
* \@breaking-change 10.0.0
* @type {?}
*/
DomPortalOutlet.prototype.attachDomPortal;
/**
* Element into which the content is projected.
* @type {?}
*/
DomPortalOutlet.prototype.outletElement;
/**
* @type {?}
* @private
*/
DomPortalOutlet.prototype._componentFactoryResolver;
/**
* @type {?}
* @private
*/
DomPortalOutlet.prototype._appRef;
/**
* @type {?}
* @private
*/
DomPortalOutlet.prototype._defaultInjector;
}
/**
* @deprecated Use `DomPortalOutlet` instead.
* \@breaking-change 9.0.0
*/
class DomPortalHost extends DomPortalOutlet {
}
/**
* @fileoverview added by tsickle
* Generated from: src/cdk/portal/portal-directives.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* 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.
*/
class CdkPortal extends TemplatePortal {
/**
* @param {?} templateRef
* @param {?} viewContainerRef
*/
constructor(templateRef, viewContainerRef) {
super(templateRef, viewContainerRef);
}
}
CdkPortal.decorators = [
{ type: Directive, args: [{
selector: '[cdkPortal]',
exportAs: 'cdkPortal',
},] }
];
/** @nocollapse */
CdkPortal.ctorParameters = () => [
{ type: TemplateRef },
{ type: ViewContainerRef }
];
/**
* @deprecated Use `CdkPortal` instead.
* \@breaking-change 9.0.0
*/
class TemplatePortalDirective extends CdkPortal {
}
TemplatePortalDirective.decorators = [
{ type: Directive, args: [{
selector: '[cdk-portal], [portal]',
exportAs: 'cdkPortal',
providers: [{
provide: CdkPortal,
useExisting: TemplatePortalDirective
}]
},] }
];
/**
* Directive version of a PortalOutlet. Because the directive *is* a PortalOutlet, portals can be
* directly attached to it, enabling declarative use.
*
* Usage:
* `