UNPKG

@angular-mdc/web

Version:
1,257 lines (1,239 loc) 56.5 kB
/** * @license * Copyright (c) Dominic Carretto * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/trimox/angular-mdc-web/blob/master/LICENSE */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/cdk/overlay'), require('@angular/cdk/portal'), require('@angular/cdk/platform'), require('rxjs'), require('rxjs/operators'), require('@angular-mdc/web/base'), require('@angular/cdk/coercion'), require('@angular-mdc/web/button'), require('@angular-mdc/web/ripple'), require('@angular-mdc/web/dom'), require('@material/dialog'), require('@angular/common'), require('@angular/cdk/a11y')) : typeof define === 'function' && define.amd ? define('@angular-mdc/web/dialog', ['exports', '@angular/core', '@angular/cdk/overlay', '@angular/cdk/portal', '@angular/cdk/platform', 'rxjs', 'rxjs/operators', '@angular-mdc/web/base', '@angular/cdk/coercion', '@angular-mdc/web/button', '@angular-mdc/web/ripple', '@angular-mdc/web/dom', '@material/dialog', '@angular/common', '@angular/cdk/a11y'], factory) : (global = global || self, factory((global.ng = global.ng || {}, global.ng.web = global.ng.web || {}, global.ng.web.dialog = {}), global.ng.core, global.ng.cdk.overlay, global.ng.cdk.portal, global.ng.cdk.platform, global.rxjs, global.rxjs.operators, global.ng.web.base, global.ng.cdk.coercion, global.ng.web.button, global.ng.web.ripple, global.ng.web.dom, global.mdc.dialog, global.ng.common, global.ng.cdk.a11y)); }(this, (function (exports, core, overlay, portal, platform, rxjs, operators, base, coercion, button, ripple, dom, dialog, common, a11y) { 'use strict'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var _extendStatics = function extendStatics(d, b) { _extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; } || function (d, b) { for (var p in b) { if (b.hasOwnProperty(p)) d[p] = b[p]; } }; return _extendStatics(d, b); }; function __extends(d, b) { _extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var _assign = function __assign() { _assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) { if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } } return t; }; return _assign.apply(this, arguments); }; /** * @fileoverview added by tsickle * Generated from: dialog/dialog-directives.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ var MdcDialogAction = /** @class */ (function () { function MdcDialogAction(elementRef) { this.elementRef = elementRef; this._action = ''; } Object.defineProperty(MdcDialogAction.prototype, "action", { get: /** * @return {?} */ function () { return this._action; }, set: /** * @param {?} action * @return {?} */ function (action) { // If the directive is set without a name (updated programatically), then this setter will // trigger with an empty string and should not overwrite the programatically set value. if (!action) { return; } this._action = action; this.elementRef.nativeElement.setAttribute('data-mdc-dialog-action', this._action); }, enumerable: true, configurable: true }); MdcDialogAction.decorators = [ { type: core.Directive, args: [{ selector: '[mdcDialogAction]' },] }, ]; /** @nocollapse */ MdcDialogAction.ctorParameters = function () { return [ { type: core.ElementRef } ]; }; MdcDialogAction.propDecorators = { action: [{ type: core.Input, args: ['mdcDialogAction',] }] }; return MdcDialogAction; }()); var MdcDialogScrim = /** @class */ (function () { function MdcDialogScrim(elementRef) { this.elementRef = elementRef; } MdcDialogScrim.decorators = [ { type: core.Directive, args: [{ selector: 'mdc-dialog-scrim', host: { 'class': 'mdc-dialog__scrim' } },] }, ]; /** @nocollapse */ MdcDialogScrim.ctorParameters = function () { return [ { type: core.ElementRef } ]; }; return MdcDialogScrim; }()); var MdcDialogContainer = /** @class */ (function () { function MdcDialogContainer(elementRef) { this.elementRef = elementRef; } MdcDialogContainer.decorators = [ { type: core.Directive, args: [{ selector: '[mdcDialogContainer], mdc-dialog-container', host: { 'class': 'mdc-dialog__container' } },] }, ]; /** @nocollapse */ MdcDialogContainer.ctorParameters = function () { return [ { type: core.ElementRef } ]; }; return MdcDialogContainer; }()); var MdcDialogSurface = /** @class */ (function () { function MdcDialogSurface(elementRef) { this.elementRef = elementRef; } MdcDialogSurface.decorators = [ { type: core.Directive, args: [{ selector: '[mdcDialogSurface], mdc-dialog-surface', host: { 'class': 'mdc-dialog__surface' } },] }, ]; /** @nocollapse */ MdcDialogSurface.ctorParameters = function () { return [ { type: core.ElementRef } ]; }; return MdcDialogSurface; }()); var MdcDialogTitle = /** @class */ (function () { function MdcDialogTitle(elementRef) { this.elementRef = elementRef; } MdcDialogTitle.decorators = [ { type: core.Directive, args: [{ selector: '[mdcDialogTitle], mdc-dialog-title', host: { 'class': 'mdc-dialog__title' } },] }, ]; /** @nocollapse */ MdcDialogTitle.ctorParameters = function () { return [ { type: core.ElementRef } ]; }; return MdcDialogTitle; }()); var MdcDialogContent = /** @class */ (function () { function MdcDialogContent(elementRef) { this.elementRef = elementRef; } MdcDialogContent.decorators = [ { type: core.Directive, args: [{ selector: '[mdcDialogContent], mdc-dialog-content', host: { 'class': 'mdc-dialog__content' } },] }, ]; /** @nocollapse */ MdcDialogContent.ctorParameters = function () { return [ { type: core.ElementRef } ]; }; return MdcDialogContent; }()); var MdcDialogActions = /** @class */ (function () { function MdcDialogActions(elementRef) { this.elementRef = elementRef; this._stacked = false; } Object.defineProperty(MdcDialogActions.prototype, "stacked", { get: /** * @return {?} */ function () { return this._stacked; }, set: /** * @param {?} value * @return {?} */ function (value) { this._stacked = coercion.coerceBooleanProperty(value); }, enumerable: true, configurable: true }); MdcDialogActions.decorators = [ { type: core.Component, args: [{selector: 'mdc-dialog-actions, [mdcDialogActions]', template: '<ng-content></ng-content>', exportAs: 'mdcDialogActions', host: { 'class': 'mdc-dialog__actions', '[class.mdc-dialog--stacked]': 'stacked' }, encapsulation: core.ViewEncapsulation.None, changeDetection: core.ChangeDetectionStrategy.OnPush },] }, ]; /** @nocollapse */ MdcDialogActions.ctorParameters = function () { return [ { type: core.ElementRef } ]; }; MdcDialogActions.propDecorators = { stacked: [{ type: core.Input }] }; return MdcDialogActions; }()); var MdcDialogButton = /** @class */ (function (_super) { __extends(MdcDialogButton, _super); function MdcDialogButton() { var _this = _super !== null && _super.apply(this, arguments) || this; _this._default = false; return _this; } Object.defineProperty(MdcDialogButton.prototype, "default", { get: /** * @return {?} */ function () { return this._default; }, set: /** * @param {?} value * @return {?} */ function (value) { this._default = coercion.coerceBooleanProperty(value); }, enumerable: true, configurable: true }); MdcDialogButton.decorators = [ { type: core.Component, args: [{selector: '[mdcDialogButton]', exportAs: 'mdcDialogButton', host: { 'class': 'mdc-dialog__button', '[class.mdc-button]': 'true', '[class.mdc-dialog__button--default]': 'default' }, template: "\n <div class=\"mdc-button__ripple\"></div>\n <ng-content></ng-content>", providers: [ripple.MdcRipple], encapsulation: core.ViewEncapsulation.None, changeDetection: core.ChangeDetectionStrategy.OnPush },] }, ]; MdcDialogButton.propDecorators = { default: [{ type: core.Input }] }; return MdcDialogButton; }(button.MdcButton)); /** * @fileoverview added by tsickle * Generated from: dialog/dialog-ref.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Unique id for the created dialog. * @type {?} */ var uniqueId = 0; /** * Reference to a dialog dispatched from the MdcDialog service. * @template T, R */ var /** * Reference to a dialog dispatched from the MdcDialog service. * @template T, R */ MdcDialogRef = /** @class */ (function () { function MdcDialogRef(_overlayRef, _portalInstance, id) { var _this = this; if (id === void 0) { id = "mdc-dialog-" + uniqueId++; } this._overlayRef = _overlayRef; this._portalInstance = _portalInstance; this.id = id; /** * Subject for notifying the user that the dialog has finished opening. */ this._afterOpened = new rxjs.Subject(); /** * Subject for notifying the user that the dialog has started closing. */ this._beforeClosed = new rxjs.Subject(); /** * Subject for notifying the user that the dialog has finished closing. */ this._afterClosed = new rxjs.Subject(); // Pass the id along to the portal. _portalInstance._id = id; _overlayRef.detachments().subscribe((/** * @return {?} */ function () { _this._beforeClosed.next(_this._result); _this._beforeClosed.complete(); _this._afterClosed.next(_this._result); _this._afterClosed.complete(); _this.componentInstance = (/** @type {?} */ (null)); _this._overlayRef.dispose(); })); } /** * Close the dialog. * @param dialogResult Optional result to return to the dialog opener. */ /** * Close the dialog. * @param {?=} dialogResult Optional result to return to the dialog opener. * @return {?} */ MdcDialogRef.prototype.close = /** * Close the dialog. * @param {?=} dialogResult Optional result to return to the dialog opener. * @return {?} */ function (dialogResult) { this._result = dialogResult; this._overlayRef.dispose(); }; /** Marks the dialog as opened. */ /** * Marks the dialog as opened. * @return {?} */ MdcDialogRef.prototype.opened = /** * Marks the dialog as opened. * @return {?} */ function () { if (!this._afterOpened.closed) { this._afterOpened.next(); this._afterOpened.complete(); } }; /** Gets an observable that is notified when the dialog is finished opening. */ /** * Gets an observable that is notified when the dialog is finished opening. * @return {?} */ MdcDialogRef.prototype.afterOpened = /** * Gets an observable that is notified when the dialog is finished opening. * @return {?} */ function () { return this._afterOpened.asObservable(); }; /** Gets an observable that is notified when the dialog has started closing. */ /** * Gets an observable that is notified when the dialog has started closing. * @return {?} */ MdcDialogRef.prototype.beforeClosed = /** * Gets an observable that is notified when the dialog has started closing. * @return {?} */ function () { return this._beforeClosed.asObservable(); }; /** Gets an observable that is notified when the dialog is finished closing. */ /** * Gets an observable that is notified when the dialog is finished closing. * @return {?} */ MdcDialogRef.prototype.afterClosed = /** * Gets an observable that is notified when the dialog is finished closing. * @return {?} */ function () { return this._afterClosed.asObservable(); }; return MdcDialogRef; }()); /** * @fileoverview added by tsickle * Generated from: dialog/dialog.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ var LAYOUT_EVENTS = ['resize', 'orientationchange']; var MdcDialogComponent = /** @class */ (function (_super) { __extends(MdcDialogComponent, _super); function MdcDialogComponent(_ngZone, _platform, elementRef, dialogRef) { var _this = _super.call(this, elementRef) || this; _this._ngZone = _ngZone; _this._platform = _platform; _this.elementRef = elementRef; _this.dialogRef = dialogRef; /** * Emits whenever the component is destroyed. */ _this._destroy = new rxjs.Subject(); _this._scrollable = true; _this._layoutEventSubscription = null; _this.config = dialogRef._portalInstance._config; return _this; } Object.defineProperty(MdcDialogComponent.prototype, "layoutEvents", { /** Combined stream of all of the dialog layout events. */ get: /** * Combined stream of all of the dialog layout events. * @return {?} */ function () { return rxjs.merge.apply(void 0, LAYOUT_EVENTS.map((/** * @param {?} evt * @return {?} */ function (evt) { return rxjs.fromEvent(window, evt); }))); }, enumerable: true, configurable: true }); /** * @return {?} */ MdcDialogComponent.prototype.getDefaultFoundation = /** * @return {?} */ function () { var _this = this; /** @type {?} */ var adapter = { addClass: (/** * @param {?} className * @return {?} */ function (className) { return _this._getDialog().classList.add(className); }), removeClass: (/** * @param {?} className * @return {?} */ function (className) { return _this._getDialog().classList.remove(className); }), getInitialFocusEl: (/** * @return {?} */ function () { return _this._platform.isBrowser ? (/** @type {?} */ (document.querySelector("[cdkFocusInitial]"))) : null; }), hasClass: (/** * @param {?} className * @return {?} */ function (className) { return _this._getDialog().classList.contains(className); }), addBodyClass: (/** * @param {?} className * @return {?} */ function (className) { if (_this._platform.isBrowser) { (/** @type {?} */ (document.body)).classList.add(className); } }), removeBodyClass: (/** * @param {?} className * @return {?} */ function (className) { if (_this._platform.isBrowser) { (/** @type {?} */ (document.body)).classList.remove(className); } }), eventTargetMatches: (/** * @param {?} target * @param {?} selector * @return {?} */ function (target, selector) { return dom.matches((/** @type {?} */ (target)), selector); }), trapFocus: (/** * @return {?} */ function () { }), releaseFocus: (/** * @return {?} */ function () { }), isContentScrollable: (/** * @return {?} */ function () { return !!_this._content && _this._scrollable && dialog.util.isScrollable(_this._content.elementRef.nativeElement); }), areButtonsStacked: (/** * @return {?} */ function () { return dialog.util.areTopsMisaligned((/** @type {?} */ (_this._buttons))); }), getActionFromEvent: (/** * @param {?} event * @return {?} */ function (event) { /** @type {?} */ var element = dom.closest((/** @type {?} */ (event.target)), "[" + dialog.strings.ACTION_ATTRIBUTE + "]"); return element && element.getAttribute(dialog.strings.ACTION_ATTRIBUTE); }), clickDefaultButton: (/** * @return {?} */ function () { var _a, _b, _c; /** @type {?} */ var defaultBtn = _this._buttons.find((/** * @param {?} _ * @return {?} */ function (_) { return _.default; })); (_c = (_b = (_a = defaultBtn) === null || _a === void 0 ? void 0 : _a.elementRef) === null || _b === void 0 ? void 0 : _b.nativeElement) === null || _c === void 0 ? void 0 : _c.click(); }), reverseButtons: (/** * @return {?} */ function () { _this._buttons.toArray().reverse(); _this._buttons.forEach((/** * @param {?} button * @return {?} */ function (button) { return (/** @type {?} */ (button.getHostElement().parentElement)).appendChild(button.getHostElement()); })); }), notifyOpened: (/** * @return {?} */ function () { return _this.dialogRef.opened(); }), notifyOpening: (/** * @return {?} */ function () { }), notifyClosed: (/** * @param {?} action * @return {?} */ function (action) { return _this._closeDialogByRef(action); }), notifyClosing: (/** * @return {?} */ function () { }) }; return new dialog.MDCDialogFoundation(adapter); }; /** * @return {?} */ MdcDialogComponent.prototype.ngAfterViewInit = /** * @return {?} */ function () { this._foundation = this.getDefaultFoundation(); this._initialize(); this._loadListeners(); this._foundation.open(); }; /** * @private * @return {?} */ MdcDialogComponent.prototype._initialize = /** * @private * @return {?} */ function () { this._scrollable = !!this.config.scrollable; if (!this.config.clickOutsideToClose) { this._foundation.setScrimClickAction(''); } if (!this.config.escapeToClose) { this._foundation.setEscapeKeyAction(''); } if (!this.config.buttonsStacked) { this._foundation.setAutoStackButtons(false); } }; /** * @return {?} */ MdcDialogComponent.prototype.ngOnDestroy = /** * @return {?} */ function () { var _a, _b; this._destroy.next(); this._destroy.complete(); (_a = this._layoutEventSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe(); (_b = this._foundation) === null || _b === void 0 ? void 0 : _b.destroy(); }; /** Recalculates layout and automatically adds/removes modifier classes like --scrollable. */ /** * Recalculates layout and automatically adds/removes modifier classes like --scrollable. * @return {?} */ MdcDialogComponent.prototype.layout = /** * Recalculates layout and automatically adds/removes modifier classes like --scrollable. * @return {?} */ function () { this._foundation.layout(); }; /** * @param {?} evt * @return {?} */ MdcDialogComponent.prototype._onKeydown = /** * @param {?} evt * @return {?} */ function (evt) { this._foundation.handleKeydown(evt); }; /** * @param {?} evt * @return {?} */ MdcDialogComponent.prototype._onClick = /** * @param {?} evt * @return {?} */ function (evt) { this._foundation.handleClick(evt); }; /** * @private * @param {?=} action * @return {?} */ MdcDialogComponent.prototype._closeDialogByRef = /** * @private * @param {?=} action * @return {?} */ function (action) { this.dialogRef.close(action); }; /** * @private * @return {?} */ MdcDialogComponent.prototype._loadListeners = /** * @private * @return {?} */ function () { var _this = this; this._layoutEventSubscription = this.layoutEvents.pipe() .subscribe((/** * @return {?} */ function () { return _this.layout(); })); if (this._platform.isBrowser) { this._ngZone.runOutsideAngular((/** * @return {?} */ function () { return rxjs.fromEvent(document, 'keydown').pipe(operators.takeUntil(_this._destroy)) .subscribe((/** * @param {?} evt * @return {?} */ function (evt) { return _this._ngZone.run((/** * @return {?} */ function () { return _this._foundation.handleDocumentKeydown(evt); })); })); })); } }; /** Retrieves the DOM element of the component host. */ /** * Retrieves the DOM element of the component host. * @private * @return {?} */ MdcDialogComponent.prototype._getDialog = /** * Retrieves the DOM element of the component host. * @private * @return {?} */ function () { return this._elementRef.nativeElement; }; MdcDialogComponent.decorators = [ { type: core.Component, args: [{selector: 'mdc-dialog', exportAs: 'mdc-dialog', host: { '[attr.id]': 'config?.id', 'role': 'alertdialog', 'class': 'mdc-dialog', '[attr.aria-modal]': 'true', '[attr.aria-labelledby]': 'config?.ariaLabel', '[attr.aria-label]': 'config?.ariaLabel', '[attr.aria-describedby]': 'config?.ariaDescribedBy || null', '(click)': '_onClick($event)', '(keydown)': '_onKeydown($event)' }, template: "\n <mdc-dialog-scrim></mdc-dialog-scrim>\n <ng-content></ng-content>", encapsulation: core.ViewEncapsulation.None, changeDetection: core.ChangeDetectionStrategy.OnPush },] }, ]; /** @nocollapse */ MdcDialogComponent.ctorParameters = function () { return [ { type: core.NgZone }, { type: platform.Platform }, { type: core.ElementRef }, { type: MdcDialogRef } ]; }; MdcDialogComponent.propDecorators = { _surface: [{ type: core.ContentChild, args: [MdcDialogSurface, { static: false },] }], _content: [{ type: core.ContentChild, args: [MdcDialogContent, { static: false },] }], _buttons: [{ type: core.ContentChildren, args: [MdcDialogButton, { descendants: true },] }] }; return MdcDialogComponent; }(base.MDCComponent)); /** * @fileoverview added by tsickle * Generated from: dialog/dialog-config.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @template D */ var /** * @template D */ MdcDialogConfig = /** @class */ (function () { function MdcDialogConfig() { /** * ID of the element that describes the dialog. */ this.ariaDescribedBy = null; /** * Aria label to assign to the dialog element */ this.ariaLabel = null; /** * Whether the user can use escape key to close the dialog */ this.escapeToClose = true; /** * Whether the user can click outside to close the dialog */ this.clickOutsideToClose = true; /** * Applied automatically when the dialog has overflowing content to warrant scrolling. */ this.scrollable = true; /** * Applied automatically when the dialog's action buttons can't fit on a single line and must be stacked. */ this.buttonsStacked = true; /** * Whether the dialog should focus the first focusable element on open. */ this.autoFocus = true; /** * Whether the dialog should restore focus to the * previously-focused element, after it's closed. */ this.restoreFocus = true; /** * Data to be injected into the dialog content. */ this.data = null; } return MdcDialogConfig; }()); /** * @fileoverview added by tsickle * Generated from: dialog/dialog-portal.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Throws an exception for the case when a ComponentPortal is * attached to a DomPortalOutlet without an origin. * @return {?} */ function throwMdcDialogContentAlreadyAttachedError() { throw Error('Attempting to attach dialog content after content is already attached'); } var MdcDialogPortal = /** @class */ (function (_super) { __extends(MdcDialogPortal, _super); function MdcDialogPortal(_elementRef, _focusTrapFactory, _document, _config) { var _this = _super.call(this) || this; _this._elementRef = _elementRef; _this._focusTrapFactory = _focusTrapFactory; _this._document = _document; _this._config = _config; /** * Element that was focused before the dialog was opened. Save this to restore upon close. */ _this._elementFocusedBeforeDialogWasOpened = null; /** * A subject emitting after the dialog exits the view. */ _this._afterExit = new rxjs.Subject(); return _this; } /** * Attach a ComponentPortal as content to this dialog container. * @param portal Portal to be attached as the dialog content. */ /** * Attach a ComponentPortal as content to this dialog container. * @template T * @param {?} portal Portal to be attached as the dialog content. * @return {?} */ MdcDialogPortal.prototype.attachComponentPortal = /** * Attach a ComponentPortal as content to this dialog container. * @template T * @param {?} portal Portal to be attached as the dialog content. * @return {?} */ function (portal) { if (this._portalOutlet.hasAttached()) { throwMdcDialogContentAlreadyAttachedError(); } this._savePreviouslyFocusedElement(); return this._portalOutlet.attachComponentPortal(portal); }; /** * Attach a TemplatePortal as content to this dialog container. * @param portal Portal to be attached as the dialog content. */ /** * Attach a TemplatePortal as content to this dialog container. * @template C * @param {?} portal Portal to be attached as the dialog content. * @return {?} */ MdcDialogPortal.prototype.attachTemplatePortal = /** * Attach a TemplatePortal as content to this dialog container. * @template C * @param {?} portal Portal to be attached as the dialog content. * @return {?} */ function (portal) { if (this._portalOutlet.hasAttached()) { throwMdcDialogContentAlreadyAttachedError(); } this._savePreviouslyFocusedElement(); return this._portalOutlet.attachTemplatePortal(portal); }; /** Moves the focus inside the focus trap. */ /** * Moves the focus inside the focus trap. * @return {?} */ MdcDialogPortal.prototype.trapFocus = /** * Moves the focus inside the focus trap. * @return {?} */ function () { /** @type {?} */ var element = this._elementRef.nativeElement; if (!this._focusTrap) { this._focusTrap = this._focusTrapFactory.create(element); } // If we were to attempt to focus immediately, then the content of the dialog would not yet be // ready in instances where change detection has to run first. To deal with this, we simply // wait for the microtask queue to be empty. if (this._config.autoFocus) { this._focusTrap.focusInitialElementWhenReady(); } else { /** @type {?} */ var activeElement = this._document.activeElement; // Otherwise ensure that focus is on the dialog container. It's possible that a different // component tried to move focus. Note that we only want to do this // if the focus isn't inside the dialog already, because it's possible that the consumer // turned off `autoFocus` in order to move focus themselves. if (activeElement !== element && !element.contains(activeElement)) { element.focus(); } } }; /** Restores focus to the element that was focused before the dialog opened. */ /** * Restores focus to the element that was focused before the dialog opened. * @return {?} */ MdcDialogPortal.prototype.restoreFocus = /** * Restores focus to the element that was focused before the dialog opened. * @return {?} */ function () { /** @type {?} */ var toFocus = this._elementFocusedBeforeDialogWasOpened; // We need the extra check, because IE can set the `activeElement` to null in some cases. if (this._config.restoreFocus && toFocus && typeof toFocus.focus === 'function') { toFocus.focus(); } if (this._focusTrap) { this._focusTrap.destroy(); } }; /** Saves a reference to the element that was focused before the dialog was opened. */ /** * Saves a reference to the element that was focused before the dialog was opened. * @private * @return {?} */ MdcDialogPortal.prototype._savePreviouslyFocusedElement = /** * Saves a reference to the element that was focused before the dialog was opened. * @private * @return {?} */ function () { var _this = this; if (this._document) { this._elementFocusedBeforeDialogWasOpened = (/** @type {?} */ (this._document.activeElement)); // Note that there is no focus method when rendering on the server. if (this._elementRef.nativeElement.focus) { // Move focus onto the dialog immediately in order to prevent the user from accidentally // opening multiple dialogs at the same time. Needs to be async, because the element // may not be focusable immediately. Promise.resolve().then((/** * @return {?} */ function () { return _this._elementRef.nativeElement.focus(); })); } } }; MdcDialogPortal.decorators = [ { type: core.Component, args: [{selector: 'mdc-dialog-portal', host: { '[attr.id]': '_id' }, template: '<ng-template cdkPortalOutlet></ng-template>', encapsulation: core.ViewEncapsulation.None },] }, ]; /** @nocollapse */ MdcDialogPortal.ctorParameters = function () { return [ { type: core.ElementRef }, { type: a11y.FocusTrapFactory }, { type: undefined, decorators: [{ type: core.Optional }, { type: core.Inject, args: [common.DOCUMENT,] }] }, { type: MdcDialogConfig } ]; }; MdcDialogPortal.propDecorators = { _portalOutlet: [{ type: core.ViewChild, args: [portal.CdkPortalOutlet, { static: true },] }] }; return MdcDialogPortal; }(portal.BasePortalOutlet)); /** * @fileoverview added by tsickle * Generated from: dialog/dialog.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Injection token that can be used to access the data that was passed in to a dialog. * @type {?} */ var MDC_DIALOG_DATA = new core.InjectionToken('MdcDialogData'); /** * Injection token that can be used to specify default dialog options. * @type {?} */ var MDC_DIALOG_DEFAULT_OPTIONS = new core.InjectionToken('mdc-dialog-default-options'); var MdcDialog = /** @class */ (function () { function MdcDialog(_overlay, _injector, _defaultOptions, _parentDialog) { var _this = this; this._overlay = _overlay; this._injector = _injector; this._defaultOptions = _defaultOptions; this._parentDialog = _parentDialog; this._openDialogsAtThisLevel = []; this._afterAllClosedAtThisLevel = new rxjs.Subject(); this._afterOpenedAtThisLevel = new rxjs.Subject(); this._ariaHiddenElements = new Map(); /** * Stream that emits when all open dialog have finished closing. * Will emit on subscribe if there are no open dialogs to begin with. */ this.afterAllClosed = (/** @type {?} */ (rxjs.defer((/** * @return {?} */ function () { return _this.openDialogs.length ? _this._afterAllClosed : _this._afterAllClosed.pipe(operators.startWith(undefined)); })))); } Object.defineProperty(MdcDialog.prototype, "openDialogs", { /** Keeps track of the currently-open dialogs. */ get: /** * Keeps track of the currently-open dialogs. * @return {?} */ function () { return this._parentDialog ? this._parentDialog.openDialogs : this._openDialogsAtThisLevel; }, enumerable: true, configurable: true }); Object.defineProperty(MdcDialog.prototype, "afterOpened", { /** Stream that emits when a dialog has been opened. */ get: /** * Stream that emits when a dialog has been opened. * @return {?} */ function () { return this._parentDialog ? this._parentDialog.afterOpened : this._afterOpenedAtThisLevel; }, enumerable: true, configurable: true }); Object.defineProperty(MdcDialog.prototype, "_afterAllClosed", { get: /** * @return {?} */ function () { /** @type {?} */ var parent = this._parentDialog; return parent ? parent._afterAllClosed : this._afterAllClosedAtThisLevel; }, enumerable: true, configurable: true }); /** * Opens a modal dialog containing the given template. * @param componentOrTemplateRef Type of the component to load into the dialog, * or a TemplateRef to instantiate as the dialog content. * @param config Extra configuration options. * @returns Reference to the newly-opened dialog. */ /** * Opens a modal dialog containing the given template. * @template T, D, R * @param {?} componentOrTemplateRef Type of the component to load into the dialog, * or a TemplateRef to instantiate as the dialog content. * @param {?=} config Extra configuration options. * @return {?} Reference to the newly-opened dialog. */ MdcDialog.prototype.open = /** * Opens a modal dialog containing the given template. * @template T, D, R * @param {?} componentOrTemplateRef Type of the component to load into the dialog, * or a TemplateRef to instantiate as the dialog content. * @param {?=} config Extra configuration options. * @return {?} Reference to the newly-opened dialog. */ function (componentOrTemplateRef, config) { var _this = this; config = _applyConfigDefaults(config, this._defaultOptions || new MdcDialogConfig()); if (config.id && this.getDialogById(config.id)) { throw Error("Dialog with id \"" + config.id + "\" exists already. The dialog id must be unique."); } /** @type {?} */ var overlayRef = this._createOverlay(); /** @type {?} */ var dialogContainer = this._attachDialogContainer(overlayRef, config); /** @type {?} */ var dialogRef = this._attachDialogContent(componentOrTemplateRef, dialogContainer, overlayRef, config); this.openDialogs.push(dialogRef); dialogRef.afterClosed().subscribe((/** * @return {?} */ function () { return _this._removeOpenDialog(dialogRef, dialogContainer); })); this.afterOpened.next(dialogRef); return dialogRef; }; /** Closes all of the currently-open dialogs. */ /** * Closes all of the currently-open dialogs. * @return {?} */ MdcDialog.prototype.closeAll = /** * Closes all of the currently-open dialogs. * @return {?} */ function () { this._closeDialogs(this.openDialogs); }; /** * Finds an open dialog by its id. * @param id ID to use when looking up the dialog. */ /** * Finds an open dialog by its id. * @param {?} id ID to use when looking up the dialog. * @return {?} */ MdcDialog.prototype.getDialogById = /** * Finds an open dialog by its id. * @param {?} id ID to use when looking up the dialog. * @return {?} */ function (id) { return this.openDialogs.find((/** * @param {?} dialog * @return {?} */ function (dialog) { return dialog.id === id; })); }; /** * @return {?} */ MdcDialog.prototype.ngOnDestroy = /** * @return {?} */ function () { // Only close the dialogs at this level on destroy // since the parent service may still be active. this._closeDialogs(this._openDialogsAtThisLevel); this._afterAllClosedAtThisLevel.complete(); this._afterOpenedAtThisLevel.complete(); }; /** * Creates the overlay into which the dialog will be loaded. * @returns A promise resolving to the OverlayRef for the created overlay. */ /** * Creates the overlay into which the dialog will be loaded. * @private * @return {?} A promise resolving to the OverlayRef for the created overlay. */ MdcDialog.prototype._createOverlay = /** * Creates the overlay into which the dialog will be loaded. * @private * @return {?} A promise resolving to the OverlayRef for the created overlay. */ function () { return this._overlay.create(); }; /** * Attaches an MdcDialogPortal to a dialog's already-created overlay. * @param overlay Reference to the dialog's underlying overlay. * @param config The dialog configuration. * @returns A promise resolving to a ComponentRef for the attached container. */ /** * Attaches an MdcDialogPortal to a dialog's already-created overlay. * @private * @param {?} overlay Reference to the dialog's underlying overlay. * @param {?} config The dialog configuration. * @return {?} A promise resolving to a ComponentRef for the attached container. */ MdcDialog.prototype._attachDialogContainer = /** * Attaches an MdcDialogPortal to a dialog's already-created overlay. * @private * @param {?} overlay Reference to the dialog's underlying overlay. * @param {?} config The dialog configuration. * @return {?} A promise resolving to a ComponentRef for the attached container. */ function (overlay, config) { /** @type {?} */ var userInjector = config && config.viewContainerRef && config.viewContainerRef.injector; /** @type {?} */ var injector = new portal.PortalInjector(userInjector || this._injector, new WeakMap([ [MdcDialogConfig, config] ])); /** @type {?} */ var containerPortal = new portal.ComponentPortal(MdcDialogPortal, config.viewContainerRef, injector, config.componentFactoryResolver); /** @type {?} */ var containerRef = overlay.attach(containerPortal); return containerRef.instance; }; /** * Attaches the user-provided component to the already-created MdcDialogPortal. * @param componentOrTemplateRef The type of component being loaded into the dialog, * or a TemplateRef to instantiate as the content. * @param dialogContainer Reference to the wrapping MdcDialogPortal. * @param overlayRef Reference to the overlay in which the dialog resides. * @param config The dialog configuration. * @returns A promise resolving to the MdcDialogRef that should be returned to the user. */ /** * Attaches the user-provided component to the already-created MdcDialogPortal. * @private * @template T, R * @param {?} componentOrTemplateRef The type of component being loaded into the dialog, * or a TemplateRef to instantiate as the content. * @param {?} dialogContainer Reference to the wrapping MdcDialogPortal. * @param {?} overlayRef Reference to the overlay in which the dialog resides. * @param {?} config The dialog configuration. * @return {?} A promise resolving to the MdcDialogRef that should be returned to the user. */ MdcDialog.prototype._attachDialogContent = /** * Attaches the user-provided component to the already-created MdcDialogPortal. * @private * @template T, R * @param {?} componentOrTemplateRef The type of component being loaded into the dialog, * or a TemplateRef to instantiate as the content. * @param {?} dialogContainer Reference to the wrapping MdcDialogPortal. * @param {?} overlayRef Reference to the overlay in which the dialog resides. * @param {?} config The dialog configuration. * @return {?} A promise resolving to the MdcDialogRef that should be returned to the user. */ function (componentOrTemplateRef, dialogContainer, overlayRef, config) { // Create a reference to the dialog we're creating in order to give the user a handle // to modify and close it. /** @type {?} */ var dialogRef = new MdcDialogRef(overlayRef, dialogContainer, config.id); if (componentOrTemplateRef instanceof core.TemplateRef) { dialogContainer.attachTemplatePortal(new portal.TemplatePortal(componentOrTemplateRef, (/** @type {?} */ (null)), (/** @type {?} */ ({ $implicit: config.data, dialogRef: dialogRef })))); } else { /** @type {?} */ var injector = this._createInjector(config, dialogRef, dialogContainer); /** @type {?} */ var contentRef = dialogContainer.attachComponentPortal(new portal.ComponentPortal(componentOrTemplateRef, config.viewContainerRef, injector)); dialogRef.componentInstance = contentRef.instance; } return dialogRef; }; /** * Creates a custom injector to be used inside the dialog. This allows a component loaded inside * of a dialog to close itself and, optionally, to return a value. * @param config Config object that is used to construct the dialog. * @param dialogRef Reference to the dialog. * @param container Dialog container element that wraps all of the contents. * @returns The custom injector that can be used inside the dialog. */ /** * Creates a custom injector to be used inside the dialog. This allows a component loaded inside * of a dialog to close itself and, optionally, to return a value. * @private * @template T * @param {?} config Config object that is used to construct the dialog. * @param {?} dialogRef Reference to the dialog. * @param {?} portalContainer * @return {?} The custom injector that can be used inside the dialog. */ MdcDialog.prototype._createInjector = /** * Creates a custom injector to be used inside the dialog. This allows a component loaded inside * of a dialog to close itself and, optionally, to return a value. * @private * @template T * @param {?} config Config object that is used to construct the dialog. * @param {?} dialogRef Reference to the dialog. * @param {?} portalContainer * @return {?} The custom injector that can be used inside the dialog. */ function (config, d