http://git-wip-us.apache.org/repos/asf/nifi-fds/blob/eec354e6/node_modules/@angular/cdk/bundles/cdk-a11y.umd.js ---------------------------------------------------------------------- diff --git a/node_modules/@angular/cdk/bundles/cdk-a11y.umd.js b/node_modules/@angular/cdk/bundles/cdk-a11y.umd.js new file mode 100644 index 0000000..c5b06f8 --- /dev/null +++ b/node_modules/@angular/cdk/bundles/cdk-a11y.umd.js @@ -0,0 +1,2427 @@ +/** + * @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 + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/cdk/coercion'), require('rxjs/operators/take'), require('@angular/cdk/platform'), require('@angular/common'), require('rxjs/Subject'), require('rxjs/Subscription'), require('@angular/cdk/keycodes'), require('rxjs/operators/debounceTime'), require('rxjs/operators/filter'), require('rxjs/operators/map'), require('rxjs/operators/tap'), require('rxjs/observable/of')) : + typeof define === 'function' && define.amd ? define(['exports', '@angular/core', '@angular/cdk/coercion', 'rxjs/operators/take', '@angular/cdk/platform', '@angular/common', 'rxjs/Subject', 'rxjs/Subscription', '@angular/cdk/keycodes', 'rxjs/operators/debounceTime', 'rxjs/operators/filter', 'rxjs/operators/map', 'rxjs/operators/tap', 'rxjs/observable/of'], factory) : + (factory((global.ng = global.ng || {}, global.ng.cdk = global.ng.cdk || {}, global.ng.cdk.a11y = global.ng.cdk.a11y || {}),global.ng.core,global.ng.cdk.coercion,global.Rx.operators,global.ng.cdk.platform,global.ng.common,global.Rx,global.Rx,global.ng.cdk.keycodes,global.Rx.operators,global.Rx.operators,global.Rx.operators,global.Rx.operators,global.Rx.Observable)); +}(this, (function (exports,_angular_core,_angular_cdk_coercion,rxjs_operators_take,_angular_cdk_platform,_angular_common,rxjs_Subject,rxjs_Subscription,_angular_cdk_keycodes,rxjs_operators_debounceTime,rxjs_operators_filter,rxjs_operators_map,rxjs_operators_tap,rxjs_observable_of) { '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 = 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]; }; + +function __extends(d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} + +/** + * @fileoverview added by tsickle + * @suppress {checkTypes} checked by tsc + */ + +/** + * Utility for checking the interactivity of an element, such as whether is is focusable or + * tabbable. + */ +var InteractivityChecker = /** @class */ (function () { + function InteractivityChecker(_platform) { + this._platform = _platform; + } + /** + * Gets whether an element is disabled. + * + * @param element Element to be checked. + * @returns Whether the element is disabled. + */ + /** + * Gets whether an element is disabled. + * + * @param {?} element Element to be checked. + * @return {?} Whether the element is disabled. + */ + InteractivityChecker.prototype.isDisabled = /** + * Gets whether an element is disabled. + * + * @param {?} element Element to be checked. + * @return {?} Whether the element is disabled. + */ + function (element) { + // This does not capture some cases, such as a non-form control with a disabled attribute or + // a form control inside of a disabled form, but should capture the most common cases. + return element.hasAttribute('disabled'); + }; + /** + * Gets whether an element is visible for the purposes of interactivity. + * + * This will capture states like `display: none` and `visibility: hidden`, but not things like + * being clipped by an `overflow: hidden` parent or being outside the viewport. + * + * @returns Whether the element is visible. + */ + /** + * Gets whether an element is visible for the purposes of interactivity. + * + * This will capture states like `display: none` and `visibility: hidden`, but not things like + * being clipped by an `overflow: hidden` parent or being outside the viewport. + * + * @param {?} element + * @return {?} Whether the element is visible. + */ + InteractivityChecker.prototype.isVisible = /** + * Gets whether an element is visible for the purposes of interactivity. + * + * This will capture states like `display: none` and `visibility: hidden`, but not things like + * being clipped by an `overflow: hidden` parent or being outside the viewport. + * + * @param {?} element + * @return {?} Whether the element is visible. + */ + function (element) { + return hasGeometry(element) && getComputedStyle(element).visibility === 'visible'; + }; + /** + * Gets whether an element can be reached via Tab key. + * Assumes that the element has already been checked with isFocusable. + * + * @param element Element to be checked. + * @returns Whether the element is tabbable. + */ + /** + * Gets whether an element can be reached via Tab key. + * Assumes that the element has already been checked with isFocusable. + * + * @param {?} element Element to be checked. + * @return {?} Whether the element is tabbable. + */ + InteractivityChecker.prototype.isTabbable = /** + * Gets whether an element can be reached via Tab key. + * Assumes that the element has already been checked with isFocusable. + * + * @param {?} element Element to be checked. + * @return {?} Whether the element is tabbable. + */ + function (element) { + // Nothing is tabbable on the the server ð + if (!this._platform.isBrowser) { + return false; + } + var /** @type {?} */ frameElement = getFrameElement(getWindow(element)); + if (frameElement) { + var /** @type {?} */ frameType = frameElement && frameElement.nodeName.toLowerCase(); + // Frame elements inherit their tabindex onto all child elements. + if (getTabIndexValue(frameElement) === -1) { + return false; + } + // Webkit and Blink consider anything inside of an <object> element as non-tabbable. + if ((this._platform.BLINK || this._platform.WEBKIT) && frameType === 'object') { + return false; + } + // Webkit and Blink disable tabbing to an element inside of an invisible frame. + if ((this._platform.BLINK || this._platform.WEBKIT) && !this.isVisible(frameElement)) { + return false; + } + } + var /** @type {?} */ nodeName = element.nodeName.toLowerCase(); + var /** @type {?} */ tabIndexValue = getTabIndexValue(element); + if (element.hasAttribute('contenteditable')) { + return tabIndexValue !== -1; + } + if (nodeName === 'iframe') { + // The frames may be tabbable depending on content, but it's not possibly to reliably + // investigate the content of the frames. + return false; + } + if (nodeName === 'audio') { + if (!element.hasAttribute('controls')) { + // By default an <audio> element without the controls enabled is not tabbable. + return false; + } + else if (this._platform.BLINK) { + // In Blink <audio controls> elements are always tabbable. + return true; + } + } + if (nodeName === 'video') { + if (!element.hasAttribute('controls') && this._platform.TRIDENT) { + // In Trident a <video> element without the controls enabled is not tabbable. + return false; + } + else if (this._platform.BLINK || this._platform.FIREFOX) { + // In Chrome and Firefox <video controls> elements are always tabbable. + return true; + } + } + if (nodeName === 'object' && (this._platform.BLINK || this._platform.WEBKIT)) { + // In all Blink and WebKit based browsers <object> elements are never tabbable. + return false; + } + // In iOS the browser only considers some specific elements as tabbable. + if (this._platform.WEBKIT && this._platform.IOS && !isPotentiallyTabbableIOS(element)) { + return false; + } + return element.tabIndex >= 0; + }; + /** + * Gets whether an element can be focused by the user. + * + * @param element Element to be checked. + * @returns Whether the element is focusable. + */ + /** + * Gets whether an element can be focused by the user. + * + * @param {?} element Element to be checked. + * @return {?} Whether the element is focusable. + */ + InteractivityChecker.prototype.isFocusable = /** + * Gets whether an element can be focused by the user. + * + * @param {?} element Element to be checked. + * @return {?} Whether the element is focusable. + */ + function (element) { + // Perform checks in order of left to most expensive. + // Again, naive approach that does not capture many edge cases and browser quirks. + return isPotentiallyFocusable(element) && !this.isDisabled(element) && this.isVisible(element); + }; + InteractivityChecker.decorators = [ + { type: _angular_core.Injectable }, + ]; + /** @nocollapse */ + InteractivityChecker.ctorParameters = function () { return [ + { type: _angular_cdk_platform.Platform, }, + ]; }; + return InteractivityChecker; +}()); +/** + * Returns the frame element from a window object. Since browsers like MS Edge throw errors if + * the frameElement property is being accessed from a different host address, this property + * should be accessed carefully. + * @param {?} window + * @return {?} + */ +function getFrameElement(window) { + try { + return /** @type {?} */ (window.frameElement); + } + catch (/** @type {?} */ e) { + return null; + } +} +/** + * Checks whether the specified element has any geometry / rectangles. + * @param {?} element + * @return {?} + */ +function hasGeometry(element) { + // Use logic from jQuery to check for an invisible element. + // See https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js#L12 + return !!(element.offsetWidth || element.offsetHeight || + (typeof element.getClientRects === 'function' && element.getClientRects().length)); +} +/** + * Gets whether an element's + * @param {?} element + * @return {?} + */ +function isNativeFormElement(element) { + var /** @type {?} */ nodeName = element.nodeName.toLowerCase(); + return nodeName === 'input' || + nodeName === 'select' || + nodeName === 'button' || + nodeName === 'textarea'; +} +/** + * Gets whether an element is an `<input type="hidden">`. + * @param {?} element + * @return {?} + */ +function isHiddenInput(element) { + return isInputElement(element) && element.type == 'hidden'; +} +/** + * Gets whether an element is an anchor that has an href attribute. + * @param {?} element + * @return {?} + */ +function isAnchorWithHref(element) { + return isAnchorElement(element) && element.hasAttribute('href'); +} +/** + * Gets whether an element is an input element. + * @param {?} element + * @return {?} + */ +function isInputElement(element) { + return element.nodeName.toLowerCase() == 'input'; +} +/** + * Gets whether an element is an anchor element. + * @param {?} element + * @return {?} + */ +function isAnchorElement(element) { + return element.nodeName.toLowerCase() == 'a'; +} +/** + * Gets whether an element has a valid tabindex. + * @param {?} element + * @return {?} + */ +function hasValidTabIndex(element) { + if (!element.hasAttribute('tabindex') || element.tabIndex === undefined) { + return false; + } + var /** @type {?} */ tabIndex = element.getAttribute('tabindex'); + // IE11 parses tabindex="" as the value "-32768" + if (tabIndex == '-32768') { + return false; + } + return !!(tabIndex && !isNaN(parseInt(tabIndex, 10))); +} +/** + * Returns the parsed tabindex from the element attributes instead of returning the + * evaluated tabindex from the browsers defaults. + * @param {?} element + * @return {?} + */ +function getTabIndexValue(element) { + if (!hasValidTabIndex(element)) { + return null; + } + // See browser issue in Gecko https://bugzilla.mozilla.org/show_bug.cgi?id=1128054 + var /** @type {?} */ tabIndex = parseInt(element.getAttribute('tabindex') || '', 10); + return isNaN(tabIndex) ? -1 : tabIndex; +} +/** + * Checks whether the specified element is potentially tabbable on iOS + * @param {?} element + * @return {?} + */ +function isPotentiallyTabbableIOS(element) { + var /** @type {?} */ nodeName = element.nodeName.toLowerCase(); + var /** @type {?} */ inputType = nodeName === 'input' && (/** @type {?} */ (element)).type; + return inputType === 'text' + || inputType === 'password' + || nodeName === 'select' + || nodeName === 'textarea'; +} +/** + * Gets whether an element is potentially focusable without taking current visible/disabled state + * into account. + * @param {?} element + * @return {?} + */ +function isPotentiallyFocusable(element) { + // Inputs are potentially focusable *unless* they're type="hidden". + if (isHiddenInput(element)) { + return false; + } + return isNativeFormElement(element) || + isAnchorWithHref(element) || + element.hasAttribute('contenteditable') || + hasValidTabIndex(element); +} +/** + * Gets the parent window of a DOM node with regards of being inside of an iframe. + * @param {?} node + * @return {?} + */ +function getWindow(node) { + return node.ownerDocument.defaultView || window; +} + +/** + * @fileoverview added by tsickle + * @suppress {checkTypes} checked by tsc + */ + +/** + * Class that allows for trapping focus within a DOM element. + * + * This class currently uses a relatively simple approach to focus trapping. + * It assumes that the tab order is the same as DOM order, which is not necessarily true. + * Things like `tabIndex > 0`, flex `order`, and shadow roots can cause to two to misalign. + */ +var FocusTrap = /** @class */ (function () { + function FocusTrap(_element, _checker, _ngZone, _document, deferAnchors) { + if (deferAnchors === void 0) { deferAnchors = false; } + this._element = _element; + this._checker = _checker; + this._ngZone = _ngZone; + this._document = _document; + this._enabled = true; + if (!deferAnchors) { + this.attachAnchors(); + } + } + Object.defineProperty(FocusTrap.prototype, "enabled", { + /** Whether the focus trap is active. */ + get: /** + * Whether the focus trap is active. + * @return {?} + */ + function () { return this._enabled; }, + set: /** + * @param {?} val + * @return {?} + */ + function (val) { + this._enabled = val; + if (this._startAnchor && this._endAnchor) { + this._startAnchor.tabIndex = this._endAnchor.tabIndex = this._enabled ? 0 : -1; + } + }, + enumerable: true, + configurable: true + }); + /** Destroys the focus trap by cleaning up the anchors. */ + /** + * Destroys the focus trap by cleaning up the anchors. + * @return {?} + */ + FocusTrap.prototype.destroy = /** + * Destroys the focus trap by cleaning up the anchors. + * @return {?} + */ + function () { + if (this._startAnchor && this._startAnchor.parentNode) { + this._startAnchor.parentNode.removeChild(this._startAnchor); + } + if (this._endAnchor && this._endAnchor.parentNode) { + this._endAnchor.parentNode.removeChild(this._endAnchor); + } + this._startAnchor = this._endAnchor = null; + }; + /** + * Inserts the anchors into the DOM. This is usually done automatically + * in the constructor, but can be deferred for cases like directives with `*ngIf`. + */ + /** + * Inserts the anchors into the DOM. This is usually done automatically + * in the constructor, but can be deferred for cases like directives with `*ngIf`. + * @return {?} + */ + FocusTrap.prototype.attachAnchors = /** + * Inserts the anchors into the DOM. This is usually done automatically + * in the constructor, but can be deferred for cases like directives with `*ngIf`. + * @return {?} + */ + function () { + var _this = this; + if (!this._startAnchor) { + this._startAnchor = this._createAnchor(); + } + if (!this._endAnchor) { + this._endAnchor = this._createAnchor(); + } + this._ngZone.runOutsideAngular(function () { + /** @type {?} */ ((_this._startAnchor)).addEventListener('focus', function () { + _this.focusLastTabbableElement(); + }); /** @type {?} */ + ((_this._endAnchor)).addEventListener('focus', function () { + _this.focusFirstTabbableElement(); + }); + if (_this._element.parentNode) { + _this._element.parentNode.insertBefore(/** @type {?} */ ((_this._startAnchor)), _this._element); + _this._element.parentNode.insertBefore(/** @type {?} */ ((_this._endAnchor)), _this._element.nextSibling); + } + }); + }; + /** + * Waits for the zone to stabilize, then either focuses the first element that the + * user specified, or the first tabbable element. + * @returns Returns a promise that resolves with a boolean, depending + * on whether focus was moved successfuly. + */ + /** + * Waits for the zone to stabilize, then either focuses the first element that the + * user specified, or the first tabbable element. + * @return {?} Returns a promise that resolves with a boolean, depending + * on whether focus was moved successfuly. + */ + FocusTrap.prototype.focusInitialElementWhenReady = /** + * Waits for the zone to stabilize, then either focuses the first element that the + * user specified, or the first tabbable element. + * @return {?} Returns a promise that resolves with a boolean, depending + * on whether focus was moved successfuly. + */ + function () { + var _this = this; + return new Promise(function (resolve) { + _this._executeOnStable(function () { return resolve(_this.focusInitialElement()); }); + }); + }; + /** + * Waits for the zone to stabilize, then focuses + * the first tabbable element within the focus trap region. + * @returns Returns a promise that resolves with a boolean, depending + * on whether focus was moved successfuly. + */ + /** + * Waits for the zone to stabilize, then focuses + * the first tabbable element within the focus trap region. + * @return {?} Returns a promise that resolves with a boolean, depending + * on whether focus was moved successfuly. + */ + FocusTrap.prototype.focusFirstTabbableElementWhenReady = /** + * Waits for the zone to stabilize, then focuses + * the first tabbable element within the focus trap region. + * @return {?} Returns a promise that resolves with a boolean, depending + * on whether focus was moved successfuly. + */ + function () { + var _this = this; + return new Promise(function (resolve) { + _this._executeOnStable(function () { return resolve(_this.focusFirstTabbableElement()); }); + }); + }; + /** + * Waits for the zone to stabilize, then focuses + * the last tabbable element within the focus trap region. + * @returns Returns a promise that resolves with a boolean, depending + * on whether focus was moved successfuly. + */ + /** + * Waits for the zone to stabilize, then focuses + * the last tabbable element within the focus trap region. + * @return {?} Returns a promise that resolves with a boolean, depending + * on whether focus was moved successfuly. + */ + FocusTrap.prototype.focusLastTabbableElementWhenReady = /** + * Waits for the zone to stabilize, then focuses + * the last tabbable element within the focus trap region. + * @return {?} Returns a promise that resolves with a boolean, depending + * on whether focus was moved successfuly. + */ + function () { + var _this = this; + return new Promise(function (resolve) { + _this._executeOnStable(function () { return resolve(_this.focusLastTabbableElement()); }); + }); + }; + /** + * Get the specified boundary element of the trapped region. + * @param {?} bound The boundary to get (start or end of trapped region). + * @return {?} The boundary element. + */ + FocusTrap.prototype._getRegionBoundary = /** + * Get the specified boundary element of the trapped region. + * @param {?} bound The boundary to get (start or end of trapped region). + * @return {?} The boundary element. + */ + function (bound) { + // Contains the deprecated version of selector, for temporary backwards comparability. + var /** @type {?} */ markers = /** @type {?} */ (this._element.querySelectorAll("[cdk-focus-region-" + bound + "], " + + ("[cdkFocusRegion" + bound + "], ") + + ("[cdk-focus-" + bound + "]"))); + for (var /** @type {?} */ i = 0; i < markers.length; i++) { + if (markers[i].hasAttribute("cdk-focus-" + bound)) { + console.warn("Found use of deprecated attribute 'cdk-focus-" + bound + "'," + + (" use 'cdkFocusRegion" + bound + "' instead."), markers[i]); + } + else if (markers[i].hasAttribute("cdk-focus-region-" + bound)) { + console.warn("Found use of deprecated attribute 'cdk-focus-region-" + bound + "'," + + (" use 'cdkFocusRegion" + bound + "' instead."), markers[i]); + } + } + if (bound == 'start') { + return markers.length ? markers[0] : this._getFirstTabbableElement(this._element); + } + return markers.length ? + markers[markers.length - 1] : this._getLastTabbableElement(this._element); + }; + /** + * Focuses the element that should be focused when the focus trap is initialized. + * @returns Whether focus was moved successfuly. + */ + /** + * Focuses the element that should be focused when the focus trap is initialized. + * @return {?} Whether focus was moved successfuly. + */ + FocusTrap.prototype.focusInitialElement = /** + * Focuses the element that should be focused when the focus trap is initialized. + * @return {?} Whether focus was moved successfuly. + */ + function () { + // Contains the deprecated version of selector, for temporary backwards comparability. + var /** @type {?} */ redirectToElement = /** @type {?} */ (this._element.querySelector("[cdk-focus-initial], " + + "[cdkFocusInitial]")); + if (this._element.hasAttribute("cdk-focus-initial")) { + console.warn("Found use of deprecated attribute 'cdk-focus-initial'," + + " use 'cdkFocusInitial' instead.", this._element); + } + if (redirectToElement) { + redirectToElement.focus(); + return true; + } + return this.focusFirstTabbableElement(); + }; + /** + * Focuses the first tabbable element within the focus trap region. + * @returns Whether focus was moved successfuly. + */ + /** + * Focuses the first tabbable element within the focus trap region. + * @return {?} Whether focus was moved successfuly. + */ + FocusTrap.prototype.focusFirstTabbableElement = /** + * Focuses the first tabbable element within the focus trap region. + * @return {?} Whether focus was moved successfuly. + */ + function () { + var /** @type {?} */ redirectToElement = this._getRegionBoundary('start'); + if (redirectToElement) { + redirectToElement.focus(); + } + return !!redirectToElement; + }; + /** + * Focuses the last tabbable element within the focus trap region. + * @returns Whether focus was moved successfuly. + */ + /** + * Focuses the last tabbable element within the focus trap region. + * @return {?} Whether focus was moved successfuly. + */ + FocusTrap.prototype.focusLastTabbableElement = /** + * Focuses the last tabbable element within the focus trap region. + * @return {?} Whether focus was moved successfuly. + */ + function () { + var /** @type {?} */ redirectToElement = this._getRegionBoundary('end'); + if (redirectToElement) { + redirectToElement.focus(); + } + return !!redirectToElement; + }; + /** + * Get the first tabbable element from a DOM subtree (inclusive). + * @param {?} root + * @return {?} + */ + FocusTrap.prototype._getFirstTabbableElement = /** + * Get the first tabbable element from a DOM subtree (inclusive). + * @param {?} root + * @return {?} + */ + function (root) { + if (this._checker.isFocusable(root) && this._checker.isTabbable(root)) { + return root; + } + // Iterate in DOM order. Note that IE doesn't have `children` for SVG so we fall + // back to `childNodes` which includes text nodes, comments etc. + var /** @type {?} */ children = root.children || root.childNodes; + for (var /** @type {?} */ i = 0; i < children.length; i++) { + var /** @type {?} */ tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE ? + this._getFirstTabbableElement(/** @type {?} */ (children[i])) : + null; + if (tabbableChild) { + return tabbableChild; + } + } + return null; + }; + /** + * Get the last tabbable element from a DOM subtree (inclusive). + * @param {?} root + * @return {?} + */ + FocusTrap.prototype._getLastTabbableElement = /** + * Get the last tabbable element from a DOM subtree (inclusive). + * @param {?} root + * @return {?} + */ + function (root) { + if (this._checker.isFocusable(root) && this._checker.isTabbable(root)) { + return root; + } + // Iterate in reverse DOM order. + var /** @type {?} */ children = root.children || root.childNodes; + for (var /** @type {?} */ i = children.length - 1; i >= 0; i--) { + var /** @type {?} */ tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE ? + this._getLastTabbableElement(/** @type {?} */ (children[i])) : + null; + if (tabbableChild) { + return tabbableChild; + } + } + return null; + }; + /** + * Creates an anchor element. + * @return {?} + */ + FocusTrap.prototype._createAnchor = /** + * Creates an anchor element. + * @return {?} + */ + function () { + var /** @type {?} */ anchor = this._document.createElement('div'); + anchor.tabIndex = this._enabled ? 0 : -1; + anchor.classList.add('cdk-visually-hidden'); + anchor.classList.add('cdk-focus-trap-anchor'); + return anchor; + }; + /** + * Executes a function when the zone is stable. + * @param {?} fn + * @return {?} + */ + FocusTrap.prototype._executeOnStable = /** + * Executes a function when the zone is stable. + * @param {?} fn + * @return {?} + */ + function (fn) { + if (this._ngZone.isStable) { + fn(); + } + else { + this._ngZone.onStable.asObservable().pipe(rxjs_operators_take.take(1)).subscribe(fn); + } + }; + return FocusTrap; +}()); +/** + * Factory that allows easy instantiation of focus traps. + */ +var FocusTrapFactory = /** @class */ (function () { + function FocusTrapFactory(_checker, _ngZone, _document) { + this._checker = _checker; + this._ngZone = _ngZone; + this._document = _document; + } + /** + * Creates a focus-trapped region around the given element. + * @param element The element around which focus will be trapped. + * @param deferCaptureElements Defers the creation of focus-capturing elements to be done + * manually by the user. + * @returns The created focus trap instance. + */ + /** + * Creates a focus-trapped region around the given element. + * @param {?} element The element around which focus will be trapped. + * @param {?=} deferCaptureElements Defers the creation of focus-capturing elements to be done + * manually by the user. + * @return {?} The created focus trap instance. + */ + FocusTrapFactory.prototype.create = /** + * Creates a focus-trapped region around the given element. + * @param {?} element The element around which focus will be trapped. + * @param {?=} deferCaptureElements Defers the creation of focus-capturing elements to be done + * manually by the user. + * @return {?} The created focus trap instance. + */ + function (element, deferCaptureElements) { + if (deferCaptureElements === void 0) { deferCaptureElements = false; } + return new FocusTrap(element, this._checker, this._ngZone, this._document, deferCaptureElements); + }; + FocusTrapFactory.decorators = [ + { type: _angular_core.Injectable }, + ]; + /** @nocollapse */ + FocusTrapFactory.ctorParameters = function () { return [ + { type: InteractivityChecker, }, + { type: _angular_core.NgZone, }, + { type: undefined, decorators: [{ type: _angular_core.Inject, args: [_angular_common.DOCUMENT,] },] }, + ]; }; + return FocusTrapFactory; +}()); +/** + * Directive for trapping focus within a region. + * \@docs-private + * @deprecated + * \@deletion-target 6.0.0 + */ +var FocusTrapDeprecatedDirective = /** @class */ (function () { + function FocusTrapDeprecatedDirective(_elementRef, _focusTrapFactory) { + this._elementRef = _elementRef; + this._focusTrapFactory = _focusTrapFactory; + this.focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement, true); + } + Object.defineProperty(FocusTrapDeprecatedDirective.prototype, "disabled", { + get: /** + * Whether the focus trap is active. + * @return {?} + */ + function () { return !this.focusTrap.enabled; }, + set: /** + * @param {?} val + * @return {?} + */ + function (val) { + this.focusTrap.enabled = !_angular_cdk_coercion.coerceBooleanProperty(val); + }, + enumerable: true, + configurable: true + }); + /** + * @return {?} + */ + FocusTrapDeprecatedDirective.prototype.ngOnDestroy = /** + * @return {?} + */ + function () { + this.focusTrap.destroy(); + }; + /** + * @return {?} + */ + FocusTrapDeprecatedDirective.prototype.ngAfterContentInit = /** + * @return {?} + */ + function () { + this.focusTrap.attachAnchors(); + }; + FocusTrapDeprecatedDirective.decorators = [ + { type: _angular_core.Directive, args: [{ + selector: 'cdk-focus-trap', + },] }, + ]; + /** @nocollapse */ + FocusTrapDeprecatedDirective.ctorParameters = function () { return [ + { type: _angular_core.ElementRef, }, + { type: FocusTrapFactory, }, + ]; }; + FocusTrapDeprecatedDirective.propDecorators = { + "disabled": [{ type: _angular_core.Input },], + }; + return FocusTrapDeprecatedDirective; +}()); +/** + * Directive for trapping focus within a region. + */ +var CdkTrapFocus = /** @class */ (function () { + function CdkTrapFocus(_elementRef, _focusTrapFactory, _document) { + this._elementRef = _elementRef; + this._focusTrapFactory = _focusTrapFactory; + /** + * Previously focused element to restore focus to upon destroy when using autoCapture. + */ + this._previouslyFocusedElement = null; + this._document = _document; + this.focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement, true); + } + Object.defineProperty(CdkTrapFocus.prototype, "enabled", { + get: /** + * Whether the focus trap is active. + * @return {?} + */ + function () { return this.focusTrap.enabled; }, + set: /** + * @param {?} value + * @return {?} + */ + function (value) { this.focusTrap.enabled = _angular_cdk_coercion.coerceBooleanProperty(value); }, + enumerable: true, + configurable: true + }); + Object.defineProperty(CdkTrapFocus.prototype, "autoCapture", { + get: /** + * Whether the directive should automatially move focus into the trapped region upon + * initialization and return focus to the previous activeElement upon destruction. + * @return {?} + */ + function () { return this._autoCapture; }, + set: /** + * @param {?} value + * @return {?} + */ + function (value) { this._autoCapture = _angular_cdk_coercion.coerceBooleanProperty(value); }, + enumerable: true, + configurable: true + }); + /** + * @return {?} + */ + CdkTrapFocus.prototype.ngOnDestroy = /** + * @return {?} + */ + function () { + this.focusTrap.destroy(); + // If we stored a previously focused element when using autoCapture, return focus to that + // element now that the trapped region is being destroyed. + if (this._previouslyFocusedElement) { + this._previouslyFocusedElement.focus(); + this._previouslyFocusedElement = null; + } + }; + /** + * @return {?} + */ + CdkTrapFocus.prototype.ngAfterContentInit = /** + * @return {?} + */ + function () { + this.focusTrap.attachAnchors(); + if (this.autoCapture) { + this._previouslyFocusedElement = /** @type {?} */ (this._document.activeElement); + this.focusTrap.focusInitialElementWhenReady(); + } + }; + CdkTrapFocus.decorators = [ + { type: _angular_core.Directive, args: [{ + selector: '[cdkTrapFocus]', + exportAs: 'cdkTrapFocus', + },] }, + ]; + /** @nocollapse */ + CdkTrapFocus.ctorParameters = function () { return [ + { type: _angular_core.ElementRef, }, + { type: FocusTrapFactory, }, + { type: undefined, decorators: [{ type: _angular_core.Inject, args: [_angular_common.DOCUMENT,] },] }, + ]; }; + CdkTrapFocus.propDecorators = { + "enabled": [{ type: _angular_core.Input, args: ['cdkTrapFocus',] },], + "autoCapture": [{ type: _angular_core.Input, args: ['cdkTrapFocusAutoCapture',] },], + }; + return CdkTrapFocus; +}()); + +/** + * @fileoverview added by tsickle + * @suppress {checkTypes} checked by tsc + */ + +/** + * IDs are deliminated by an empty space, as per the spec. + */ +var ID_DELIMINATOR = ' '; +/** + * Adds the given ID to the specified ARIA attribute on an element. + * Used for attributes such as aria-labelledby, aria-owns, etc. + * @param {?} el + * @param {?} attr + * @param {?} id + * @return {?} + */ +function addAriaReferencedId(el, attr, id) { + var /** @type {?} */ ids = getAriaReferenceIds(el, attr); + if (ids.some(function (existingId) { return existingId.trim() == id.trim(); })) { + return; + } + ids.push(id.trim()); + el.setAttribute(attr, ids.join(ID_DELIMINATOR)); +} +/** + * Removes the given ID from the specified ARIA attribute on an element. + * Used for attributes such as aria-labelledby, aria-owns, etc. + * @param {?} el + * @param {?} attr + * @param {?} id + * @return {?} + */ +function removeAriaReferencedId(el, attr, id) { + var /** @type {?} */ ids = getAriaReferenceIds(el, attr); + var /** @type {?} */ filteredIds = ids.filter(function (val) { return val != id.trim(); }); + el.setAttribute(attr, filteredIds.join(ID_DELIMINATOR)); +} +/** + * Gets the list of IDs referenced by the given ARIA attribute on an element. + * Used for attributes such as aria-labelledby, aria-owns, etc. + * @param {?} el + * @param {?} attr + * @return {?} + */ +function getAriaReferenceIds(el, attr) { + // Get string array of all individual ids (whitespace deliminated) in the attribute value + return (el.getAttribute(attr) || '').match(/\S+/g) || []; +} + +/** + * @fileoverview added by tsickle + * @suppress {checkTypes} checked by tsc + */ + +/** + * Interface used to register message elements and keep a count of how many registrations have + * the same message and the reference to the message element used for the `aria-describedby`. + * @record + */ + +/** + * ID used for the body container where all messages are appended. + */ +var MESSAGES_CONTAINER_ID = 'cdk-describedby-message-container'; +/** + * ID prefix used for each created message element. + */ +var CDK_DESCRIBEDBY_ID_PREFIX = 'cdk-describedby-message'; +/** + * Attribute given to each host element that is described by a message element. + */ +var CDK_DESCRIBEDBY_HOST_ATTRIBUTE = 'cdk-describedby-host'; +/** + * Global incremental identifier for each registered message element. + */ +var nextId = 0; +/** + * Global map of all registered message elements that have been placed into the document. + */ +var messageRegistry = new Map(); +/** + * Container for all registered messages. + */ +var messagesContainer = null; +/** + * Utility that creates visually hidden elements with a message content. Useful for elements that + * want to use aria-describedby to further describe themselves without adding additional visual + * content. + * \@docs-private + */ +var AriaDescriber = /** @class */ (function () { + function AriaDescriber(_document) { + this._document = _document; + } + /** + * Adds to the host element an aria-describedby reference to a hidden element that contains + * the message. If the same message has already been registered, then it will reuse the created + * message element. + */ + /** + * Adds to the host element an aria-describedby reference to a hidden element that contains + * the message. If the same message has already been registered, then it will reuse the created + * message element. + * @param {?} hostElement + * @param {?} message + * @return {?} + */ + AriaDescriber.prototype.describe = /** + * Adds to the host element an aria-describedby reference to a hidden element that contains + * the message. If the same message has already been registered, then it will reuse the created + * message element. + * @param {?} hostElement + * @param {?} message + * @return {?} + */ + function (hostElement, message) { + if (hostElement.nodeType !== this._document.ELEMENT_NODE || !message.trim()) { + return; + } + if (!messageRegistry.has(message)) { + this._createMessageElement(message); + } + if (!this._isElementDescribedByMessage(hostElement, message)) { + this._addMessageReference(hostElement, message); + } + }; + /** Removes the host element's aria-describedby reference to the message element. */ + /** + * Removes the host element's aria-describedby reference to the message element. + * @param {?} hostElement + * @param {?} message + * @return {?} + */ + AriaDescriber.prototype.removeDescription = /** + * Removes the host element's aria-describedby reference to the message element. + * @param {?} hostElement + * @param {?} message + * @return {?} + */ + function (hostElement, message) { + if (hostElement.nodeType !== this._document.ELEMENT_NODE || !message.trim()) { + return; + } + if (this._isElementDescribedByMessage(hostElement, message)) { + this._removeMessageReference(hostElement, message); + } + var /** @type {?} */ registeredMessage = messageRegistry.get(message); + if (registeredMessage && registeredMessage.referenceCount === 0) { + this._deleteMessageElement(message); + } + if (messagesContainer && messagesContainer.childNodes.length === 0) { + this._deleteMessagesContainer(); + } + }; + /** Unregisters all created message elements and removes the message container. */ + /** + * Unregisters all created message elements and removes the message container. + * @return {?} + */ + AriaDescriber.prototype.ngOnDestroy = /** + * Unregisters all created message elements and removes the message container. + * @return {?} + */ + function () { + var /** @type {?} */ describedElements = this._document.querySelectorAll("[" + CDK_DESCRIBEDBY_HOST_ATTRIBUTE + "]"); + for (var /** @type {?} */ i = 0; i < describedElements.length; i++) { + this._removeCdkDescribedByReferenceIds(describedElements[i]); + describedElements[i].removeAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE); + } + if (messagesContainer) { + this._deleteMessagesContainer(); + } + messageRegistry.clear(); + }; + /** + * Creates a new element in the visually hidden message container element with the message + * as its content and adds it to the message registry. + * @param {?} message + * @return {?} + */ + AriaDescriber.prototype._createMessageElement = /** + * Creates a new element in the visually hidden message container element with the message + * as its content and adds it to the message registry. + * @param {?} message + * @return {?} + */ + function (message) { + var /** @type {?} */ messageElement = this._document.createElement('div'); + messageElement.setAttribute('id', CDK_DESCRIBEDBY_ID_PREFIX + "-" + nextId++); + messageElement.appendChild(/** @type {?} */ ((this._document.createTextNode(message)))); + if (!messagesContainer) { + this._createMessagesContainer(); + } /** @type {?} */ + ((messagesContainer)).appendChild(messageElement); + messageRegistry.set(message, { messageElement: messageElement, referenceCount: 0 }); + }; + /** + * Deletes the message element from the global messages container. + * @param {?} message + * @return {?} + */ + AriaDescriber.prototype._deleteMessageElement = /** + * Deletes the message element from the global messages container. + * @param {?} message + * @return {?} + */ + function (message) { + var /** @type {?} */ registeredMessage = messageRegistry.get(message); + var /** @type {?} */ messageElement = registeredMessage && registeredMessage.messageElement; + if (messagesContainer && messageElement) { + messagesContainer.removeChild(messageElement); + } + messageRegistry.delete(message); + }; + /** + * Creates the global container for all aria-describedby messages. + * @return {?} + */ + AriaDescriber.prototype._createMessagesContainer = /** + * Creates the global container for all aria-describedby messages. + * @return {?} + */ + function () { + messagesContainer = this._document.createElement('div'); + messagesContainer.setAttribute('id', MESSAGES_CONTAINER_ID); + messagesContainer.setAttribute('aria-hidden', 'true'); + messagesContainer.style.display = 'none'; + this._document.body.appendChild(messagesContainer); + }; + /** + * Deletes the global messages container. + * @return {?} + */ + AriaDescriber.prototype._deleteMessagesContainer = /** + * Deletes the global messages container. + * @return {?} + */ + function () { + if (messagesContainer && messagesContainer.parentNode) { + messagesContainer.parentNode.removeChild(messagesContainer); + messagesContainer = null; + } + }; + /** + * Removes all cdk-describedby messages that are hosted through the element. + * @param {?} element + * @return {?} + */ + AriaDescriber.prototype._removeCdkDescribedByReferenceIds = /** + * Removes all cdk-describedby messages that are hosted through the element. + * @param {?} element + * @return {?} + */ + function (element) { + // Remove all aria-describedby reference IDs that are prefixed by CDK_DESCRIBEDBY_ID_PREFIX + var /** @type {?} */ originalReferenceIds = getAriaReferenceIds(element, 'aria-describedby') + .filter(function (id) { return id.indexOf(CDK_DESCRIBEDBY_ID_PREFIX) != 0; }); + element.setAttribute('aria-describedby', originalReferenceIds.join(' ')); + }; + /** + * Adds a message reference to the element using aria-describedby and increments the registered + * message's reference count. + * @param {?} element + * @param {?} message + * @return {?} + */ + AriaDescriber.prototype._addMessageReference = /** + * Adds a message reference to the element using aria-describedby and increments the registered + * message's reference count. + * @param {?} element + * @param {?} message + * @return {?} + */ + function (element, message) { + var /** @type {?} */ registeredMessage = /** @type {?} */ ((messageRegistry.get(message))); + // Add the aria-describedby reference and set the + // describedby_host attribute to mark the element. + addAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id); + element.setAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE, ''); + registeredMessage.referenceCount++; + }; + /** + * Removes a message reference from the element using aria-describedby + * and decrements the registered message's reference count. + * @param {?} element + * @param {?} message + * @return {?} + */ + AriaDescriber.prototype._removeMessageReference = /** + * Removes a message reference from the element using aria-describedby + * and decrements the registered message's reference count. + * @param {?} element + * @param {?} message + * @return {?} + */ + function (element, message) { + var /** @type {?} */ registeredMessage = /** @type {?} */ ((messageRegistry.get(message))); + registeredMessage.referenceCount--; + removeAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id); + element.removeAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE); + }; + /** + * Returns true if the element has been described by the provided message ID. + * @param {?} element + * @param {?} message + * @return {?} + */ + AriaDescriber.prototype._isElementDescribedByMessage = /** + * Returns true if the element has been described by the provided message ID. + * @param {?} element + * @param {?} message + * @return {?} + */ + function (element, message) { + var /** @type {?} */ referenceIds = getAriaReferenceIds(element, 'aria-describedby'); + var /** @type {?} */ registeredMessage = messageRegistry.get(message); + var /** @type {?} */ messageId = registeredMessage && registeredMessage.messageElement.id; + return !!messageId && referenceIds.indexOf(messageId) != -1; + }; + AriaDescriber.decorators = [ + { type: _angular_core.Injectable }, + ]; + /** @nocollapse */ + AriaDescriber.ctorParameters = function () { return [ + { type: undefined, decorators: [{ type: _angular_core.Inject, args: [_angular_common.DOCUMENT,] },] }, + ]; }; + return AriaDescriber; +}()); +/** + * \@docs-private + * @param {?} parentDispatcher + * @param {?} _document + * @return {?} + */ +function ARIA_DESCRIBER_PROVIDER_FACTORY(parentDispatcher, _document) { + return parentDispatcher || new AriaDescriber(_document); +} +/** + * \@docs-private + */ +var ARIA_DESCRIBER_PROVIDER = { + // If there is already an AriaDescriber available, use that. Otherwise, provide a new one. + provide: AriaDescriber, + deps: [ + [new _angular_core.Optional(), new _angular_core.SkipSelf(), AriaDescriber], + /** @type {?} */ (_angular_common.DOCUMENT) + ], + useFactory: ARIA_DESCRIBER_PROVIDER_FACTORY +}; + +/** + * @fileoverview added by tsickle + * @suppress {checkTypes} checked by tsc + */ + +/** + * This interface is for items that can be passed to a ListKeyManager. + * @record + */ + +/** + * This class manages keyboard events for selectable lists. If you pass it a query list + * of items, it will set the active item correctly when arrow events occur. + */ +var ListKeyManager = /** @class */ (function () { + function ListKeyManager(_items) { + var _this = this; + this._items = _items; + this._activeItemIndex = -1; + this._wrap = false; + this._letterKeyStream = new rxjs_Subject.Subject(); + this._typeaheadSubscription = rxjs_Subscription.Subscription.EMPTY; + this._vertical = true; + this._pressedLetters = []; + /** + * Stream that emits any time the TAB key is pressed, so components can react + * when focus is shifted off of the list. + */ + this.tabOut = new rxjs_Subject.Subject(); + /** + * Stream that emits whenever the active item of the list manager changes. + */ + this.change = new rxjs_Subject.Subject(); + _items.changes.subscribe(function (newItems) { + if (_this._activeItem) { + var /** @type {?} */ itemArray = newItems.toArray(); + var /** @type {?} */ newIndex = itemArray.indexOf(_this._activeItem); + if (newIndex > -1 && newIndex !== _this._activeItemIndex) { + _this._activeItemIndex = newIndex; + } + } + }); + } + /** + * Turns on wrapping mode, which ensures that the active item will wrap to + * the other end of list when there are no more items in the given direction. + */ + /** + * Turns on wrapping mode, which ensures that the active item will wrap to + * the other end of list when there are no more items in the given direction. + * @return {?} + */ + ListKeyManager.prototype.withWrap = /** + * Turns on wrapping mode, which ensures that the active item will wrap to + * the other end of list when there are no more items in the given direction. + * @return {?} + */ + function () { + this._wrap = true; + return this; + }; + /** + * Configures whether the key manager should be able to move the selection vertically. + * @param enabled Whether vertical selection should be enabled. + */ + /** + * Configures whether the key manager should be able to move the selection vertically. + * @param {?=} enabled Whether vertical selection should be enabled. + * @return {?} + */ + ListKeyManager.prototype.withVerticalOrientation = /** + * Configures whether the key manager should be able to move the selection vertically. + * @param {?=} enabled Whether vertical selection should be enabled. + * @return {?} + */ + function (enabled) { + if (enabled === void 0) { enabled = true; } + this._vertical = enabled; + return this; + }; + /** + * Configures the key manager to move the selection horizontally. + * Passing in `null` will disable horizontal movement. + * @param direction Direction in which the selection can be moved. + */ + /** + * Configures the key manager to move the selection horizontally. + * Passing in `null` will disable horizontal movement. + * @param {?} direction Direction in which the selection can be moved. + * @return {?} + */ + ListKeyManager.prototype.withHorizontalOrientation = /** + * Configures the key manager to move the selection horizontally. + * Passing in `null` will disable horizontal movement. + * @param {?} direction Direction in which the selection can be moved. + * @return {?} + */ + function (direction) { + this._horizontal = direction; + return this; + }; + /** + * Turns on typeahead mode which allows users to set the active item by typing. + * @param debounceInterval Time to wait after the last keystroke before setting the active item. + */ + /** + * Turns on typeahead mode which allows users to set the active item by typing. + * @param {?=} debounceInterval Time to wait after the last keystroke before setting the active item. + * @return {?} + */ + ListKeyManager.prototype.withTypeAhead = /** + * Turns on typeahead mode which allows users to set the active item by typing. + * @param {?=} debounceInterval Time to wait after the last keystroke before setting the active item. + * @return {?} + */ + function (debounceInterval) { + var _this = this; + if (debounceInterval === void 0) { debounceInterval = 200; } + if (this._items.length && this._items.some(function (item) { return typeof item.getLabel !== 'function'; })) { + throw Error('ListKeyManager items in typeahead mode must implement the `getLabel` method.'); + } + this._typeaheadSubscription.unsubscribe(); + // Debounce the presses of non-navigational keys, collect the ones that correspond to letters + // and convert those letters back into a string. Afterwards find the first item that starts + // with that string and select it. + this._typeaheadSubscription = this._letterKeyStream.pipe(rxjs_operators_tap.tap(function (keyCode) { return _this._pressedLetters.push(keyCode); }), rxjs_operators_debounceTime.debounceTime(debounceInterval), rxjs_operators_filter.filter(function () { return _this._pressedLetters.length > 0; }), rxjs_operators_map.map(function () { return _this._pressedLetters.join(''); })).subscribe(function (inputString) { + var /** @type {?} */ items = _this._items.toArray(); + // Start at 1 because we want to start searching at the item immediately + // following the current active item. + for (var /** @type {?} */ i = 1; i < items.length + 1; i++) { + var /** @type {?} */ index = (_this._activeItemIndex + i) % items.length; + var /** @type {?} */ item = items[index]; + if (!item.disabled && /** @type {?} */ ((item.getLabel))().toUpperCase().trim().indexOf(inputString) === 0) { + _this.setActiveItem(index); + break; + } + } + _this._pressedLetters = []; + }); + return this; + }; + /** + * Sets the active item to the item at the index specified. + * @param index The index of the item to be set as active. + */ + /** + * Sets the active item to the item at the index specified. + * @param {?} index The index of the item to be set as active. + * @return {?} + */ + ListKeyManager.prototype.setActiveItem = /** + * Sets the active item to the item at the index specified. + * @param {?} index The index of the item to be set as active. + * @return {?} + */ + function (index) { + var /** @type {?} */ previousIndex = this._activeItemIndex; + this._activeItemIndex = index; + this._activeItem = this._items.toArray()[index]; + if (this._activeItemIndex !== previousIndex) { + this.change.next(index); + } + }; + /** + * Sets the active item depending on the key event passed in. + * @param event Keyboard event to be used for determining which element should be active. + */ + /** + * Sets the active item depending on the key event passed in. + * @param {?} event Keyboard event to be used for determining which element should be active. + * @return {?} + */ + ListKeyManager.prototype.onKeydown = /** + * Sets the active item depending on the key event passed in. + * @param {?} event Keyboard event to be used for determining which element should be active. + * @return {?} + */ + function (event) { + var /** @type {?} */ keyCode = event.keyCode; + switch (keyCode) { + case _angular_cdk_keycodes.TAB: + this.tabOut.next(); + return; + case _angular_cdk_keycodes.DOWN_ARROW: + if (this._vertical) { + this.setNextItemActive(); + break; + } + case _angular_cdk_keycodes.UP_ARROW: + if (this._vertical) { + this.setPreviousItemActive(); + break; + } + case _angular_cdk_keycodes.RIGHT_ARROW: + if (this._horizontal === 'ltr') { + this.setNextItemActive(); + break; + } + else if (this._horizontal === 'rtl') { + this.setPreviousItemActive(); + break; + } + case _angular_cdk_keycodes.LEFT_ARROW: + if (this._horizontal === 'ltr') { + this.setPreviousItemActive(); + break; + } + else if (this._horizontal === 'rtl') { + this.setNextItemActive(); + break; + } + default: + // Attempt to use the `event.key` which also maps it to the user's keyboard language, + // otherwise fall back to resolving alphanumeric characters via the keyCode. + if (event.key && event.key.length === 1) { + this._letterKeyStream.next(event.key.toLocaleUpperCase()); + } + else if ((keyCode >= _angular_cdk_keycodes.A && keyCode <= _angular_cdk_keycodes.Z) || (keyCode >= _angular_cdk_keycodes.ZERO && keyCode <= _angular_cdk_keycodes.NINE)) { + this._letterKeyStream.next(String.fromCharCode(keyCode)); + } + // Note that we return here, in order to avoid preventing + // the default action of non-navigational keys. + return; + } + this._pressedLetters = []; + event.preventDefault(); + }; + Object.defineProperty(ListKeyManager.prototype, "activeItemIndex", { + /** Index of the currently active item. */ + get: /** + * Index of the currently active item. + * @return {?} + */ + function () { + return this._activeItemIndex; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(ListKeyManager.prototype, "activeItem", { + /** The active item. */ + get: /** + * The active item. + * @return {?} + */ + function () { + return this._activeItem; + }, + enumerable: true, + configurable: true + }); + /** Sets the active item to the first enabled item in the list. */ + /** + * Sets the active item to the first enabled item in the list. + * @return {?} + */ + ListKeyManager.prototype.setFirstItemActive = /** + * Sets the active item to the first enabled item in the list. + * @return {?} + */ + function () { + this._setActiveItemByIndex(0, 1); + }; + /** Sets the active item to the last enabled item in the list. */ + /** + * Sets the active item to the last enabled item in the list. + * @return {?} + */ + ListKeyManager.prototype.setLastItemActive = /** + * Sets the active item to the last enabled item in the list. + * @return {?} + */ + function () { + this._setActiveItemByIndex(this._items.length - 1, -1); + }; + /** Sets the active item to the next enabled item in the list. */ + /** + * Sets the active item to the next enabled item in the list. + * @return {?} + */ + ListKeyManager.prototype.setNextItemActive = /** + * Sets the active item to the next enabled item in the list. + * @return {?} + */ + function () { + this._activeItemIndex < 0 ? this.setFirstItemActive() : this._setActiveItemByDelta(1); + }; + /** Sets the active item to a previous enabled item in the list. */ + /** + * Sets the active item to a previous enabled item in the list. + * @return {?} + */ + ListKeyManager.prototype.setPreviousItemActive = /** + * Sets the active item to a previous enabled item in the list. + * @return {?} + */ + function () { + this._activeItemIndex < 0 && this._wrap ? this.setLastItemActive() + : this._setActiveItemByDelta(-1); + }; + /** + * Allows setting of the activeItemIndex without any other effects. + * @param index The new activeItemIndex. + */ + /** + * Allows setting of the activeItemIndex without any other effects. + * @param {?} index The new activeItemIndex. + * @return {?} + */ + ListKeyManager.prototype.updateActiveItemIndex = /** + * Allows setting of the activeItemIndex without any other effects. + * @param {?} index The new activeItemIndex. + * @return {?} + */ + function (index) { + this._activeItemIndex = index; + }; + /** + * This method sets the active item, given a list of items and the delta between the + * currently active item and the new active item. It will calculate differently + * depending on whether wrap mode is turned on. + * @param {?} delta + * @param {?=} items + * @return {?} + */ + ListKeyManager.prototype._setActiveItemByDelta = /** + * This method sets the active item, given a list of items and the delta between the + * currently active item and the new active item. It will calculate differently + * depending on whether wrap mode is turned on. + * @param {?} delta + * @param {?=} items + * @return {?} + */ + function (delta, items) { + if (items === void 0) { items = this._items.toArray(); } + this._wrap ? this._setActiveInWrapMode(delta, items) + : this._setActiveInDefaultMode(delta, items); + }; + /** + * Sets the active item properly given "wrap" mode. In other words, it will continue to move + * down the list until it finds an item that is not disabled, and it will wrap if it + * encounters either end of the list. + * @param {?} delta + * @param {?} items + * @return {?} + */ + ListKeyManager.prototype._setActiveInWrapMode = /** + * Sets the active item properly given "wrap" mode. In other words, it will continue to move + * down the list until it finds an item that is not disabled, and it will wrap if it + * encounters either end of the list. + * @param {?} delta + * @param {?} items + * @return {?} + */ + function (delta, items) { + // when active item would leave menu, wrap to beginning or end + this._activeItemIndex = + (this._activeItemIndex + delta + items.length) % items.length; + // skip all disabled menu items recursively until an enabled one is reached + if (items[this._activeItemIndex].disabled) { + this._setActiveInWrapMode(delta, items); + } + else { + this.setActiveItem(this._activeItemIndex); + } + }; + /** + * Sets the active item properly given the default mode. In other words, it will + * continue to move down the list until it finds an item that is not disabled. If + * it encounters either end of the list, it will stop and not wrap. + * @param {?} delta + * @param {?} items + * @return {?} + */ + ListKeyManager.prototype._setActiveInDefaultMode = /** + * Sets the active item properly given the default mode. In other words, it will + * continue to move down the list until it finds an item that is not disabled. If + * it encounters either end of the list, it will stop and not wrap. + * @param {?} delta + * @param {?} items + * @return {?} + */ + function (delta, items) { + this._setActiveItemByIndex(this._activeItemIndex + delta, delta, items); + }; + /** + * Sets the active item to the first enabled item starting at the index specified. If the + * item is disabled, it will move in the fallbackDelta direction until it either + * finds an enabled item or encounters the end of the list. + * @param {?} index + * @param {?} fallbackDelta + * @param {?=} items + * @return {?} + */ + ListKeyManager.prototype._setActiveItemByIndex = /** + * Sets the active item to the first enabled item starting at the index specified. If the + * item is disabled, it will move in the fallbackDelta direction until it either + * finds an enabled item or encounters the end of the list. + * @param {?} index + * @param {?} fallbackDelta + * @param {?=} items + * @return {?} + */ + function (index, fallbackDelta, items) { + if (items === void 0) { items = this._items.toArray(); } + if (!items[index]) { + return; + } + while (items[index].disabled) { + index += fallbackDelta; + if (!items[index]) { + return; + } + } + this.setActiveItem(index); + }; + return ListKeyManager; +}()); + +/** + * @fileoverview added by tsickle + * @suppress {checkTypes} checked by tsc + */ + +/** + * This is the interface for highlightable items (used by the ActiveDescendantKeyManager). + * Each item must know how to style itself as active or inactive and whether or not it is + * currently disabled. + * @record + */ + +var ActiveDescendantKeyManager = /** @class */ (function (_super) { + __extends(ActiveDescendantKeyManager, _super); + function ActiveDescendantKeyManager() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** + * This method sets the active item to the item at the specified index. + * It also adds active styles to the newly active item and removes active + * styles from the previously active item. + */ + /** + * This method sets the active item to the item at the specified index. + * It also adds active styles to the newly active item and removes active + * styles from the previously active item. + * @param {?} index + * @return {?} + */ + ActiveDescendantKeyManager.prototype.setActiveItem = /** + * This method sets the active item to the item at the specified index. + * It also adds active styles to the newly active item and removes active + * styles from the previously active item. + * @param {?} index + * @return {?} + */ + function (index) { + if (this.activeItem) { + this.activeItem.setInactiveStyles(); + } + _super.prototype.setActiveItem.call(this, index); + if (this.activeItem) { + this.activeItem.setActiveStyles(); + } + }; + return ActiveDescendantKeyManager; +}(ListKeyManager)); + +/** + * @fileoverview added by tsickle + * @suppress {checkTypes} checked by tsc + */ + +/** + * This is the interface for focusable items (used by the FocusKeyManager). + * Each item must know how to focus itself, whether or not it is currently disabled + * and be able to supply it's label. + * @record + */ + +var FocusKeyManager = /** @class */ (function (_super) { + __extends(FocusKeyManager, _super); + function FocusKeyManager() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this._origin = 'program'; + return _this; + } + /** + * Sets the focus origin that will be passed in to the items for any subsequent `focus` calls. + * @param origin Focus origin to be used when focusing items. + */ + /** + * Sets the focus origin that will be passed in to the items for any subsequent `focus` calls. + * @param {?} origin Focus origin to be used when focusing items. + * @return {?} + */ + FocusKeyManager.prototype.setFocusOrigin = /** + * Sets the focus origin that will be passed in to the items for any subsequent `focus` calls. + * @param {?} origin Focus origin to be used when focusing items. + * @return {?} + */ + function (origin) { + this._origin = origin; + return this; + }; + /** + * This method sets the active item to the item at the specified index. + * It also adds focuses the newly active item. + */ + /** + * This method sets the active item to the item at the specified index. + * It also adds focuses the newly active item. + * @param {?} index + * @return {?} + */ + FocusKeyManager.prototype.setActiveItem = /** + * This method sets the active item to the item at the specified index. + * It also adds focuses the newly active item. + * @param {?} index + * @return {?} + */ + function (index) { + _super.prototype.setActiveItem.call(this, index); + if (this.activeItem) { + this.activeItem.focus(this._origin); + } + }; + return FocusKeyManager; +}(ListKeyManager)); + +/** + * @fileoverview added by tsickle + * @suppress {checkTypes} checked by tsc + */ + +var LIVE_ANNOUNCER_ELEMENT_TOKEN = new _angular_core.InjectionToken('liveAnnouncerElement'); +var LiveAnnouncer = /** @class */ (function () { + function LiveAnnouncer(elementToken, _document) { + this._document = _document; + // We inject the live element as `any` because the constructor signature cannot reference + // browser globals (HTMLElement) on non-browser environments, since having a class decorator + // causes TypeScript to preserve the constructor signature types. + this._liveElement = elementToken || this._createLiveElement(); + } + /** + * Announces a message to screenreaders. + * @param message Message to be announced to the screenreader + * @param politeness The politeness of the announcer element + */ + /** + * Announces a message to screenreaders. + * @param {?} message Message to be announced to the screenreader + * @param {?=} politeness The politeness of the announcer element + * @return {?} + */ + LiveAnnouncer.prototype.announce = /** + * Announces a message to screenreaders. + * @param {?} message Message to be announced to the screenreader + * @param {?=} politeness The politeness of the announcer element + * @return {?} + */ + function (message, politeness) { + var _this = this; + if (politeness === void 0) { politeness = 'polite'; } + this._liveElement.textContent = ''; + // TODO: ensure changing the politeness works on all environments we support. + this._liveElement.setAttribute('aria-live', politeness); + // This 100ms timeout is necessary for some browser + screen-reader combinations: + // - Both JAWS and NVDA over IE11 will not announce anything without a non-zero timeout. + // - With Chrome and IE11 with NVDA or JAWS, a repeated (identical) message won't be read a + // second time without clearing and then using a non-zero delay. + // (using JAWS 17 at time of this writing). + setTimeout(function () { return _this._liveElement.textContent = message; }, 100); + }; + /** + * @return {?} + */ + LiveAnnouncer.prototype.ngOnDestroy = /** + * @return {?} + */ + function () { + if (this._liveElement && this._liveElement.parentNode) { + this._liveElement.parentNode.removeChild(this._liveElement); + } + }; + /** + * @return {?} + */ + LiveAnnouncer.prototype._createLiveElement = /** + * @return {?} + */ + function () { + var /** @type {?} */ liveEl = this._document.createElement('div'); + liveEl.classList.add('cdk-visually-hidden'); + liveEl.setAttribute('aria-atomic', 'true'); + liveEl.setAttribute('aria-live', 'polite'); + this._document.body.appendChild(liveEl); + return liveEl; + }; + LiveAnnouncer.decorators = [ + { type: _angular_core.Injectable }, + ]; + /** @nocollapse */ + LiveAnnouncer.ctorParameters = function () { return [ + { type: undefined, decorators: [{ type: _angular_core.Optional }, { type: _angular_core.Inject, args: [LIVE_ANNOUNCER_ELEMENT_TOKEN,] },] }, + { type: undefined, decorators: [{ type: _angular_core.Inject, args: [_angular_common.DOCUMENT,] },] }, + ]; }; + return LiveAnnouncer; +}()); +/** + * \@docs-private + * @param {?} parentDispatcher + * @param {?} liveElement + * @param {?} _document + * @return {?} + */ +function LIVE_ANNOUNCER_PROVIDER_FACTORY(parentDispatcher, liveElement, _document) { + return parentDispatcher || new LiveAnnouncer(liveElement, _document); +} +/** + * \@docs-private + */ +var LIVE_ANNOUNCER_PROVIDER = { + // If there is already a LiveAnnouncer available, use that. Otherwise, provide a new one. + provide: LiveAnnouncer, + deps: [ + [new _angular_core.Optional(), new _angular_core.SkipSelf(), LiveAnnouncer], + [new _angular_core.Optional(), new _angular_core.Inject(LIVE_ANNOUNCER_ELEMENT_TOKEN)], + _angular_common.DOCUMENT, + ], + useFactory: LIVE_ANNOUNCER_PROVIDER_FACTORY +}; + +/** + * @fileoverview added by tsickle + * @suppress {checkTypes} checked by tsc + */ + +// This is the value used by AngularJS Material. Through trial and error (on iPhone 6S) they found +// that a value of around 650ms seems appropriate. +var TOUCH_BUFFER_MS = 650; +/** + * Monitors mouse and keyboard events to determine the cause of focus events. + */ +var FocusMonitor = /** @class */ (function () { + function FocusMonitor(_ngZone, _platform) { + this._ngZone = _ngZone; + this._platform = _platform; + /** + * The focus origin that the next focus event is a result of. + */ + this._origin = null; + /** + * Whether the window has just been focused. + */ + this._windowFocused = false; + /** + * Map of elements being monitored to their info. + */ + this._elementInfo = new Map(); + /** + * A map of global objects to lists of current listeners. + */ + this._unregisterGlobalListeners = function () { }; + /** + * The number of elements currently being monitored. + */ + this._monitoredElementCount = 0; + } + /** + * @param {?} element + * @param {?=} renderer + * @param {?=} checkChildren + * @return {?} + */ + FocusMonitor.prototype.monitor = /** + * @param {?} element + * @param {?=} renderer + * @param {?=} checkChildren + * @return {?} + */ + function (element, renderer, checkChildren) { + var _this = this; + // TODO(mmalerba): clean up after deprecated signature is removed. + if (!(renderer instanceof _angular_core.Renderer2)) { + checkChildren = renderer; + } + checkChildren = !!checkChildren; + // Do nothing if we're not on the browser platform. + if (!this._platform.isBrowser) { + return rxjs_observable_of.of(null); + } + // Check if we're already monitoring this element. + if (this._elementInfo.has(element)) { + var /** @type {?} */ cachedInfo = this._elementInfo.get(element); /** @type {?} */ + ((cachedInfo)).checkChildren = checkChildren; + return /** @type {?} */ ((cachedInfo)).subject.asObservable(); + } + // Create monitored element info. + var /** @type {?} */ info = { + unlisten: function () { }, + checkChildren: checkChildren, + subject: new rxjs_Subject.Subject() + }; + this._elementInfo.set(element, info); + this._incrementMonitoredElementCount(); + // Start listening. We need to listen in capture phase since focus events don't bubble. + var /** @type {?} */ focusListener = function (event) { return _this._onFocus(event, element); }; + var /** @type {?} */ blurListener = function (event) { return _this._onBlur(event, element); }; + this._ngZone.runOutsideAngular(function () { + element.addEventListener('focus', focusListener, true); + element.addEventListener('blur', blurListener, true); + }); + // Create an unlisten function for later. + info.unlisten = function () { + element.removeEventListener('focus', focusListener, true); + element.removeEventListener('blur', blurListener, true); + }; + return info.subject.asObservable(); + }; + /** + * Stops monitoring an element and removes all focus classes. + * @param element The element to stop monitoring. + */ + /** + * Stops monitoring an element and removes all focus classes. + * @param {?} element The element to stop monitoring. + * @return {?} + */ + FocusMonitor.prototype.stopMonitoring = /** + * Stops monitoring an element and removes all focus classes. + * @param {?} element The element to stop monitoring. + * @return {?} + */ + function (element) { + var /** @type {?} */ elementInfo = this._elementInfo.get(element); + if (elementInfo) { + elementInfo.unlisten(); + elementInfo.subject.complete(); + this._setClasses(element); + this._elementInfo.delete(element); + this._decrementMonitoredElementCount(); + } + }; + /** + * Focuses the element via the specified focus origin. + * @param element The element to focus. + * @param origin The focus origin. + */ + /** + * Focuses the element via the specified focus origin. + * @param {?} element The element to focus. + * @param {?} origin The focus origin. + * @return {?} + */ + FocusMonitor.prototype.focusVia = /** + * Focuses the element via the specified focus origin. + * @param {?} element The element to focus. + * @param {?} origin The focus origin. + * @return {?} + */ + function (element, origin) { + this._setOriginForCurrentEventQueue(origin); + element.focus(); + }; + /** + * @return {?} + */ + FocusMonitor.prototype.ngOnDestroy = /** + * @return {?} + */ + function () { + var _this = this; + this._elementInfo.forEach(function (_info, element) { return _this.stopMonitoring(element); }); + }; + /** + * Register necessary event listeners on the document and window. + * @return {?} + */ + FocusMonitor.prototype._registerGlobalListeners = /** + * Register necessary event listeners on the document and window. + * @return {?} + */ + function () { + var _this = this; + // Do nothing if we're not on the browser platform. + if (!this._platform.isBrowser) { + return; + } + // On keydown record the origin and clear any touch event that may be in progress. + var /** @type {?} */ documentKeydownListener = function () { + _this._lastTouchTarget = null; + _this._setOriginForCurrentEventQueue('keyboard'); + }; + // On mousedown record the origin only if there is not touch target, since a mousedown can + // happen as a result of a touch event. + var /** @type {?} */ documentMousedownListener = function () { + if (!_this._lastTouchTarget) { + _this._setOriginForCurrentEventQueue('mouse'); + } + }; + // When the touchstart event fires the focus event is not yet in the event queue. This means + // we can't rely on the trick used above (setting timeout of 0ms). Instead we wait 650ms to + // see if a focus happens. + var /** @type {?} */ documentTouchstartListener = function (event) { + if (_this._touchTimeoutId != null) { + clearTimeout(_this._touchTimeoutId); + } + _this._lastTouchTarget = event.target; + _this._touchTimeoutId = setTimeout(function () { return _this._lastTouchTarget = null; }, TOUCH_BUFFER_MS); + }; + // Make a note of when the window regains focus, so we can restore the origin info for the + // focused element. + var /** @type {?} */ windowFocusListener = function () { + _this._windowFocused = true; + _this._windowFocusTimeoutId = setTimeout(function () { return _this._windowFocused = false; }, 0); + }; + // Note: we listen to events in the capture phase so we can detect them even if the user stops + // propagation. + this._ngZone.runOutsideAngular(function () { + document.addEventListener('keydown', documentKeydownListener, true); + document.addEventListener('mousedown', documentMousedownListener, true); + document.addEventListener('touchstart', documentTouchstartListener, _angular_cdk_platform.supportsPassiveEventListeners() ? (/** @type {?} */ ({ passive: true, capture: true })) : true); + window.addEventListener('focus', windowFocusListener); + }); + this._unregisterGlobalListeners = function () { + document.removeEventListener('keydown', documentKeydownListener, true); + document.removeEventListener('mousedown', documentMousedownListener, true); + document.removeEventListener('touchstart', documentTouchstartListener, _angular_cdk_platform.supportsPassiveEventListeners() ? (/** @type {?} */ ({ passive: true, capture: true })) : true); + window.removeEventListener('focus', windowFocusListener); + // Clear timeouts for all potentially pending timeouts to prevent the leaks. + clearTimeout(_this._windowFocusTimeoutId); + clearTimeout(_this._touchTimeoutId); + clearTimeout(_this._originTimeoutId); + }; + }; + /** + * @param {?} element + * @param {?} className + * @param {?} shouldSet + * @return {?} + */ + FocusMonitor.prototype._toggleClass = /** + * @param {?} element + * @param {?} className + * @param {?} shouldSet + * @return {?} + */ + function (element, className, shouldSet) { + if (shouldSet) { + element.classList.add(className); + } + else { + element.classList.remove(className); + } + }; + /** + * Sets the focus classes on the element based on the given focus origin. + * @param {?} element The element to update the classes on. + * @param {?=} origin The focus origin. + * @return {?} + */ + FocusMonitor.prototype._setClasses = /** + * Sets the focus classes on the element based on the given focus origin. + * @param {?} element The element to update the classes on. + * @param {?=} origin The focus origin. + * @return {?} + */ + function (element, origin) { + var /** @type {?} */ elementInfo = this._elementInfo.get(element); + if (elementInfo) { + this._toggleClass(element, 'cdk-focused', !!origin); + this._toggleClass(element, 'cdk-touch-focused', origin === 'touch'); + this._toggleClass(element, 'cdk-keyboard-focused', origin === 'keyboard'); + this._toggleClass(element, 'cdk-mouse-focused', origin === 'mouse'); + this._toggleClass(element, 'cdk-program-focused', origin === 'program'); + } + }; + /** + * Sets the origin and schedules an async function to clear it at the end of the event queue. + * @param {?} origin The origin to set. + * @return {?} + */ + FocusMonitor.prototype._setOriginForCurrentEventQueue = /** + * Sets the origin and schedules an async function to clear it at the end of the event queue. + * @param {?} origin The origin to set. + * @return {?} + */ + function (origin) { + var _this = this; + this._origin = origin; + this._originTimeoutId = setTimeout(function () { return _this._origin = null; }, 0); + }; + /** + * Checks whether the given focus event was caused by a touchstart event. + * @param {?} event The focus event to check. + * @return {?} Whether the event was caused by a touch. + */ + FocusMonitor.prototype._wasCausedByTouch = /** + * Checks whether the given focus event was caused by a touchstart event. + * @param {?} event The focus event to check. + * @return {?} Whether the event was caused by a touch. + */ + function (event) { + // Note(mmalerba): This implementation is not quite perfect, there is a small edge case. + // Consider the following dom structure: + // + // <div #parent tabindex="0" cdkFocusClasses> + // <div #child (click)="#parent.focus()"></div> + // </div> + // + // If the user touches the #child element and the #parent is programmatically focused as a + // result, this code will still consider it to have been caused by the touch event and will + // apply the cdk-touch-focused class rather than the cdk-program-focused class. This is a + // relatively small edge-case that can be worked around by using + // focusVia(parentEl, 'program') to focus the parent element. + // + // If we decide that we absolutely must handle this case correctly, we can do so by listening + // for the first focus event after the touchstart, and then the first blur event after that + // focus event. When that blur event fires we know that whatever follows is not a result of the + // touchstart. + var /** @type {?} */ focusTarget = event.target; + return this._lastTouchTarget instanceof Node && focusTarget instanceof Node && + (focusTarget === this._lastTouchTarget || focusTarget.contains(this._lastTouchTarget)); + }; + /** + * Handles focus events on a registered element. + * @param {?} event The focus event. + * @param {?} element The monitored element. + * @return {?} + */ + FocusMonitor.prototype._onFocus = /** + * Handles focus events on a registered element. + * @param {?} event The focus event. + * @param {?} element The monitored element. + * @return {?} + */ + function (event, element) { + // NOTE(mmalerba): We currently set the classes based on the focus origin of the most recent + // focus event affecting the monitored element. If we want to use the origin of the first event + // instead we should check for the cdk-focused class here and return if the element already has + // it. (This only matters for elements that have includesChildren = true). + // If we are not counting child-element-focus as focused, make sure that the event target is the + // monitore
<TRUNCATED>
