UNPKG

27.6 kBJavaScriptView Raw
1import * as i0 from '@angular/core';
2import { ElementRef, Injector, Directive, EventEmitter, Inject, Output, NgModule } from '@angular/core';
3import { DOCUMENT } from '@angular/common';
4
5/**
6 * Throws an exception when attempting to attach a null portal to a host.
7 * @docs-private
8 */
9function throwNullPortalError() {
10 throw Error('Must provide a portal to attach');
11}
12/**
13 * Throws an exception when attempting to attach a portal to a host that is already attached.
14 * @docs-private
15 */
16function throwPortalAlreadyAttachedError() {
17 throw Error('Host already has a portal attached');
18}
19/**
20 * Throws an exception when attempting to attach a portal to an already-disposed host.
21 * @docs-private
22 */
23function throwPortalOutletAlreadyDisposedError() {
24 throw Error('This PortalOutlet has already been disposed');
25}
26/**
27 * Throws an exception when attempting to attach an unknown portal type.
28 * @docs-private
29 */
30function throwUnknownPortalTypeError() {
31 throw Error('Attempting to attach an unknown Portal type. BasePortalOutlet accepts either ' +
32 'a ComponentPortal or a TemplatePortal.');
33}
34/**
35 * Throws an exception when attempting to attach a portal to a null host.
36 * @docs-private
37 */
38function throwNullPortalOutletError() {
39 throw Error('Attempting to attach a portal to a null PortalOutlet');
40}
41/**
42 * Throws an exception when attempting to detach a portal that is not attached.
43 * @docs-private
44 */
45function throwNoPortalAttachedError() {
46 throw Error('Attempting to detach a portal that is not attached to a host');
47}
48
49/**
50 * A `Portal` is something that you want to render somewhere else.
51 * It can be attach to / detached from a `PortalOutlet`.
52 */
53class Portal {
54 /** Attach this portal to a host. */
55 attach(host) {
56 if (typeof ngDevMode === 'undefined' || ngDevMode) {
57 if (host == null) {
58 throwNullPortalOutletError();
59 }
60 if (host.hasAttached()) {
61 throwPortalAlreadyAttachedError();
62 }
63 }
64 this._attachedHost = host;
65 return host.attach(this);
66 }
67 /** Detach this portal from its host */
68 detach() {
69 let host = this._attachedHost;
70 if (host != null) {
71 this._attachedHost = null;
72 host.detach();
73 }
74 else if (typeof ngDevMode === 'undefined' || ngDevMode) {
75 throwNoPortalAttachedError();
76 }
77 }
78 /** Whether this portal is attached to a host. */
79 get isAttached() {
80 return this._attachedHost != null;
81 }
82 /**
83 * Sets the PortalOutlet reference without performing `attach()`. This is used directly by
84 * the PortalOutlet when it is performing an `attach()` or `detach()`.
85 */
86 setAttachedHost(host) {
87 this._attachedHost = host;
88 }
89}
90/**
91 * A `ComponentPortal` is a portal that instantiates some Component upon attachment.
92 */
93class ComponentPortal extends Portal {
94 constructor(component, viewContainerRef, injector, componentFactoryResolver, projectableNodes) {
95 super();
96 this.component = component;
97 this.viewContainerRef = viewContainerRef;
98 this.injector = injector;
99 this.componentFactoryResolver = componentFactoryResolver;
100 this.projectableNodes = projectableNodes;
101 }
102}
103/**
104 * A `TemplatePortal` is a portal that represents some embedded template (TemplateRef).
105 */
106class TemplatePortal extends Portal {
107 constructor(
108 /** The embedded template that will be used to instantiate an embedded View in the host. */
109 templateRef,
110 /** Reference to the ViewContainer into which the template will be stamped out. */
111 viewContainerRef,
112 /** Contextual data to be passed in to the embedded view. */
113 context,
114 /** The injector to use for the embedded view. */
115 injector) {
116 super();
117 this.templateRef = templateRef;
118 this.viewContainerRef = viewContainerRef;
119 this.context = context;
120 this.injector = injector;
121 }
122 get origin() {
123 return this.templateRef.elementRef;
124 }
125 /**
126 * Attach the portal to the provided `PortalOutlet`.
127 * When a context is provided it will override the `context` property of the `TemplatePortal`
128 * instance.
129 */
130 attach(host, context = this.context) {
131 this.context = context;
132 return super.attach(host);
133 }
134 detach() {
135 this.context = undefined;
136 return super.detach();
137 }
138}
139/**
140 * A `DomPortal` is a portal whose DOM element will be taken from its current position
141 * in the DOM and moved into a portal outlet, when it is attached. On detach, the content
142 * will be restored to its original position.
143 */
144class DomPortal extends Portal {
145 constructor(element) {
146 super();
147 this.element = element instanceof ElementRef ? element.nativeElement : element;
148 }
149}
150/**
151 * Partial implementation of PortalOutlet that handles attaching
152 * ComponentPortal and TemplatePortal.
153 */
154class BasePortalOutlet {
155 constructor() {
156 /** Whether this host has already been permanently disposed. */
157 this._isDisposed = false;
158 // @breaking-change 10.0.0 `attachDomPortal` to become a required abstract method.
159 this.attachDomPortal = null;
160 }
161 /** Whether this host has an attached portal. */
162 hasAttached() {
163 return !!this._attachedPortal;
164 }
165 /** Attaches a portal. */
166 attach(portal) {
167 if (typeof ngDevMode === 'undefined' || ngDevMode) {
168 if (!portal) {
169 throwNullPortalError();
170 }
171 if (this.hasAttached()) {
172 throwPortalAlreadyAttachedError();
173 }
174 if (this._isDisposed) {
175 throwPortalOutletAlreadyDisposedError();
176 }
177 }
178 if (portal instanceof ComponentPortal) {
179 this._attachedPortal = portal;
180 return this.attachComponentPortal(portal);
181 }
182 else if (portal instanceof TemplatePortal) {
183 this._attachedPortal = portal;
184 return this.attachTemplatePortal(portal);
185 // @breaking-change 10.0.0 remove null check for `this.attachDomPortal`.
186 }
187 else if (this.attachDomPortal && portal instanceof DomPortal) {
188 this._attachedPortal = portal;
189 return this.attachDomPortal(portal);
190 }
191 if (typeof ngDevMode === 'undefined' || ngDevMode) {
192 throwUnknownPortalTypeError();
193 }
194 }
195 /** Detaches a previously attached portal. */
196 detach() {
197 if (this._attachedPortal) {
198 this._attachedPortal.setAttachedHost(null);
199 this._attachedPortal = null;
200 }
201 this._invokeDisposeFn();
202 }
203 /** Permanently dispose of this portal host. */
204 dispose() {
205 if (this.hasAttached()) {
206 this.detach();
207 }
208 this._invokeDisposeFn();
209 this._isDisposed = true;
210 }
211 /** @docs-private */
212 setDisposeFn(fn) {
213 this._disposeFn = fn;
214 }
215 _invokeDisposeFn() {
216 if (this._disposeFn) {
217 this._disposeFn();
218 this._disposeFn = null;
219 }
220 }
221}
222/**
223 * @deprecated Use `BasePortalOutlet` instead.
224 * @breaking-change 9.0.0
225 */
226class BasePortalHost extends BasePortalOutlet {
227}
228
229/**
230 * A PortalOutlet for attaching portals to an arbitrary DOM element outside of the Angular
231 * application context.
232 */
233class DomPortalOutlet extends BasePortalOutlet {
234 /**
235 * @param outletElement Element into which the content is projected.
236 * @param _componentFactoryResolver Used to resolve the component factory.
237 * Only required when attaching component portals.
238 * @param _appRef Reference to the application. Only used in component portals when there
239 * is no `ViewContainerRef` available.
240 * @param _defaultInjector Injector to use as a fallback when the portal being attached doesn't
241 * have one. Only used for component portals.
242 * @param _document Reference to the document. Used when attaching a DOM portal. Will eventually
243 * become a required parameter.
244 */
245 constructor(
246 /** Element into which the content is projected. */
247 outletElement, _componentFactoryResolver, _appRef, _defaultInjector,
248 /**
249 * @deprecated `_document` Parameter to be made required.
250 * @breaking-change 10.0.0
251 */
252 _document) {
253 super();
254 this.outletElement = outletElement;
255 this._componentFactoryResolver = _componentFactoryResolver;
256 this._appRef = _appRef;
257 this._defaultInjector = _defaultInjector;
258 /**
259 * Attaches a DOM portal by transferring its content into the outlet.
260 * @param portal Portal to be attached.
261 * @deprecated To be turned into a method.
262 * @breaking-change 10.0.0
263 */
264 this.attachDomPortal = (portal) => {
265 // @breaking-change 10.0.0 Remove check and error once the
266 // `_document` constructor parameter is required.
267 if (!this._document && (typeof ngDevMode === 'undefined' || ngDevMode)) {
268 throw Error('Cannot attach DOM portal without _document constructor parameter');
269 }
270 const element = portal.element;
271 if (!element.parentNode && (typeof ngDevMode === 'undefined' || ngDevMode)) {
272 throw Error('DOM portal content must be attached to a parent node.');
273 }
274 // Anchor used to save the element's previous position so
275 // that we can restore it when the portal is detached.
276 const anchorNode = this._document.createComment('dom-portal');
277 element.parentNode.insertBefore(anchorNode, element);
278 this.outletElement.appendChild(element);
279 this._attachedPortal = portal;
280 super.setDisposeFn(() => {
281 // We can't use `replaceWith` here because IE doesn't support it.
282 if (anchorNode.parentNode) {
283 anchorNode.parentNode.replaceChild(element, anchorNode);
284 }
285 });
286 };
287 this._document = _document;
288 }
289 /**
290 * Attach the given ComponentPortal to DOM element using the ComponentFactoryResolver.
291 * @param portal Portal to be attached
292 * @returns Reference to the created component.
293 */
294 attachComponentPortal(portal) {
295 const resolver = (portal.componentFactoryResolver || this._componentFactoryResolver);
296 if ((typeof ngDevMode === 'undefined' || ngDevMode) && !resolver) {
297 throw Error('Cannot attach component portal to outlet without a ComponentFactoryResolver.');
298 }
299 const componentFactory = resolver.resolveComponentFactory(portal.component);
300 let componentRef;
301 // If the portal specifies a ViewContainerRef, we will use that as the attachment point
302 // for the component (in terms of Angular's component tree, not rendering).
303 // When the ViewContainerRef is missing, we use the factory to create the component directly
304 // and then manually attach the view to the application.
305 if (portal.viewContainerRef) {
306 componentRef = portal.viewContainerRef.createComponent(componentFactory, portal.viewContainerRef.length, portal.injector || portal.viewContainerRef.injector, portal.projectableNodes || undefined);
307 this.setDisposeFn(() => componentRef.destroy());
308 }
309 else {
310 if ((typeof ngDevMode === 'undefined' || ngDevMode) && !this._appRef) {
311 throw Error('Cannot attach component portal to outlet without an ApplicationRef.');
312 }
313 componentRef = componentFactory.create(portal.injector || this._defaultInjector || Injector.NULL);
314 this._appRef.attachView(componentRef.hostView);
315 this.setDisposeFn(() => {
316 // Verify that the ApplicationRef has registered views before trying to detach a host view.
317 // This check also protects the `detachView` from being called on a destroyed ApplicationRef.
318 if (this._appRef.viewCount > 0) {
319 this._appRef.detachView(componentRef.hostView);
320 }
321 componentRef.destroy();
322 });
323 }
324 // At this point the component has been instantiated, so we move it to the location in the DOM
325 // where we want it to be rendered.
326 this.outletElement.appendChild(this._getComponentRootNode(componentRef));
327 this._attachedPortal = portal;
328 return componentRef;
329 }
330 /**
331 * Attaches a template portal to the DOM as an embedded view.
332 * @param portal Portal to be attached.
333 * @returns Reference to the created embedded view.
334 */
335 attachTemplatePortal(portal) {
336 let viewContainer = portal.viewContainerRef;
337 let viewRef = viewContainer.createEmbeddedView(portal.templateRef, portal.context, {
338 injector: portal.injector,
339 });
340 // The method `createEmbeddedView` will add the view as a child of the viewContainer.
341 // But for the DomPortalOutlet the view can be added everywhere in the DOM
342 // (e.g Overlay Container) To move the view to the specified host element. We just
343 // re-append the existing root nodes.
344 viewRef.rootNodes.forEach(rootNode => this.outletElement.appendChild(rootNode));
345 // Note that we want to detect changes after the nodes have been moved so that
346 // any directives inside the portal that are looking at the DOM inside a lifecycle
347 // hook won't be invoked too early.
348 viewRef.detectChanges();
349 this.setDisposeFn(() => {
350 let index = viewContainer.indexOf(viewRef);
351 if (index !== -1) {
352 viewContainer.remove(index);
353 }
354 });
355 this._attachedPortal = portal;
356 // TODO(jelbourn): Return locals from view.
357 return viewRef;
358 }
359 /**
360 * Clears out a portal from the DOM.
361 */
362 dispose() {
363 super.dispose();
364 this.outletElement.remove();
365 }
366 /** Gets the root HTMLElement for an instantiated component. */
367 _getComponentRootNode(componentRef) {
368 return componentRef.hostView.rootNodes[0];
369 }
370}
371/**
372 * @deprecated Use `DomPortalOutlet` instead.
373 * @breaking-change 9.0.0
374 */
375class DomPortalHost extends DomPortalOutlet {
376}
377
378/**
379 * Directive version of a `TemplatePortal`. Because the directive *is* a TemplatePortal,
380 * the directive instance itself can be attached to a host, enabling declarative use of portals.
381 */
382class CdkPortal extends TemplatePortal {
383 constructor(templateRef, viewContainerRef) {
384 super(templateRef, viewContainerRef);
385 }
386 static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: CdkPortal, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); }
387 static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: CdkPortal, selector: "[cdkPortal]", exportAs: ["cdkPortal"], usesInheritance: true, ngImport: i0 }); }
388}
389i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: CdkPortal, decorators: [{
390 type: Directive,
391 args: [{
392 selector: '[cdkPortal]',
393 exportAs: 'cdkPortal',
394 }]
395 }], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }]; } });
396/**
397 * @deprecated Use `CdkPortal` instead.
398 * @breaking-change 9.0.0
399 */
400class TemplatePortalDirective extends CdkPortal {
401 static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: TemplatePortalDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
402 static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: TemplatePortalDirective, selector: "[cdk-portal], [portal]", providers: [
403 {
404 provide: CdkPortal,
405 useExisting: TemplatePortalDirective,
406 },
407 ], exportAs: ["cdkPortal"], usesInheritance: true, ngImport: i0 }); }
408}
409i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: TemplatePortalDirective, decorators: [{
410 type: Directive,
411 args: [{
412 selector: '[cdk-portal], [portal]',
413 exportAs: 'cdkPortal',
414 providers: [
415 {
416 provide: CdkPortal,
417 useExisting: TemplatePortalDirective,
418 },
419 ],
420 }]
421 }] });
422/**
423 * Directive version of a PortalOutlet. Because the directive *is* a PortalOutlet, portals can be
424 * directly attached to it, enabling declarative use.
425 *
426 * Usage:
427 * `<ng-template [cdkPortalOutlet]="greeting"></ng-template>`
428 */
429class CdkPortalOutlet extends BasePortalOutlet {
430 constructor(_componentFactoryResolver, _viewContainerRef,
431 /**
432 * @deprecated `_document` parameter to be made required.
433 * @breaking-change 9.0.0
434 */
435 _document) {
436 super();
437 this._componentFactoryResolver = _componentFactoryResolver;
438 this._viewContainerRef = _viewContainerRef;
439 /** Whether the portal component is initialized. */
440 this._isInitialized = false;
441 /** Emits when a portal is attached to the outlet. */
442 this.attached = new EventEmitter();
443 /**
444 * Attaches the given DomPortal to this PortalHost by moving all of the portal content into it.
445 * @param portal Portal to be attached.
446 * @deprecated To be turned into a method.
447 * @breaking-change 10.0.0
448 */
449 this.attachDomPortal = (portal) => {
450 // @breaking-change 9.0.0 Remove check and error once the
451 // `_document` constructor parameter is required.
452 if (!this._document && (typeof ngDevMode === 'undefined' || ngDevMode)) {
453 throw Error('Cannot attach DOM portal without _document constructor parameter');
454 }
455 const element = portal.element;
456 if (!element.parentNode && (typeof ngDevMode === 'undefined' || ngDevMode)) {
457 throw Error('DOM portal content must be attached to a parent node.');
458 }
459 // Anchor used to save the element's previous position so
460 // that we can restore it when the portal is detached.
461 const anchorNode = this._document.createComment('dom-portal');
462 portal.setAttachedHost(this);
463 element.parentNode.insertBefore(anchorNode, element);
464 this._getRootNode().appendChild(element);
465 this._attachedPortal = portal;
466 super.setDisposeFn(() => {
467 if (anchorNode.parentNode) {
468 anchorNode.parentNode.replaceChild(element, anchorNode);
469 }
470 });
471 };
472 this._document = _document;
473 }
474 /** Portal associated with the Portal outlet. */
475 get portal() {
476 return this._attachedPortal;
477 }
478 set portal(portal) {
479 // Ignore the cases where the `portal` is set to a falsy value before the lifecycle hooks have
480 // run. This handles the cases where the user might do something like `<div cdkPortalOutlet>`
481 // and attach a portal programmatically in the parent component. When Angular does the first CD
482 // round, it will fire the setter with empty string, causing the user's content to be cleared.
483 if (this.hasAttached() && !portal && !this._isInitialized) {
484 return;
485 }
486 if (this.hasAttached()) {
487 super.detach();
488 }
489 if (portal) {
490 super.attach(portal);
491 }
492 this._attachedPortal = portal || null;
493 }
494 /** Component or view reference that is attached to the portal. */
495 get attachedRef() {
496 return this._attachedRef;
497 }
498 ngOnInit() {
499 this._isInitialized = true;
500 }
501 ngOnDestroy() {
502 super.dispose();
503 this._attachedRef = this._attachedPortal = null;
504 }
505 /**
506 * Attach the given ComponentPortal to this PortalOutlet using the ComponentFactoryResolver.
507 *
508 * @param portal Portal to be attached to the portal outlet.
509 * @returns Reference to the created component.
510 */
511 attachComponentPortal(portal) {
512 portal.setAttachedHost(this);
513 // If the portal specifies an origin, use that as the logical location of the component
514 // in the application tree. Otherwise use the location of this PortalOutlet.
515 const viewContainerRef = portal.viewContainerRef != null ? portal.viewContainerRef : this._viewContainerRef;
516 const resolver = portal.componentFactoryResolver || this._componentFactoryResolver;
517 const componentFactory = resolver.resolveComponentFactory(portal.component);
518 const ref = viewContainerRef.createComponent(componentFactory, viewContainerRef.length, portal.injector || viewContainerRef.injector, portal.projectableNodes || undefined);
519 // If we're using a view container that's different from the injected one (e.g. when the portal
520 // specifies its own) we need to move the component into the outlet, otherwise it'll be rendered
521 // inside of the alternate view container.
522 if (viewContainerRef !== this._viewContainerRef) {
523 this._getRootNode().appendChild(ref.hostView.rootNodes[0]);
524 }
525 super.setDisposeFn(() => ref.destroy());
526 this._attachedPortal = portal;
527 this._attachedRef = ref;
528 this.attached.emit(ref);
529 return ref;
530 }
531 /**
532 * Attach the given TemplatePortal to this PortalHost as an embedded View.
533 * @param portal Portal to be attached.
534 * @returns Reference to the created embedded view.
535 */
536 attachTemplatePortal(portal) {
537 portal.setAttachedHost(this);
538 const viewRef = this._viewContainerRef.createEmbeddedView(portal.templateRef, portal.context, {
539 injector: portal.injector,
540 });
541 super.setDisposeFn(() => this._viewContainerRef.clear());
542 this._attachedPortal = portal;
543 this._attachedRef = viewRef;
544 this.attached.emit(viewRef);
545 return viewRef;
546 }
547 /** Gets the root node of the portal outlet. */
548 _getRootNode() {
549 const nativeElement = this._viewContainerRef.element.nativeElement;
550 // The directive could be set on a template which will result in a comment
551 // node being the root. Use the comment's parent node if that is the case.
552 return (nativeElement.nodeType === nativeElement.ELEMENT_NODE
553 ? nativeElement
554 : nativeElement.parentNode);
555 }
556 static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: CdkPortalOutlet, deps: [{ token: i0.ComponentFactoryResolver }, { token: i0.ViewContainerRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); }
557 static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: { portal: ["cdkPortalOutlet", "portal"] }, outputs: { attached: "attached" }, exportAs: ["cdkPortalOutlet"], usesInheritance: true, ngImport: i0 }); }
558}
559i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: CdkPortalOutlet, decorators: [{
560 type: Directive,
561 args: [{
562 selector: '[cdkPortalOutlet]',
563 exportAs: 'cdkPortalOutlet',
564 inputs: ['portal: cdkPortalOutlet'],
565 }]
566 }], ctorParameters: function () { return [{ type: i0.ComponentFactoryResolver }, { type: i0.ViewContainerRef }, { type: undefined, decorators: [{
567 type: Inject,
568 args: [DOCUMENT]
569 }] }]; }, propDecorators: { attached: [{
570 type: Output
571 }] } });
572/**
573 * @deprecated Use `CdkPortalOutlet` instead.
574 * @breaking-change 9.0.0
575 */
576class PortalHostDirective extends CdkPortalOutlet {
577 static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: PortalHostDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
578 static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: PortalHostDirective, selector: "[cdkPortalHost], [portalHost]", inputs: { portal: ["cdkPortalHost", "portal"] }, providers: [
579 {
580 provide: CdkPortalOutlet,
581 useExisting: PortalHostDirective,
582 },
583 ], exportAs: ["cdkPortalHost"], usesInheritance: true, ngImport: i0 }); }
584}
585i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: PortalHostDirective, decorators: [{
586 type: Directive,
587 args: [{
588 selector: '[cdkPortalHost], [portalHost]',
589 exportAs: 'cdkPortalHost',
590 inputs: ['portal: cdkPortalHost'],
591 providers: [
592 {
593 provide: CdkPortalOutlet,
594 useExisting: PortalHostDirective,
595 },
596 ],
597 }]
598 }] });
599class PortalModule {
600 static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: PortalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
601 static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.0.0", ngImport: i0, type: PortalModule, declarations: [CdkPortal, CdkPortalOutlet, TemplatePortalDirective, PortalHostDirective], exports: [CdkPortal, CdkPortalOutlet, TemplatePortalDirective, PortalHostDirective] }); }
602 static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: PortalModule }); }
603}
604i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: PortalModule, decorators: [{
605 type: NgModule,
606 args: [{
607 exports: [CdkPortal, CdkPortalOutlet, TemplatePortalDirective, PortalHostDirective],
608 declarations: [CdkPortal, CdkPortalOutlet, TemplatePortalDirective, PortalHostDirective],
609 }]
610 }] });
611
612/**
613 * Custom injector to be used when providing custom
614 * injection tokens to components inside a portal.
615 * @docs-private
616 * @deprecated Use `Injector.create` instead.
617 * @breaking-change 11.0.0
618 */
619class PortalInjector {
620 constructor(_parentInjector, _customTokens) {
621 this._parentInjector = _parentInjector;
622 this._customTokens = _customTokens;
623 }
624 get(token, notFoundValue) {
625 const value = this._customTokens.get(token);
626 if (typeof value !== 'undefined') {
627 return value;
628 }
629 return this._parentInjector.get(token, notFoundValue);
630 }
631}
632
633/**
634 * Generated bundle index. Do not edit.
635 */
636
637export { BasePortalHost, BasePortalOutlet, CdkPortal, CdkPortalOutlet, ComponentPortal, DomPortal, DomPortalHost, DomPortalOutlet, Portal, PortalHostDirective, PortalInjector, PortalModule, TemplatePortal, TemplatePortalDirective };
638//# sourceMappingURL=portal.mjs.map