source: trip-planner-front/node_modules/@angular/cdk/fesm2015/portal.js@ eed0bf8

Last change on this file since eed0bf8 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

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