@angular/cdk 7.1.0 → 7.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/_a11y.scss +1 -1
- package/a11y/typings/focus-monitor/focus-monitor.d.ts +20 -5
- package/a11y/typings/focus-trap/focus-trap.d.ts +2 -0
- package/a11y/typings/index.metadata.json +1 -1
- package/bundles/cdk-a11y.umd.js +428 -197
- package/bundles/cdk-a11y.umd.js.map +1 -1
- package/bundles/cdk-a11y.umd.min.js +1 -1
- package/bundles/cdk-a11y.umd.min.js.map +1 -1
- package/bundles/cdk-accordion.umd.js +16 -9
- package/bundles/cdk-accordion.umd.js.map +1 -1
- package/bundles/cdk-accordion.umd.min.js.map +1 -1
- package/bundles/cdk-bidi.umd.js +11 -6
- package/bundles/cdk-bidi.umd.js.map +1 -1
- package/bundles/cdk-bidi.umd.min.js.map +1 -1
- package/bundles/cdk-coercion.umd.js +25 -9
- package/bundles/cdk-coercion.umd.js.map +1 -1
- package/bundles/cdk-coercion.umd.min.js +1 -1
- package/bundles/cdk-coercion.umd.min.js.map +1 -1
- package/bundles/cdk-collections.umd.js +28 -5
- package/bundles/cdk-collections.umd.js.map +1 -1
- package/bundles/cdk-collections.umd.min.js.map +1 -1
- package/bundles/cdk-drag-drop.umd.js +2297 -973
- package/bundles/cdk-drag-drop.umd.js.map +1 -1
- package/bundles/cdk-drag-drop.umd.min.js +2 -1
- package/bundles/cdk-drag-drop.umd.min.js.map +1 -1
- package/bundles/cdk-keycodes.umd.js +12 -2
- package/bundles/cdk-keycodes.umd.js.map +1 -1
- package/bundles/cdk-layout.umd.js +29 -22
- package/bundles/cdk-layout.umd.js.map +1 -1
- package/bundles/cdk-layout.umd.min.js +1 -1
- package/bundles/cdk-layout.umd.min.js.map +1 -1
- package/bundles/cdk-observers.umd.js +27 -8
- package/bundles/cdk-observers.umd.js.map +1 -1
- package/bundles/cdk-observers.umd.min.js +1 -1
- package/bundles/cdk-observers.umd.min.js.map +1 -1
- package/bundles/cdk-overlay.umd.js +586 -240
- package/bundles/cdk-overlay.umd.js.map +1 -1
- package/bundles/cdk-overlay.umd.min.js +2 -2
- package/bundles/cdk-overlay.umd.min.js.map +1 -1
- package/bundles/cdk-platform.umd.js +50 -28
- package/bundles/cdk-platform.umd.js.map +1 -1
- package/bundles/cdk-platform.umd.min.js.map +1 -1
- package/bundles/cdk-portal.umd.js +17 -10
- package/bundles/cdk-portal.umd.js.map +1 -1
- package/bundles/cdk-portal.umd.min.js.map +1 -1
- package/bundles/cdk-scrolling.umd.js +148 -50
- package/bundles/cdk-scrolling.umd.js.map +1 -1
- package/bundles/cdk-scrolling.umd.min.js +1 -1
- package/bundles/cdk-scrolling.umd.min.js.map +1 -1
- package/bundles/cdk-stepper.umd.js +69 -27
- package/bundles/cdk-stepper.umd.js.map +1 -1
- package/bundles/cdk-stepper.umd.min.js +1 -1
- package/bundles/cdk-stepper.umd.min.js.map +1 -1
- package/bundles/cdk-table.umd.js +189 -51
- package/bundles/cdk-table.umd.js.map +1 -1
- package/bundles/cdk-table.umd.min.js +1 -1
- package/bundles/cdk-table.umd.min.js.map +1 -1
- package/bundles/cdk-text-field.umd.js +76 -38
- package/bundles/cdk-text-field.umd.js.map +1 -1
- package/bundles/cdk-text-field.umd.min.js +1 -1
- package/bundles/cdk-text-field.umd.min.js.map +1 -1
- package/bundles/cdk-tree.umd.js +71 -34
- package/bundles/cdk-tree.umd.js.map +1 -1
- package/bundles/cdk-tree.umd.min.js +1 -1
- package/bundles/cdk-tree.umd.min.js.map +1 -1
- package/bundles/cdk.umd.js +5 -4
- package/bundles/cdk.umd.js.map +1 -1
- package/bundles/cdk.umd.min.js +1 -1
- package/bundles/cdk.umd.min.js.map +1 -1
- package/coercion/typings/element.d.ts +13 -0
- package/coercion/typings/index.metadata.json +1 -1
- package/coercion/typings/public-api.d.ts +1 -0
- package/drag-drop/typings/{drag-handle.d.ts → directives/drag-handle.d.ts} +6 -2
- package/drag-drop/typings/{drag-placeholder.d.ts → directives/drag-placeholder.d.ts} +0 -0
- package/drag-drop/typings/{drag-preview.d.ts → directives/drag-preview.d.ts} +0 -0
- package/drag-drop/typings/directives/drag.d.ts +110 -0
- package/{typings/esm5/drag-drop → drag-drop/typings/directives}/drop-list-group.d.ts +3 -0
- package/drag-drop/typings/{drop-list.d.ts → directives/drop-list.d.ts} +32 -72
- package/drag-drop/typings/drag-drop-registry.d.ts +8 -3
- package/drag-drop/typings/drag-events.d.ts +14 -7
- package/{typings/esm5/drag-drop/drag.d.ts → drag-drop/typings/drag-ref.d.ts} +152 -83
- package/drag-drop/typings/drop-list-container.d.ts +19 -3
- package/drag-drop/typings/drop-list-ref.d.ts +234 -0
- package/drag-drop/typings/index.d.ts +1 -0
- package/drag-drop/typings/index.metadata.json +1 -1
- package/drag-drop/typings/public-api.d.ts +13 -6
- package/esm2015/a11y.js +306 -182
- package/esm2015/a11y.js.map +1 -1
- package/esm2015/accordion.js +16 -11
- package/esm2015/accordion.js.map +1 -1
- package/esm2015/bidi.js +13 -8
- package/esm2015/bidi.js.map +1 -1
- package/esm2015/cdk.js +7 -6
- package/esm2015/cdk.js.map +1 -1
- package/esm2015/coercion.js +25 -8
- package/esm2015/coercion.js.map +1 -1
- package/esm2015/collections.js +22 -7
- package/esm2015/collections.js.map +1 -1
- package/esm2015/drag-drop.js +1774 -864
- package/esm2015/drag-drop.js.map +1 -1
- package/esm2015/keycodes.js +14 -4
- package/esm2015/keycodes.js.map +1 -1
- package/esm2015/layout.js +29 -19
- package/esm2015/layout.js.map +1 -1
- package/esm2015/observers.js +16 -11
- package/esm2015/observers.js.map +1 -1
- package/esm2015/overlay.js +373 -213
- package/esm2015/overlay.js.map +1 -1
- package/esm2015/platform.js +53 -31
- package/esm2015/platform.js.map +1 -1
- package/esm2015/portal.js +14 -10
- package/esm2015/portal.js.map +1 -1
- package/esm2015/scrolling.js +111 -51
- package/esm2015/scrolling.js.map +1 -1
- package/esm2015/stepper.js +56 -30
- package/esm2015/stepper.js.map +1 -1
- package/esm2015/table.js +96 -48
- package/esm2015/table.js.map +1 -1
- package/esm2015/text-field.js +54 -37
- package/esm2015/text-field.js.map +1 -1
- package/esm2015/tree.js +55 -36
- package/esm2015/tree.js.map +1 -1
- package/esm5/a11y.es5.js +432 -201
- package/esm5/a11y.es5.js.map +1 -1
- package/esm5/accordion.es5.js +18 -11
- package/esm5/accordion.es5.js.map +1 -1
- package/esm5/bidi.es5.js +13 -8
- package/esm5/bidi.es5.js.map +1 -1
- package/esm5/cdk.es5.js +7 -6
- package/esm5/cdk.es5.js.map +1 -1
- package/esm5/coercion.es5.js +25 -8
- package/esm5/coercion.es5.js.map +1 -1
- package/esm5/collections.es5.js +35 -7
- package/esm5/collections.es5.js.map +1 -1
- package/esm5/drag-drop.es5.js +2358 -1035
- package/esm5/drag-drop.es5.js.map +1 -1
- package/esm5/keycodes.es5.js +14 -4
- package/esm5/keycodes.es5.js.map +1 -1
- package/esm5/layout.es5.js +31 -24
- package/esm5/layout.es5.js.map +1 -1
- package/esm5/observers.es5.js +30 -11
- package/esm5/observers.es5.js.map +1 -1
- package/esm5/overlay.es5.js +590 -244
- package/esm5/overlay.es5.js.map +1 -1
- package/esm5/platform.es5.js +52 -30
- package/esm5/platform.es5.js.map +1 -1
- package/esm5/portal.es5.js +19 -12
- package/esm5/portal.es5.js.map +1 -1
- package/esm5/scrolling.es5.js +150 -52
- package/esm5/scrolling.es5.js.map +1 -1
- package/esm5/stepper.es5.js +71 -30
- package/esm5/stepper.es5.js.map +1 -1
- package/esm5/table.es5.js +191 -53
- package/esm5/table.es5.js.map +1 -1
- package/esm5/text-field.es5.js +75 -37
- package/esm5/text-field.es5.js.map +1 -1
- package/esm5/tree.es5.js +74 -37
- package/esm5/tree.es5.js.map +1 -1
- package/overlay/typings/index.metadata.json +1 -1
- package/overlay/typings/overlay-directives.d.ts +0 -2
- package/overlay/typings/overlay-ref.d.ts +1 -1
- package/package.json +4 -4
- package/portal/typings/portal.d.ts +1 -1
- package/schematics/migration.json +5 -0
- package/schematics/ng-generate/drag-drop/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.ts +2 -2
- package/schematics/ng-update/index.d.ts +2 -0
- package/schematics/ng-update/index.js +5 -0
- package/schematics/ng-update/index.js.map +1 -1
- package/schematics/ng-update/target-version.d.ts +7 -1
- package/schematics/ng-update/target-version.js +10 -0
- package/schematics/ng-update/target-version.js.map +1 -1
- package/schematics/ng-update/upgrade-data.js +2 -1
- package/schematics/ng-update/upgrade-data.js.map +1 -1
- package/schematics/ng-update/upgrade-rules/index.js +3 -2
- package/schematics/ng-update/upgrade-rules/index.js.map +1 -1
- package/schematics/utils/ast/ng-module-imports.d.ts +1 -1
- package/schematics/utils/ast/ng-module-imports.js +25 -13
- package/schematics/utils/ast/ng-module-imports.js.map +1 -1
- package/schematics/utils/get-project.js +2 -1
- package/schematics/utils/get-project.js.map +1 -1
- package/schematics/utils/parse5-element.js +3 -2
- package/schematics/utils/parse5-element.js.map +1 -1
- package/schematics/utils/project-targets.js +2 -1
- package/schematics/utils/project-targets.js.map +1 -1
- package/schematics/utils/version-agnostic-typescript.js +3 -2
- package/schematics/utils/version-agnostic-typescript.js.map +1 -1
- package/scrolling/typings/index.metadata.json +1 -1
- package/stepper/typings/index.metadata.json +1 -1
- package/stepper/typings/stepper.d.ts +13 -1
- package/text-field/typings/autosize.d.ts +6 -0
- package/text-field/typings/index.metadata.json +1 -1
- package/tree/typings/control/base-tree-control.d.ts +1 -1
- package/tree/typings/control/nested-tree-control.d.ts +2 -2
- package/tree/typings/control/tree-control.d.ts +1 -1
- package/tree/typings/nested-node.d.ts +5 -5
- package/typings/a11y/focus-monitor/focus-monitor.d.ts +20 -5
- package/typings/a11y/focus-trap/focus-trap.d.ts +2 -0
- package/typings/a11y/index.metadata.json +1 -1
- package/typings/coercion/element.d.ts +13 -0
- package/typings/coercion/index.metadata.json +1 -1
- package/typings/coercion/public-api.d.ts +1 -0
- package/typings/drag-drop/{drag-handle.d.ts → directives/drag-handle.d.ts} +6 -2
- package/typings/drag-drop/{drag-placeholder.d.ts → directives/drag-placeholder.d.ts} +0 -0
- package/typings/drag-drop/{drag-preview.d.ts → directives/drag-preview.d.ts} +0 -0
- package/typings/drag-drop/directives/drag.d.ts +110 -0
- package/typings/drag-drop/{drop-list-group.d.ts → directives/drop-list-group.d.ts} +3 -0
- package/typings/{esm5/drag-drop → drag-drop/directives}/drop-list.d.ts +32 -72
- package/typings/drag-drop/drag-drop-registry.d.ts +8 -3
- package/typings/drag-drop/drag-events.d.ts +14 -7
- package/typings/drag-drop/{drag.d.ts → drag-ref.d.ts} +152 -83
- package/typings/drag-drop/drop-list-container.d.ts +19 -3
- package/typings/drag-drop/drop-list-ref.d.ts +234 -0
- package/typings/drag-drop/index.d.ts +1 -0
- package/typings/drag-drop/index.metadata.json +1 -1
- package/typings/drag-drop/public-api.d.ts +13 -6
- package/typings/esm5/a11y/focus-monitor/focus-monitor.d.ts +20 -5
- package/typings/esm5/a11y/focus-trap/focus-trap.d.ts +2 -0
- package/typings/esm5/a11y/index.metadata.json +1 -1
- package/typings/esm5/coercion/element.d.ts +13 -0
- package/typings/esm5/coercion/index.metadata.json +1 -1
- package/typings/esm5/coercion/public-api.d.ts +1 -0
- package/typings/esm5/drag-drop/{drag-handle.d.ts → directives/drag-handle.d.ts} +6 -2
- package/typings/esm5/drag-drop/{drag-placeholder.d.ts → directives/drag-placeholder.d.ts} +0 -0
- package/typings/esm5/drag-drop/{drag-preview.d.ts → directives/drag-preview.d.ts} +0 -0
- package/typings/esm5/drag-drop/directives/drag.d.ts +110 -0
- package/{drag-drop/typings → typings/esm5/drag-drop/directives}/drop-list-group.d.ts +3 -0
- package/typings/{drag-drop → esm5/drag-drop/directives}/drop-list.d.ts +32 -72
- package/typings/esm5/drag-drop/drag-drop-registry.d.ts +8 -3
- package/typings/esm5/drag-drop/drag-events.d.ts +14 -7
- package/{drag-drop/typings/drag.d.ts → typings/esm5/drag-drop/drag-ref.d.ts} +152 -83
- package/typings/esm5/drag-drop/drop-list-container.d.ts +19 -3
- package/typings/esm5/drag-drop/drop-list-ref.d.ts +234 -0
- package/typings/esm5/drag-drop/index.d.ts +1 -0
- package/typings/esm5/drag-drop/index.metadata.json +1 -1
- package/typings/esm5/drag-drop/public-api.d.ts +13 -6
- package/typings/esm5/index.metadata.json +1 -1
- package/typings/esm5/overlay/index.metadata.json +1 -1
- package/typings/esm5/overlay/overlay-directives.d.ts +0 -2
- package/typings/esm5/overlay/overlay-ref.d.ts +1 -1
- package/typings/esm5/portal/portal.d.ts +1 -1
- package/typings/esm5/scrolling/index.metadata.json +1 -1
- package/typings/esm5/stepper/index.metadata.json +1 -1
- package/typings/esm5/stepper/stepper.d.ts +13 -1
- package/typings/esm5/text-field/autosize.d.ts +6 -0
- package/typings/esm5/text-field/index.metadata.json +1 -1
- package/typings/esm5/tree/control/base-tree-control.d.ts +1 -1
- package/typings/esm5/tree/control/nested-tree-control.d.ts +2 -2
- package/typings/esm5/tree/control/tree-control.d.ts +1 -1
- package/typings/esm5/tree/nested-node.d.ts +5 -5
- package/typings/index.metadata.json +1 -1
- package/typings/overlay/index.metadata.json +1 -1
- package/typings/overlay/overlay-directives.d.ts +0 -2
- package/typings/overlay/overlay-ref.d.ts +1 -1
- package/typings/portal/portal.d.ts +1 -1
- package/typings/schematics/ng-update/index.d.ts +2 -0
- package/typings/schematics/ng-update/target-version.d.ts +7 -1
- package/typings/schematics/utils/ast/ng-module-imports.d.ts +1 -1
- package/typings/scrolling/index.metadata.json +1 -1
- package/typings/stepper/index.metadata.json +1 -1
- package/typings/stepper/stepper.d.ts +13 -1
- package/typings/text-field/autosize.d.ts +6 -0
- package/typings/text-field/index.metadata.json +1 -1
- package/typings/tree/control/base-tree-control.d.ts +1 -1
- package/typings/tree/control/nested-tree-control.d.ts +2 -2
- package/typings/tree/control/tree-control.d.ts +1 -1
- package/typings/tree/nested-node.d.ts +5 -5
package/esm2015/a11y.js
CHANGED
|
@@ -8,20 +8,21 @@
|
|
|
8
8
|
import { DOCUMENT, CommonModule } from '@angular/common';
|
|
9
9
|
import { Inject, Injectable, Optional, SkipSelf, QueryList, Directive, ElementRef, Input, NgZone, isDevMode, InjectionToken, EventEmitter, Output, NgModule, defineInjectable, inject } from '@angular/core';
|
|
10
10
|
import { Subject, Subscription, of } from 'rxjs';
|
|
11
|
-
import { UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, TAB, A, Z, ZERO, NINE } from '@angular/cdk/keycodes';
|
|
11
|
+
import { UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, TAB, A, Z, ZERO, NINE, hasModifierKey } from '@angular/cdk/keycodes';
|
|
12
12
|
import { debounceTime, filter, map, tap, take } from 'rxjs/operators';
|
|
13
13
|
import { Platform, normalizePassiveListenerOptions, PlatformModule } from '@angular/cdk/platform';
|
|
14
|
-
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
14
|
+
import { coerceBooleanProperty, coerceElement } from '@angular/cdk/coercion';
|
|
15
15
|
import { ContentObserver, ObserversModule } from '@angular/cdk/observers';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @fileoverview added by tsickle
|
|
19
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
19
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
23
|
* IDs are deliminated by an empty space, as per the spec.
|
|
24
|
-
|
|
24
|
+
* @type {?}
|
|
25
|
+
*/
|
|
25
26
|
const ID_DELIMINATOR = ' ';
|
|
26
27
|
/**
|
|
27
28
|
* Adds the given ID to the specified ARIA attribute on an element.
|
|
@@ -69,31 +70,37 @@ function getAriaReferenceIds(el, attr) {
|
|
|
69
70
|
|
|
70
71
|
/**
|
|
71
72
|
* @fileoverview added by tsickle
|
|
72
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
73
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
73
74
|
*/
|
|
74
|
-
/**
|
|
75
|
+
/**
|
|
75
76
|
* ID used for the body container where all messages are appended.
|
|
76
|
-
|
|
77
|
+
* @type {?}
|
|
78
|
+
*/
|
|
77
79
|
const MESSAGES_CONTAINER_ID = 'cdk-describedby-message-container';
|
|
78
|
-
/**
|
|
80
|
+
/**
|
|
79
81
|
* ID prefix used for each created message element.
|
|
80
|
-
|
|
82
|
+
* @type {?}
|
|
83
|
+
*/
|
|
81
84
|
const CDK_DESCRIBEDBY_ID_PREFIX = 'cdk-describedby-message';
|
|
82
|
-
/**
|
|
85
|
+
/**
|
|
83
86
|
* Attribute given to each host element that is described by a message element.
|
|
84
|
-
|
|
87
|
+
* @type {?}
|
|
88
|
+
*/
|
|
85
89
|
const CDK_DESCRIBEDBY_HOST_ATTRIBUTE = 'cdk-describedby-host';
|
|
86
|
-
/**
|
|
90
|
+
/**
|
|
87
91
|
* Global incremental identifier for each registered message element.
|
|
88
|
-
|
|
92
|
+
* @type {?}
|
|
93
|
+
*/
|
|
89
94
|
let nextId = 0;
|
|
90
|
-
/**
|
|
95
|
+
/**
|
|
91
96
|
* Global map of all registered message elements that have been placed into the document.
|
|
92
|
-
|
|
97
|
+
* @type {?}
|
|
98
|
+
*/
|
|
93
99
|
const messageRegistry = new Map();
|
|
94
|
-
/**
|
|
100
|
+
/**
|
|
95
101
|
* Container for all registered messages.
|
|
96
|
-
|
|
102
|
+
* @type {?}
|
|
103
|
+
*/
|
|
97
104
|
let messagesContainer = null;
|
|
98
105
|
/**
|
|
99
106
|
* Utility that creates visually hidden elements with a message content. Useful for elements that
|
|
@@ -168,6 +175,7 @@ class AriaDescriber {
|
|
|
168
175
|
/**
|
|
169
176
|
* Creates a new element in the visually hidden message container element with the message
|
|
170
177
|
* as its content and adds it to the message registry.
|
|
178
|
+
* @private
|
|
171
179
|
* @param {?} message
|
|
172
180
|
* @return {?}
|
|
173
181
|
*/
|
|
@@ -175,13 +183,14 @@ class AriaDescriber {
|
|
|
175
183
|
/** @type {?} */
|
|
176
184
|
const messageElement = this._document.createElement('div');
|
|
177
185
|
messageElement.setAttribute('id', `${CDK_DESCRIBEDBY_ID_PREFIX}-${nextId++}`);
|
|
178
|
-
messageElement.appendChild(/** @type {?} */ (
|
|
179
|
-
this._createMessagesContainer();
|
|
180
|
-
((messagesContainer)).appendChild(messageElement);
|
|
186
|
+
messageElement.appendChild((/** @type {?} */ (this._document.createTextNode(message))));
|
|
187
|
+
this._createMessagesContainer();
|
|
188
|
+
(/** @type {?} */ (messagesContainer)).appendChild(messageElement);
|
|
181
189
|
messageRegistry.set(message, { messageElement, referenceCount: 0 });
|
|
182
190
|
}
|
|
183
191
|
/**
|
|
184
192
|
* Deletes the message element from the global messages container.
|
|
193
|
+
* @private
|
|
185
194
|
* @param {?} message
|
|
186
195
|
* @return {?}
|
|
187
196
|
*/
|
|
@@ -197,6 +206,7 @@ class AriaDescriber {
|
|
|
197
206
|
}
|
|
198
207
|
/**
|
|
199
208
|
* Creates the global container for all aria-describedby messages.
|
|
209
|
+
* @private
|
|
200
210
|
* @return {?}
|
|
201
211
|
*/
|
|
202
212
|
_createMessagesContainer() {
|
|
@@ -208,7 +218,7 @@ class AriaDescriber {
|
|
|
208
218
|
// old container so we don't get duplicates. Doing this, instead of emptying the previous
|
|
209
219
|
// container, should be slightly faster.
|
|
210
220
|
if (preExistingContainer) {
|
|
211
|
-
/** @type {?} */ (
|
|
221
|
+
(/** @type {?} */ (preExistingContainer.parentNode)).removeChild(preExistingContainer);
|
|
212
222
|
}
|
|
213
223
|
messagesContainer = this._document.createElement('div');
|
|
214
224
|
messagesContainer.id = MESSAGES_CONTAINER_ID;
|
|
@@ -219,6 +229,7 @@ class AriaDescriber {
|
|
|
219
229
|
}
|
|
220
230
|
/**
|
|
221
231
|
* Deletes the global messages container.
|
|
232
|
+
* @private
|
|
222
233
|
* @return {?}
|
|
223
234
|
*/
|
|
224
235
|
_deleteMessagesContainer() {
|
|
@@ -229,10 +240,12 @@ class AriaDescriber {
|
|
|
229
240
|
}
|
|
230
241
|
/**
|
|
231
242
|
* Removes all cdk-describedby messages that are hosted through the element.
|
|
243
|
+
* @private
|
|
232
244
|
* @param {?} element
|
|
233
245
|
* @return {?}
|
|
234
246
|
*/
|
|
235
247
|
_removeCdkDescribedByReferenceIds(element) {
|
|
248
|
+
// Remove all aria-describedby reference IDs that are prefixed by CDK_DESCRIBEDBY_ID_PREFIX
|
|
236
249
|
/** @type {?} */
|
|
237
250
|
const originalReferenceIds = getAriaReferenceIds(element, 'aria-describedby')
|
|
238
251
|
.filter(id => id.indexOf(CDK_DESCRIBEDBY_ID_PREFIX) != 0);
|
|
@@ -241,13 +254,14 @@ class AriaDescriber {
|
|
|
241
254
|
/**
|
|
242
255
|
* Adds a message reference to the element using aria-describedby and increments the registered
|
|
243
256
|
* message's reference count.
|
|
257
|
+
* @private
|
|
244
258
|
* @param {?} element
|
|
245
259
|
* @param {?} message
|
|
246
260
|
* @return {?}
|
|
247
261
|
*/
|
|
248
262
|
_addMessageReference(element, message) {
|
|
249
263
|
/** @type {?} */
|
|
250
|
-
const registeredMessage = /** @type {?} */ (
|
|
264
|
+
const registeredMessage = (/** @type {?} */ (messageRegistry.get(message)));
|
|
251
265
|
// Add the aria-describedby reference and set the
|
|
252
266
|
// describedby_host attribute to mark the element.
|
|
253
267
|
addAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id);
|
|
@@ -257,19 +271,21 @@ class AriaDescriber {
|
|
|
257
271
|
/**
|
|
258
272
|
* Removes a message reference from the element using aria-describedby
|
|
259
273
|
* and decrements the registered message's reference count.
|
|
274
|
+
* @private
|
|
260
275
|
* @param {?} element
|
|
261
276
|
* @param {?} message
|
|
262
277
|
* @return {?}
|
|
263
278
|
*/
|
|
264
279
|
_removeMessageReference(element, message) {
|
|
265
280
|
/** @type {?} */
|
|
266
|
-
const registeredMessage = /** @type {?} */ (
|
|
281
|
+
const registeredMessage = (/** @type {?} */ (messageRegistry.get(message)));
|
|
267
282
|
registeredMessage.referenceCount--;
|
|
268
283
|
removeAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id);
|
|
269
284
|
element.removeAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE);
|
|
270
285
|
}
|
|
271
286
|
/**
|
|
272
287
|
* Returns true if the element has been described by the provided message ID.
|
|
288
|
+
* @private
|
|
273
289
|
* @param {?} element
|
|
274
290
|
* @param {?} message
|
|
275
291
|
* @return {?}
|
|
@@ -285,6 +301,7 @@ class AriaDescriber {
|
|
|
285
301
|
}
|
|
286
302
|
/**
|
|
287
303
|
* Determines whether a message can be described on a particular element.
|
|
304
|
+
* @private
|
|
288
305
|
* @param {?} element
|
|
289
306
|
* @param {?} message
|
|
290
307
|
* @return {?}
|
|
@@ -311,24 +328,24 @@ AriaDescriber.ctorParameters = () => [
|
|
|
311
328
|
function ARIA_DESCRIBER_PROVIDER_FACTORY(parentDispatcher, _document) {
|
|
312
329
|
return parentDispatcher || new AriaDescriber(_document);
|
|
313
330
|
}
|
|
314
|
-
/**
|
|
331
|
+
/**
|
|
315
332
|
* \@docs-private \@deprecated \@breaking-change 8.0.0
|
|
316
|
-
|
|
333
|
+
* @type {?}
|
|
334
|
+
*/
|
|
317
335
|
const ARIA_DESCRIBER_PROVIDER = {
|
|
318
336
|
// If there is already an AriaDescriber available, use that. Otherwise, provide a new one.
|
|
319
337
|
provide: AriaDescriber,
|
|
320
338
|
deps: [
|
|
321
339
|
[new Optional(), new SkipSelf(), AriaDescriber],
|
|
322
|
-
/** @type {?} */ (DOCUMENT)
|
|
340
|
+
(/** @type {?} */ (DOCUMENT))
|
|
323
341
|
],
|
|
324
342
|
useFactory: ARIA_DESCRIBER_PROVIDER_FACTORY
|
|
325
343
|
};
|
|
326
344
|
|
|
327
345
|
/**
|
|
328
346
|
* @fileoverview added by tsickle
|
|
329
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
347
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
330
348
|
*/
|
|
331
|
-
// unsupported: template constraints.
|
|
332
349
|
/**
|
|
333
350
|
* This class manages keyboard events for selectable lists. If you pass it a query list
|
|
334
351
|
* of items, it will set the active item correctly when arrow events occur.
|
|
@@ -341,6 +358,7 @@ class ListKeyManager {
|
|
|
341
358
|
constructor(_items) {
|
|
342
359
|
this._items = _items;
|
|
343
360
|
this._activeItemIndex = -1;
|
|
361
|
+
this._activeItem = null;
|
|
344
362
|
this._wrap = false;
|
|
345
363
|
this._letterKeyStream = new Subject();
|
|
346
364
|
this._typeaheadSubscription = Subscription.EMPTY;
|
|
@@ -351,6 +369,7 @@ class ListKeyManager {
|
|
|
351
369
|
* by the key manager. By default, disabled items are skipped.
|
|
352
370
|
*/
|
|
353
371
|
this._skipPredicateFn = (item) => item.disabled;
|
|
372
|
+
// Buffer for the letters that the user has pressed when the typeahead option is turned on.
|
|
354
373
|
this._pressedLetters = [];
|
|
355
374
|
/**
|
|
356
375
|
* Stream that emits any time the TAB key is pressed, so components can react
|
|
@@ -381,83 +400,96 @@ class ListKeyManager {
|
|
|
381
400
|
/**
|
|
382
401
|
* Sets the predicate function that determines which items should be skipped by the
|
|
383
402
|
* list key manager.
|
|
403
|
+
* @template THIS
|
|
404
|
+
* @this {THIS}
|
|
384
405
|
* @param {?} predicate Function that determines whether the given item should be skipped.
|
|
385
|
-
* @return {
|
|
406
|
+
* @return {THIS}
|
|
386
407
|
*/
|
|
387
408
|
skipPredicate(predicate) {
|
|
388
|
-
this._skipPredicateFn = predicate;
|
|
389
|
-
return this;
|
|
409
|
+
(/** @type {?} */ (this))._skipPredicateFn = predicate;
|
|
410
|
+
return (/** @type {?} */ (this));
|
|
390
411
|
}
|
|
391
412
|
/**
|
|
392
413
|
* Configures wrapping mode, which determines whether the active item will wrap to
|
|
393
414
|
* the other end of list when there are no more items in the given direction.
|
|
415
|
+
* @template THIS
|
|
416
|
+
* @this {THIS}
|
|
394
417
|
* @param {?=} shouldWrap Whether the list should wrap when reaching the end.
|
|
395
|
-
* @return {
|
|
418
|
+
* @return {THIS}
|
|
396
419
|
*/
|
|
397
420
|
withWrap(shouldWrap = true) {
|
|
398
|
-
this._wrap = shouldWrap;
|
|
399
|
-
return this;
|
|
421
|
+
(/** @type {?} */ (this))._wrap = shouldWrap;
|
|
422
|
+
return (/** @type {?} */ (this));
|
|
400
423
|
}
|
|
401
424
|
/**
|
|
402
425
|
* Configures whether the key manager should be able to move the selection vertically.
|
|
426
|
+
* @template THIS
|
|
427
|
+
* @this {THIS}
|
|
403
428
|
* @param {?=} enabled Whether vertical selection should be enabled.
|
|
404
|
-
* @return {
|
|
429
|
+
* @return {THIS}
|
|
405
430
|
*/
|
|
406
431
|
withVerticalOrientation(enabled = true) {
|
|
407
|
-
this._vertical = enabled;
|
|
408
|
-
return this;
|
|
432
|
+
(/** @type {?} */ (this))._vertical = enabled;
|
|
433
|
+
return (/** @type {?} */ (this));
|
|
409
434
|
}
|
|
410
435
|
/**
|
|
411
436
|
* Configures the key manager to move the selection horizontally.
|
|
412
437
|
* Passing in `null` will disable horizontal movement.
|
|
438
|
+
* @template THIS
|
|
439
|
+
* @this {THIS}
|
|
413
440
|
* @param {?} direction Direction in which the selection can be moved.
|
|
414
|
-
* @return {
|
|
441
|
+
* @return {THIS}
|
|
415
442
|
*/
|
|
416
443
|
withHorizontalOrientation(direction) {
|
|
417
|
-
this._horizontal = direction;
|
|
418
|
-
return this;
|
|
444
|
+
(/** @type {?} */ (this))._horizontal = direction;
|
|
445
|
+
return (/** @type {?} */ (this));
|
|
419
446
|
}
|
|
420
447
|
/**
|
|
421
448
|
* Modifier keys which are allowed to be held down and whose default actions will be prevented
|
|
422
449
|
* as the user is pressing the arrow keys. Defaults to not allowing any modifier keys.
|
|
450
|
+
* @template THIS
|
|
451
|
+
* @this {THIS}
|
|
423
452
|
* @param {?} keys
|
|
424
|
-
* @return {
|
|
453
|
+
* @return {THIS}
|
|
425
454
|
*/
|
|
426
455
|
withAllowedModifierKeys(keys) {
|
|
427
|
-
this._allowedModifierKeys = keys;
|
|
428
|
-
return this;
|
|
456
|
+
(/** @type {?} */ (this))._allowedModifierKeys = keys;
|
|
457
|
+
return (/** @type {?} */ (this));
|
|
429
458
|
}
|
|
430
459
|
/**
|
|
431
460
|
* Turns on typeahead mode which allows users to set the active item by typing.
|
|
461
|
+
* @template THIS
|
|
462
|
+
* @this {THIS}
|
|
432
463
|
* @param {?=} debounceInterval Time to wait after the last keystroke before setting the active item.
|
|
433
|
-
* @return {
|
|
464
|
+
* @return {THIS}
|
|
434
465
|
*/
|
|
435
466
|
withTypeAhead(debounceInterval = 200) {
|
|
436
|
-
if (this._items.length && this._items.some(item => typeof item.getLabel !== 'function')) {
|
|
467
|
+
if ((/** @type {?} */ (this))._items.length && (/** @type {?} */ (this))._items.some(item => typeof item.getLabel !== 'function')) {
|
|
437
468
|
throw Error('ListKeyManager items in typeahead mode must implement the `getLabel` method.');
|
|
438
469
|
}
|
|
439
|
-
this._typeaheadSubscription.unsubscribe();
|
|
470
|
+
(/** @type {?} */ (this))._typeaheadSubscription.unsubscribe();
|
|
440
471
|
// Debounce the presses of non-navigational keys, collect the ones that correspond to letters
|
|
441
472
|
// and convert those letters back into a string. Afterwards find the first item that starts
|
|
442
473
|
// with that string and select it.
|
|
443
|
-
this._typeaheadSubscription = this._letterKeyStream.pipe(tap(keyCode => this._pressedLetters.push(keyCode)), debounceTime(debounceInterval), filter(() => this._pressedLetters.length > 0), map(() => this._pressedLetters.join(''))).subscribe(inputString => {
|
|
474
|
+
(/** @type {?} */ (this))._typeaheadSubscription = (/** @type {?} */ (this))._letterKeyStream.pipe(tap(keyCode => (/** @type {?} */ (this))._pressedLetters.push(keyCode)), debounceTime(debounceInterval), filter(() => (/** @type {?} */ (this))._pressedLetters.length > 0), map(() => (/** @type {?} */ (this))._pressedLetters.join(''))).subscribe(inputString => {
|
|
444
475
|
/** @type {?} */
|
|
445
|
-
const items = this._getItemsArray();
|
|
476
|
+
const items = (/** @type {?} */ (this))._getItemsArray();
|
|
446
477
|
// Start at 1 because we want to start searching at the item immediately
|
|
447
478
|
// following the current active item.
|
|
448
479
|
for (let i = 1; i < items.length + 1; i++) {
|
|
449
480
|
/** @type {?} */
|
|
450
|
-
const index = (this._activeItemIndex + i) % items.length;
|
|
481
|
+
const index = ((/** @type {?} */ (this))._activeItemIndex + i) % items.length;
|
|
451
482
|
/** @type {?} */
|
|
452
483
|
const item = items[index];
|
|
453
|
-
if (!
|
|
454
|
-
|
|
484
|
+
if (!(/** @type {?} */ (this))._skipPredicateFn(item) &&
|
|
485
|
+
(/** @type {?} */ (item.getLabel))().toUpperCase().trim().indexOf(inputString) === 0) {
|
|
486
|
+
(/** @type {?} */ (this)).setActiveItem(index);
|
|
455
487
|
break;
|
|
456
488
|
}
|
|
457
489
|
}
|
|
458
|
-
this._pressedLetters = [];
|
|
490
|
+
(/** @type {?} */ (this))._pressedLetters = [];
|
|
459
491
|
});
|
|
460
|
-
return this;
|
|
492
|
+
return (/** @type {?} */ (this));
|
|
461
493
|
}
|
|
462
494
|
/**
|
|
463
495
|
* @param {?} item
|
|
@@ -522,13 +554,15 @@ class ListKeyManager {
|
|
|
522
554
|
return;
|
|
523
555
|
}
|
|
524
556
|
default:
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
557
|
+
if (isModifierAllowed || hasModifierKey(event, 'shiftKey')) {
|
|
558
|
+
// Attempt to use the `event.key` which also maps it to the user's keyboard language,
|
|
559
|
+
// otherwise fall back to resolving alphanumeric characters via the keyCode.
|
|
560
|
+
if (event.key && event.key.length === 1) {
|
|
561
|
+
this._letterKeyStream.next(event.key.toLocaleUpperCase());
|
|
562
|
+
}
|
|
563
|
+
else if ((keyCode >= A && keyCode <= Z) || (keyCode >= ZERO && keyCode <= NINE)) {
|
|
564
|
+
this._letterKeyStream.next(String.fromCharCode(keyCode));
|
|
565
|
+
}
|
|
532
566
|
}
|
|
533
567
|
// Note that we return here, in order to avoid preventing
|
|
534
568
|
// the default action of non-navigational keys.
|
|
@@ -589,8 +623,11 @@ class ListKeyManager {
|
|
|
589
623
|
const itemArray = this._getItemsArray();
|
|
590
624
|
/** @type {?} */
|
|
591
625
|
const index = typeof item === 'number' ? item : itemArray.indexOf(item);
|
|
626
|
+
/** @type {?} */
|
|
627
|
+
const activeItem = itemArray[index];
|
|
628
|
+
// Explicitly check for `null` and `undefined` because other falsy values are valid.
|
|
629
|
+
this._activeItem = activeItem == null ? null : activeItem;
|
|
592
630
|
this._activeItemIndex = index;
|
|
593
|
-
this._activeItem = itemArray[index];
|
|
594
631
|
}
|
|
595
632
|
/**
|
|
596
633
|
* Allows setting of the activeItemIndex without any other effects.
|
|
@@ -606,6 +643,7 @@ class ListKeyManager {
|
|
|
606
643
|
* This method sets the active item, given a list of items and the delta between the
|
|
607
644
|
* currently active item and the new active item. It will calculate differently
|
|
608
645
|
* depending on whether wrap mode is turned on.
|
|
646
|
+
* @private
|
|
609
647
|
* @param {?} delta
|
|
610
648
|
* @return {?}
|
|
611
649
|
*/
|
|
@@ -616,6 +654,7 @@ class ListKeyManager {
|
|
|
616
654
|
* Sets the active item properly given "wrap" mode. In other words, it will continue to move
|
|
617
655
|
* down the list until it finds an item that is not disabled, and it will wrap if it
|
|
618
656
|
* encounters either end of the list.
|
|
657
|
+
* @private
|
|
619
658
|
* @param {?} delta
|
|
620
659
|
* @return {?}
|
|
621
660
|
*/
|
|
@@ -637,6 +676,7 @@ class ListKeyManager {
|
|
|
637
676
|
* Sets the active item properly given the default mode. In other words, it will
|
|
638
677
|
* continue to move down the list until it finds an item that is not disabled. If
|
|
639
678
|
* it encounters either end of the list, it will stop and not wrap.
|
|
679
|
+
* @private
|
|
640
680
|
* @param {?} delta
|
|
641
681
|
* @return {?}
|
|
642
682
|
*/
|
|
@@ -647,6 +687,7 @@ class ListKeyManager {
|
|
|
647
687
|
* Sets the active item to the first enabled item starting at the index specified. If the
|
|
648
688
|
* item is disabled, it will move in the fallbackDelta direction until it either
|
|
649
689
|
* finds an enabled item or encounters the end of the list.
|
|
690
|
+
* @private
|
|
650
691
|
* @param {?} index
|
|
651
692
|
* @param {?} fallbackDelta
|
|
652
693
|
* @return {?}
|
|
@@ -667,6 +708,7 @@ class ListKeyManager {
|
|
|
667
708
|
}
|
|
668
709
|
/**
|
|
669
710
|
* Returns the items as an array.
|
|
711
|
+
* @private
|
|
670
712
|
* @return {?}
|
|
671
713
|
*/
|
|
672
714
|
_getItemsArray() {
|
|
@@ -676,7 +718,7 @@ class ListKeyManager {
|
|
|
676
718
|
|
|
677
719
|
/**
|
|
678
720
|
* @fileoverview added by tsickle
|
|
679
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
721
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
680
722
|
*/
|
|
681
723
|
/**
|
|
682
724
|
* @template T
|
|
@@ -699,7 +741,7 @@ class ActiveDescendantKeyManager extends ListKeyManager {
|
|
|
699
741
|
|
|
700
742
|
/**
|
|
701
743
|
* @fileoverview added by tsickle
|
|
702
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
744
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
703
745
|
*/
|
|
704
746
|
/**
|
|
705
747
|
* @template T
|
|
@@ -711,12 +753,14 @@ class FocusKeyManager extends ListKeyManager {
|
|
|
711
753
|
}
|
|
712
754
|
/**
|
|
713
755
|
* Sets the focus origin that will be passed in to the items for any subsequent `focus` calls.
|
|
756
|
+
* @template THIS
|
|
757
|
+
* @this {THIS}
|
|
714
758
|
* @param {?} origin Focus origin to be used when focusing items.
|
|
715
|
-
* @return {
|
|
759
|
+
* @return {THIS}
|
|
716
760
|
*/
|
|
717
761
|
setFocusOrigin(origin) {
|
|
718
|
-
this._origin = origin;
|
|
719
|
-
return this;
|
|
762
|
+
(/** @type {?} */ (this))._origin = origin;
|
|
763
|
+
return (/** @type {?} */ (this));
|
|
720
764
|
}
|
|
721
765
|
/**
|
|
722
766
|
* @param {?} item
|
|
@@ -732,8 +776,11 @@ class FocusKeyManager extends ListKeyManager {
|
|
|
732
776
|
|
|
733
777
|
/**
|
|
734
778
|
* @fileoverview added by tsickle
|
|
735
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
779
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
736
780
|
*/
|
|
781
|
+
// The InteractivityChecker leans heavily on the ally.js accessibility utilities.
|
|
782
|
+
// Methods like `isTabbable` are only covering specific edge-cases for the browsers which are
|
|
783
|
+
// supported.
|
|
737
784
|
/**
|
|
738
785
|
* Utility for checking the interactivity of an element, such as whether is is focusable or
|
|
739
786
|
* tabbable.
|
|
@@ -776,7 +823,7 @@ class InteractivityChecker {
|
|
|
776
823
|
* @return {?} Whether the element is tabbable.
|
|
777
824
|
*/
|
|
778
825
|
isTabbable(element) {
|
|
779
|
-
// Nothing is tabbable on the
|
|
826
|
+
// Nothing is tabbable on the server 😎
|
|
780
827
|
if (!this._platform.isBrowser) {
|
|
781
828
|
return false;
|
|
782
829
|
}
|
|
@@ -869,7 +916,7 @@ InteractivityChecker.ctorParameters = () => [
|
|
|
869
916
|
*/
|
|
870
917
|
function getFrameElement(window) {
|
|
871
918
|
try {
|
|
872
|
-
return /** @type {?} */ (window.frameElement);
|
|
919
|
+
return (/** @type {?} */ (window.frameElement));
|
|
873
920
|
}
|
|
874
921
|
catch (_a) {
|
|
875
922
|
return null;
|
|
@@ -958,6 +1005,7 @@ function getTabIndexValue(element) {
|
|
|
958
1005
|
if (!hasValidTabIndex(element)) {
|
|
959
1006
|
return null;
|
|
960
1007
|
}
|
|
1008
|
+
// See browser issue in Gecko https://bugzilla.mozilla.org/show_bug.cgi?id=1128054
|
|
961
1009
|
/** @type {?} */
|
|
962
1010
|
const tabIndex = parseInt(element.getAttribute('tabindex') || '', 10);
|
|
963
1011
|
return isNaN(tabIndex) ? -1 : tabIndex;
|
|
@@ -971,7 +1019,7 @@ function isPotentiallyTabbableIOS(element) {
|
|
|
971
1019
|
/** @type {?} */
|
|
972
1020
|
let nodeName = element.nodeName.toLowerCase();
|
|
973
1021
|
/** @type {?} */
|
|
974
|
-
let inputType = nodeName === 'input' && (/** @type {?} */ (element)).type;
|
|
1022
|
+
let inputType = nodeName === 'input' && ((/** @type {?} */ (element))).type;
|
|
975
1023
|
return inputType === 'text'
|
|
976
1024
|
|| inputType === 'password'
|
|
977
1025
|
|| nodeName === 'select'
|
|
@@ -1005,7 +1053,7 @@ function getWindow(node) {
|
|
|
1005
1053
|
|
|
1006
1054
|
/**
|
|
1007
1055
|
* @fileoverview added by tsickle
|
|
1008
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
1056
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1009
1057
|
*/
|
|
1010
1058
|
/**
|
|
1011
1059
|
* Class that allows for trapping focus within a DOM element.
|
|
@@ -1028,6 +1076,9 @@ class FocusTrap {
|
|
|
1028
1076
|
this._ngZone = _ngZone;
|
|
1029
1077
|
this._document = _document;
|
|
1030
1078
|
this._hasAttached = false;
|
|
1079
|
+
// Event listeners for the anchors. Need to be regular functions so that we can unbind them later.
|
|
1080
|
+
this._startAnchorListener = () => this.focusLastTabbableElement();
|
|
1081
|
+
this._endAnchorListener = () => this.focusFirstTabbableElement();
|
|
1031
1082
|
this._enabled = true;
|
|
1032
1083
|
if (!deferAnchors) {
|
|
1033
1084
|
this.attachAnchors();
|
|
@@ -1054,11 +1105,21 @@ class FocusTrap {
|
|
|
1054
1105
|
* @return {?}
|
|
1055
1106
|
*/
|
|
1056
1107
|
destroy() {
|
|
1057
|
-
|
|
1058
|
-
|
|
1108
|
+
/** @type {?} */
|
|
1109
|
+
const startAnchor = this._startAnchor;
|
|
1110
|
+
/** @type {?} */
|
|
1111
|
+
const endAnchor = this._endAnchor;
|
|
1112
|
+
if (startAnchor) {
|
|
1113
|
+
startAnchor.removeEventListener('focus', this._startAnchorListener);
|
|
1114
|
+
if (startAnchor.parentNode) {
|
|
1115
|
+
startAnchor.parentNode.removeChild(startAnchor);
|
|
1116
|
+
}
|
|
1059
1117
|
}
|
|
1060
|
-
if (
|
|
1061
|
-
|
|
1118
|
+
if (endAnchor) {
|
|
1119
|
+
endAnchor.removeEventListener('focus', this._endAnchorListener);
|
|
1120
|
+
if (endAnchor.parentNode) {
|
|
1121
|
+
endAnchor.parentNode.removeChild(endAnchor);
|
|
1122
|
+
}
|
|
1062
1123
|
}
|
|
1063
1124
|
this._startAnchor = this._endAnchor = null;
|
|
1064
1125
|
}
|
|
@@ -1075,17 +1136,17 @@ class FocusTrap {
|
|
|
1075
1136
|
}
|
|
1076
1137
|
this._ngZone.runOutsideAngular(() => {
|
|
1077
1138
|
if (!this._startAnchor) {
|
|
1078
|
-
this._startAnchor = this._createAnchor();
|
|
1079
|
-
((this._startAnchor)).addEventListener('focus',
|
|
1139
|
+
this._startAnchor = this._createAnchor();
|
|
1140
|
+
(/** @type {?} */ (this._startAnchor)).addEventListener('focus', this._startAnchorListener);
|
|
1080
1141
|
}
|
|
1081
1142
|
if (!this._endAnchor) {
|
|
1082
|
-
this._endAnchor = this._createAnchor();
|
|
1083
|
-
((this._endAnchor)).addEventListener('focus',
|
|
1143
|
+
this._endAnchor = this._createAnchor();
|
|
1144
|
+
(/** @type {?} */ (this._endAnchor)).addEventListener('focus', this._endAnchorListener);
|
|
1084
1145
|
}
|
|
1085
1146
|
});
|
|
1086
1147
|
if (this._element.parentNode) {
|
|
1087
|
-
this._element.parentNode.insertBefore(/** @type {?} */ (
|
|
1088
|
-
this._element.parentNode.insertBefore(/** @type {?} */ (
|
|
1148
|
+
this._element.parentNode.insertBefore((/** @type {?} */ (this._startAnchor)), this._element);
|
|
1149
|
+
this._element.parentNode.insertBefore((/** @type {?} */ (this._endAnchor)), this._element.nextSibling);
|
|
1089
1150
|
this._hasAttached = true;
|
|
1090
1151
|
}
|
|
1091
1152
|
return this._hasAttached;
|
|
@@ -1125,14 +1186,16 @@ class FocusTrap {
|
|
|
1125
1186
|
}
|
|
1126
1187
|
/**
|
|
1127
1188
|
* Get the specified boundary element of the trapped region.
|
|
1189
|
+
* @private
|
|
1128
1190
|
* @param {?} bound The boundary to get (start or end of trapped region).
|
|
1129
1191
|
* @return {?} The boundary element.
|
|
1130
1192
|
*/
|
|
1131
1193
|
_getRegionBoundary(bound) {
|
|
1194
|
+
// Contains the deprecated version of selector, for temporary backwards comparability.
|
|
1132
1195
|
/** @type {?} */
|
|
1133
|
-
let markers = /** @type {?} */ (this._element.querySelectorAll(`[cdk-focus-region-${bound}], ` +
|
|
1196
|
+
let markers = (/** @type {?} */ (this._element.querySelectorAll(`[cdk-focus-region-${bound}], ` +
|
|
1134
1197
|
`[cdkFocusRegion${bound}], ` +
|
|
1135
|
-
`[cdk-focus-${bound}]`));
|
|
1198
|
+
`[cdk-focus-${bound}]`)));
|
|
1136
1199
|
for (let i = 0; i < markers.length; i++) {
|
|
1137
1200
|
// @breaking-change 8.0.0
|
|
1138
1201
|
if (markers[i].hasAttribute(`cdk-focus-${bound}`)) {
|
|
@@ -1157,9 +1220,10 @@ class FocusTrap {
|
|
|
1157
1220
|
* @return {?} Whether focus was moved successfuly.
|
|
1158
1221
|
*/
|
|
1159
1222
|
focusInitialElement() {
|
|
1223
|
+
// Contains the deprecated version of selector, for temporary backwards comparability.
|
|
1160
1224
|
/** @type {?} */
|
|
1161
|
-
const redirectToElement = /** @type {?} */ (this._element.querySelector(`[cdk-focus-initial], ` +
|
|
1162
|
-
`[cdkFocusInitial]`));
|
|
1225
|
+
const redirectToElement = (/** @type {?} */ (this._element.querySelector(`[cdk-focus-initial], ` +
|
|
1226
|
+
`[cdkFocusInitial]`)));
|
|
1163
1227
|
if (redirectToElement) {
|
|
1164
1228
|
// @breaking-change 8.0.0
|
|
1165
1229
|
if (redirectToElement.hasAttribute(`cdk-focus-initial`)) {
|
|
@@ -1210,6 +1274,7 @@ class FocusTrap {
|
|
|
1210
1274
|
}
|
|
1211
1275
|
/**
|
|
1212
1276
|
* Get the first tabbable element from a DOM subtree (inclusive).
|
|
1277
|
+
* @private
|
|
1213
1278
|
* @param {?} root
|
|
1214
1279
|
* @return {?}
|
|
1215
1280
|
*/
|
|
@@ -1217,12 +1282,14 @@ class FocusTrap {
|
|
|
1217
1282
|
if (this._checker.isFocusable(root) && this._checker.isTabbable(root)) {
|
|
1218
1283
|
return root;
|
|
1219
1284
|
}
|
|
1285
|
+
// Iterate in DOM order. Note that IE doesn't have `children` for SVG so we fall
|
|
1286
|
+
// back to `childNodes` which includes text nodes, comments etc.
|
|
1220
1287
|
/** @type {?} */
|
|
1221
1288
|
let children = root.children || root.childNodes;
|
|
1222
1289
|
for (let i = 0; i < children.length; i++) {
|
|
1223
1290
|
/** @type {?} */
|
|
1224
1291
|
let tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE ?
|
|
1225
|
-
this._getFirstTabbableElement(/** @type {?} */ (children[i])) :
|
|
1292
|
+
this._getFirstTabbableElement((/** @type {?} */ (children[i]))) :
|
|
1226
1293
|
null;
|
|
1227
1294
|
if (tabbableChild) {
|
|
1228
1295
|
return tabbableChild;
|
|
@@ -1232,6 +1299,7 @@ class FocusTrap {
|
|
|
1232
1299
|
}
|
|
1233
1300
|
/**
|
|
1234
1301
|
* Get the last tabbable element from a DOM subtree (inclusive).
|
|
1302
|
+
* @private
|
|
1235
1303
|
* @param {?} root
|
|
1236
1304
|
* @return {?}
|
|
1237
1305
|
*/
|
|
@@ -1239,12 +1307,13 @@ class FocusTrap {
|
|
|
1239
1307
|
if (this._checker.isFocusable(root) && this._checker.isTabbable(root)) {
|
|
1240
1308
|
return root;
|
|
1241
1309
|
}
|
|
1310
|
+
// Iterate in reverse DOM order.
|
|
1242
1311
|
/** @type {?} */
|
|
1243
1312
|
let children = root.children || root.childNodes;
|
|
1244
1313
|
for (let i = children.length - 1; i >= 0; i--) {
|
|
1245
1314
|
/** @type {?} */
|
|
1246
1315
|
let tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE ?
|
|
1247
|
-
this._getLastTabbableElement(/** @type {?} */ (children[i])) :
|
|
1316
|
+
this._getLastTabbableElement((/** @type {?} */ (children[i]))) :
|
|
1248
1317
|
null;
|
|
1249
1318
|
if (tabbableChild) {
|
|
1250
1319
|
return tabbableChild;
|
|
@@ -1254,6 +1323,7 @@ class FocusTrap {
|
|
|
1254
1323
|
}
|
|
1255
1324
|
/**
|
|
1256
1325
|
* Creates an anchor element.
|
|
1326
|
+
* @private
|
|
1257
1327
|
* @return {?}
|
|
1258
1328
|
*/
|
|
1259
1329
|
_createAnchor() {
|
|
@@ -1262,10 +1332,12 @@ class FocusTrap {
|
|
|
1262
1332
|
this._toggleAnchorTabIndex(this._enabled, anchor);
|
|
1263
1333
|
anchor.classList.add('cdk-visually-hidden');
|
|
1264
1334
|
anchor.classList.add('cdk-focus-trap-anchor');
|
|
1335
|
+
anchor.setAttribute('aria-hidden', 'true');
|
|
1265
1336
|
return anchor;
|
|
1266
1337
|
}
|
|
1267
1338
|
/**
|
|
1268
1339
|
* Toggles the `tabindex` of an anchor, based on the enabled state of the focus trap.
|
|
1340
|
+
* @private
|
|
1269
1341
|
* @param {?} isEnabled Whether the focus trap is enabled.
|
|
1270
1342
|
* @param {?} anchor Anchor on which to toggle the tabindex.
|
|
1271
1343
|
* @return {?}
|
|
@@ -1277,6 +1349,7 @@ class FocusTrap {
|
|
|
1277
1349
|
}
|
|
1278
1350
|
/**
|
|
1279
1351
|
* Executes a function when the zone is stable.
|
|
1352
|
+
* @private
|
|
1280
1353
|
* @param {?} fn
|
|
1281
1354
|
* @return {?}
|
|
1282
1355
|
*/
|
|
@@ -1382,7 +1455,7 @@ class CdkTrapFocus {
|
|
|
1382
1455
|
ngAfterContentInit() {
|
|
1383
1456
|
this.focusTrap.attachAnchors();
|
|
1384
1457
|
if (this.autoCapture) {
|
|
1385
|
-
this._previouslyFocusedElement = /** @type {?} */ (this._document.activeElement);
|
|
1458
|
+
this._previouslyFocusedElement = (/** @type {?} */ (this._document.activeElement));
|
|
1386
1459
|
this.focusTrap.focusInitialElementWhenReady();
|
|
1387
1460
|
}
|
|
1388
1461
|
}
|
|
@@ -1414,8 +1487,10 @@ CdkTrapFocus.propDecorators = {
|
|
|
1414
1487
|
|
|
1415
1488
|
/**
|
|
1416
1489
|
* @fileoverview added by tsickle
|
|
1417
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
1490
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1418
1491
|
*/
|
|
1492
|
+
// The token for the live announcer element is defined in a separate file from LiveAnnouncer
|
|
1493
|
+
// as a workaround for https://github.com/angular/angular/issues/22559
|
|
1419
1494
|
/** @type {?} */
|
|
1420
1495
|
const LIVE_ANNOUNCER_ELEMENT_TOKEN = new InjectionToken('liveAnnouncerElement', {
|
|
1421
1496
|
providedIn: 'root',
|
|
@@ -1431,7 +1506,7 @@ function LIVE_ANNOUNCER_ELEMENT_TOKEN_FACTORY() {
|
|
|
1431
1506
|
|
|
1432
1507
|
/**
|
|
1433
1508
|
* @fileoverview added by tsickle
|
|
1434
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
1509
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1435
1510
|
*/
|
|
1436
1511
|
class LiveAnnouncer {
|
|
1437
1512
|
/**
|
|
@@ -1466,7 +1541,7 @@ class LiveAnnouncer {
|
|
|
1466
1541
|
this.clear();
|
|
1467
1542
|
clearTimeout(this._previousTimeout);
|
|
1468
1543
|
// TODO: ensure changing the politeness works on all environments we support.
|
|
1469
|
-
this._liveElement.setAttribute('aria-live', /** @type {?} */ (
|
|
1544
|
+
this._liveElement.setAttribute('aria-live', (/** @type {?} */ (politeness)) || 'polite');
|
|
1470
1545
|
// This 100ms timeout is necessary for some browser + screen-reader combinations:
|
|
1471
1546
|
// - Both JAWS and NVDA over IE11 will not announce anything without a non-zero timeout.
|
|
1472
1547
|
// - With Chrome and IE11 with NVDA or JAWS, a repeated (identical) message won't be read a
|
|
@@ -1503,10 +1578,11 @@ class LiveAnnouncer {
|
|
|
1503
1578
|
clearTimeout(this._previousTimeout);
|
|
1504
1579
|
if (this._liveElement && this._liveElement.parentNode) {
|
|
1505
1580
|
this._liveElement.parentNode.removeChild(this._liveElement);
|
|
1506
|
-
this._liveElement = /** @type {?} */ (
|
|
1581
|
+
this._liveElement = (/** @type {?} */ (null));
|
|
1507
1582
|
}
|
|
1508
1583
|
}
|
|
1509
1584
|
/**
|
|
1585
|
+
* @private
|
|
1510
1586
|
* @return {?}
|
|
1511
1587
|
*/
|
|
1512
1588
|
_createLiveElement() {
|
|
@@ -1518,7 +1594,7 @@ class LiveAnnouncer {
|
|
|
1518
1594
|
const liveEl = this._document.createElement('div');
|
|
1519
1595
|
// Remove any old containers. This can happen when coming in from a server-side-rendered page.
|
|
1520
1596
|
for (let i = 0; i < previousElements.length; i++) {
|
|
1521
|
-
/** @type {?} */ (
|
|
1597
|
+
(/** @type {?} */ (previousElements[i].parentNode)).removeChild(previousElements[i]);
|
|
1522
1598
|
}
|
|
1523
1599
|
liveEl.classList.add(elementClass);
|
|
1524
1600
|
liveEl.classList.add('cdk-visually-hidden');
|
|
@@ -1578,6 +1654,7 @@ class CdkAriaLive {
|
|
|
1578
1654
|
return this._contentObserver
|
|
1579
1655
|
.observe(this._elementRef)
|
|
1580
1656
|
.subscribe(() => {
|
|
1657
|
+
// Note that we use textContent here, rather than innerText, in order to avoid a reflow.
|
|
1581
1658
|
/** @type {?} */
|
|
1582
1659
|
const elementText = this._elementRef.nativeElement.textContent;
|
|
1583
1660
|
// The `MutationObserver` fires also for attribute
|
|
@@ -1626,9 +1703,10 @@ CdkAriaLive.propDecorators = {
|
|
|
1626
1703
|
function LIVE_ANNOUNCER_PROVIDER_FACTORY(parentAnnouncer, liveElement, _document, ngZone) {
|
|
1627
1704
|
return parentAnnouncer || new LiveAnnouncer(liveElement, ngZone, _document);
|
|
1628
1705
|
}
|
|
1629
|
-
/**
|
|
1706
|
+
/**
|
|
1630
1707
|
* \@docs-private \@deprecated \@breaking-change 8.0.0
|
|
1631
|
-
|
|
1708
|
+
* @type {?}
|
|
1709
|
+
*/
|
|
1632
1710
|
const LIVE_ANNOUNCER_PROVIDER = {
|
|
1633
1711
|
// If there is already a LiveAnnouncer available, use that. Otherwise, provide a new one.
|
|
1634
1712
|
provide: LiveAnnouncer,
|
|
@@ -1643,10 +1721,21 @@ const LIVE_ANNOUNCER_PROVIDER = {
|
|
|
1643
1721
|
|
|
1644
1722
|
/**
|
|
1645
1723
|
* @fileoverview added by tsickle
|
|
1646
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
1724
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1647
1725
|
*/
|
|
1726
|
+
// This is the value used by AngularJS Material. Through trial and error (on iPhone 6S) they found
|
|
1727
|
+
// that a value of around 650ms seems appropriate.
|
|
1648
1728
|
/** @type {?} */
|
|
1649
1729
|
const TOUCH_BUFFER_MS = 650;
|
|
1730
|
+
/**
|
|
1731
|
+
* Event listener options that enable capturing and also
|
|
1732
|
+
* mark the the listener as passive if the browser supports it.
|
|
1733
|
+
* @type {?}
|
|
1734
|
+
*/
|
|
1735
|
+
const captureEventListenerOptions = normalizePassiveListenerOptions({
|
|
1736
|
+
passive: true,
|
|
1737
|
+
capture: true
|
|
1738
|
+
});
|
|
1650
1739
|
/**
|
|
1651
1740
|
* Monitors mouse and keyboard events to determine the cause of focus events.
|
|
1652
1741
|
*/
|
|
@@ -1670,14 +1759,54 @@ class FocusMonitor {
|
|
|
1670
1759
|
* Map of elements being monitored to their info.
|
|
1671
1760
|
*/
|
|
1672
1761
|
this._elementInfo = new Map();
|
|
1673
|
-
/**
|
|
1674
|
-
* A map of global objects to lists of current listeners.
|
|
1675
|
-
*/
|
|
1676
|
-
this._unregisterGlobalListeners = () => { };
|
|
1677
1762
|
/**
|
|
1678
1763
|
* The number of elements currently being monitored.
|
|
1679
1764
|
*/
|
|
1680
1765
|
this._monitoredElementCount = 0;
|
|
1766
|
+
/**
|
|
1767
|
+
* Event listener for `keydown` events on the document.
|
|
1768
|
+
* Needs to be an arrow function in order to preserve the context when it gets bound.
|
|
1769
|
+
*/
|
|
1770
|
+
this._documentKeydownListener = () => {
|
|
1771
|
+
// On keydown record the origin and clear any touch event that may be in progress.
|
|
1772
|
+
this._lastTouchTarget = null;
|
|
1773
|
+
this._setOriginForCurrentEventQueue('keyboard');
|
|
1774
|
+
};
|
|
1775
|
+
/**
|
|
1776
|
+
* Event listener for `mousedown` events on the document.
|
|
1777
|
+
* Needs to be an arrow function in order to preserve the context when it gets bound.
|
|
1778
|
+
*/
|
|
1779
|
+
this._documentMousedownListener = () => {
|
|
1780
|
+
// On mousedown record the origin only if there is not touch
|
|
1781
|
+
// target, since a mousedown can happen as a result of a touch event.
|
|
1782
|
+
if (!this._lastTouchTarget) {
|
|
1783
|
+
this._setOriginForCurrentEventQueue('mouse');
|
|
1784
|
+
}
|
|
1785
|
+
};
|
|
1786
|
+
/**
|
|
1787
|
+
* Event listener for `touchstart` events on the document.
|
|
1788
|
+
* Needs to be an arrow function in order to preserve the context when it gets bound.
|
|
1789
|
+
*/
|
|
1790
|
+
this._documentTouchstartListener = (event) => {
|
|
1791
|
+
// When the touchstart event fires the focus event is not yet in the event queue. This means
|
|
1792
|
+
// we can't rely on the trick used above (setting timeout of 1ms). Instead we wait 650ms to
|
|
1793
|
+
// see if a focus happens.
|
|
1794
|
+
if (this._touchTimeoutId != null) {
|
|
1795
|
+
clearTimeout(this._touchTimeoutId);
|
|
1796
|
+
}
|
|
1797
|
+
this._lastTouchTarget = event.target;
|
|
1798
|
+
this._touchTimeoutId = setTimeout(() => this._lastTouchTarget = null, TOUCH_BUFFER_MS);
|
|
1799
|
+
};
|
|
1800
|
+
/**
|
|
1801
|
+
* Event listener for `focus` events on the window.
|
|
1802
|
+
* Needs to be an arrow function in order to preserve the context when it gets bound.
|
|
1803
|
+
*/
|
|
1804
|
+
this._windowFocusListener = () => {
|
|
1805
|
+
// Make a note of when the window regains focus, so we can
|
|
1806
|
+
// restore the origin info for the focused element.
|
|
1807
|
+
this._windowFocused = true;
|
|
1808
|
+
this._windowFocusTimeoutId = setTimeout(() => this._windowFocused = false);
|
|
1809
|
+
};
|
|
1681
1810
|
}
|
|
1682
1811
|
/**
|
|
1683
1812
|
* @param {?} element
|
|
@@ -1690,14 +1819,15 @@ class FocusMonitor {
|
|
|
1690
1819
|
return of(null);
|
|
1691
1820
|
}
|
|
1692
1821
|
/** @type {?} */
|
|
1693
|
-
const nativeElement =
|
|
1822
|
+
const nativeElement = coerceElement(element);
|
|
1694
1823
|
// Check if we're already monitoring this element.
|
|
1695
1824
|
if (this._elementInfo.has(nativeElement)) {
|
|
1696
1825
|
/** @type {?} */
|
|
1697
|
-
let cachedInfo = this._elementInfo.get(nativeElement);
|
|
1698
|
-
((cachedInfo)).checkChildren = checkChildren;
|
|
1699
|
-
return /** @type {?} */ (
|
|
1826
|
+
let cachedInfo = this._elementInfo.get(nativeElement);
|
|
1827
|
+
(/** @type {?} */ (cachedInfo)).checkChildren = checkChildren;
|
|
1828
|
+
return (/** @type {?} */ (cachedInfo)).subject.asObservable();
|
|
1700
1829
|
}
|
|
1830
|
+
// Create monitored element info.
|
|
1701
1831
|
/** @type {?} */
|
|
1702
1832
|
let info = {
|
|
1703
1833
|
unlisten: () => { },
|
|
@@ -1706,6 +1836,7 @@ class FocusMonitor {
|
|
|
1706
1836
|
};
|
|
1707
1837
|
this._elementInfo.set(nativeElement, info);
|
|
1708
1838
|
this._incrementMonitoredElementCount();
|
|
1839
|
+
// Start listening. We need to listen in capture phase since focus events don't bubble.
|
|
1709
1840
|
/** @type {?} */
|
|
1710
1841
|
let focusListener = (event) => this._onFocus(event, nativeElement);
|
|
1711
1842
|
/** @type {?} */
|
|
@@ -1727,7 +1858,7 @@ class FocusMonitor {
|
|
|
1727
1858
|
*/
|
|
1728
1859
|
stopMonitoring(element) {
|
|
1729
1860
|
/** @type {?} */
|
|
1730
|
-
const nativeElement =
|
|
1861
|
+
const nativeElement = coerceElement(element);
|
|
1731
1862
|
/** @type {?} */
|
|
1732
1863
|
const elementInfo = this._elementInfo.get(nativeElement);
|
|
1733
1864
|
if (elementInfo) {
|
|
@@ -1746,12 +1877,12 @@ class FocusMonitor {
|
|
|
1746
1877
|
*/
|
|
1747
1878
|
focusVia(element, origin, options) {
|
|
1748
1879
|
/** @type {?} */
|
|
1749
|
-
const nativeElement =
|
|
1880
|
+
const nativeElement = coerceElement(element);
|
|
1750
1881
|
this._setOriginForCurrentEventQueue(origin);
|
|
1751
1882
|
// `focus` isn't available on the server
|
|
1752
1883
|
if (typeof nativeElement.focus === 'function') {
|
|
1753
1884
|
// Cast the element to `any`, because the TS typings don't have the `options` parameter yet.
|
|
1754
|
-
(/** @type {?} */ (nativeElement)).focus(options);
|
|
1885
|
+
((/** @type {?} */ (nativeElement))).focus(options);
|
|
1755
1886
|
}
|
|
1756
1887
|
}
|
|
1757
1888
|
/**
|
|
@@ -1761,63 +1892,7 @@ class FocusMonitor {
|
|
|
1761
1892
|
this._elementInfo.forEach((_info, element) => this.stopMonitoring(element));
|
|
1762
1893
|
}
|
|
1763
1894
|
/**
|
|
1764
|
-
*
|
|
1765
|
-
* @return {?}
|
|
1766
|
-
*/
|
|
1767
|
-
_registerGlobalListeners() {
|
|
1768
|
-
// Do nothing if we're not on the browser platform.
|
|
1769
|
-
if (!this._platform.isBrowser) {
|
|
1770
|
-
return;
|
|
1771
|
-
}
|
|
1772
|
-
/** @type {?} */
|
|
1773
|
-
let documentKeydownListener = () => {
|
|
1774
|
-
this._lastTouchTarget = null;
|
|
1775
|
-
this._setOriginForCurrentEventQueue('keyboard');
|
|
1776
|
-
};
|
|
1777
|
-
/** @type {?} */
|
|
1778
|
-
let documentMousedownListener = () => {
|
|
1779
|
-
if (!this._lastTouchTarget) {
|
|
1780
|
-
this._setOriginForCurrentEventQueue('mouse');
|
|
1781
|
-
}
|
|
1782
|
-
};
|
|
1783
|
-
/** @type {?} */
|
|
1784
|
-
let documentTouchstartListener = (event) => {
|
|
1785
|
-
if (this._touchTimeoutId != null) {
|
|
1786
|
-
clearTimeout(this._touchTimeoutId);
|
|
1787
|
-
}
|
|
1788
|
-
this._lastTouchTarget = event.target;
|
|
1789
|
-
this._touchTimeoutId = setTimeout(() => this._lastTouchTarget = null, TOUCH_BUFFER_MS);
|
|
1790
|
-
};
|
|
1791
|
-
/** @type {?} */
|
|
1792
|
-
let windowFocusListener = () => {
|
|
1793
|
-
this._windowFocused = true;
|
|
1794
|
-
this._windowFocusTimeoutId = setTimeout(() => this._windowFocused = false);
|
|
1795
|
-
};
|
|
1796
|
-
/** @type {?} */
|
|
1797
|
-
const captureEventListenerOptions = normalizePassiveListenerOptions({
|
|
1798
|
-
passive: true,
|
|
1799
|
-
capture: true
|
|
1800
|
-
});
|
|
1801
|
-
// Note: we listen to events in the capture phase so we can detect them even if the user stops
|
|
1802
|
-
// propagation.
|
|
1803
|
-
this._ngZone.runOutsideAngular(() => {
|
|
1804
|
-
document.addEventListener('keydown', documentKeydownListener, captureEventListenerOptions);
|
|
1805
|
-
document.addEventListener('mousedown', documentMousedownListener, captureEventListenerOptions);
|
|
1806
|
-
document.addEventListener('touchstart', documentTouchstartListener, captureEventListenerOptions);
|
|
1807
|
-
window.addEventListener('focus', windowFocusListener);
|
|
1808
|
-
});
|
|
1809
|
-
this._unregisterGlobalListeners = () => {
|
|
1810
|
-
document.removeEventListener('keydown', documentKeydownListener, captureEventListenerOptions);
|
|
1811
|
-
document.removeEventListener('mousedown', documentMousedownListener, captureEventListenerOptions);
|
|
1812
|
-
document.removeEventListener('touchstart', documentTouchstartListener, captureEventListenerOptions);
|
|
1813
|
-
window.removeEventListener('focus', windowFocusListener);
|
|
1814
|
-
// Clear timeouts for all potentially pending timeouts to prevent the leaks.
|
|
1815
|
-
clearTimeout(this._windowFocusTimeoutId);
|
|
1816
|
-
clearTimeout(this._touchTimeoutId);
|
|
1817
|
-
clearTimeout(this._originTimeoutId);
|
|
1818
|
-
};
|
|
1819
|
-
}
|
|
1820
|
-
/**
|
|
1895
|
+
* @private
|
|
1821
1896
|
* @param {?} element
|
|
1822
1897
|
* @param {?} className
|
|
1823
1898
|
* @param {?} shouldSet
|
|
@@ -1833,6 +1908,7 @@ class FocusMonitor {
|
|
|
1833
1908
|
}
|
|
1834
1909
|
/**
|
|
1835
1910
|
* Sets the focus classes on the element based on the given focus origin.
|
|
1911
|
+
* @private
|
|
1836
1912
|
* @param {?} element The element to update the classes on.
|
|
1837
1913
|
* @param {?=} origin The focus origin.
|
|
1838
1914
|
* @return {?}
|
|
@@ -1850,6 +1926,7 @@ class FocusMonitor {
|
|
|
1850
1926
|
}
|
|
1851
1927
|
/**
|
|
1852
1928
|
* Sets the origin and schedules an async function to clear it at the end of the event queue.
|
|
1929
|
+
* @private
|
|
1853
1930
|
* @param {?} origin The origin to set.
|
|
1854
1931
|
* @return {?}
|
|
1855
1932
|
*/
|
|
@@ -1864,10 +1941,28 @@ class FocusMonitor {
|
|
|
1864
1941
|
}
|
|
1865
1942
|
/**
|
|
1866
1943
|
* Checks whether the given focus event was caused by a touchstart event.
|
|
1944
|
+
* @private
|
|
1867
1945
|
* @param {?} event The focus event to check.
|
|
1868
1946
|
* @return {?} Whether the event was caused by a touch.
|
|
1869
1947
|
*/
|
|
1870
1948
|
_wasCausedByTouch(event) {
|
|
1949
|
+
// Note(mmalerba): This implementation is not quite perfect, there is a small edge case.
|
|
1950
|
+
// Consider the following dom structure:
|
|
1951
|
+
//
|
|
1952
|
+
// <div #parent tabindex="0" cdkFocusClasses>
|
|
1953
|
+
// <div #child (click)="#parent.focus()"></div>
|
|
1954
|
+
// </div>
|
|
1955
|
+
//
|
|
1956
|
+
// If the user touches the #child element and the #parent is programmatically focused as a
|
|
1957
|
+
// result, this code will still consider it to have been caused by the touch event and will
|
|
1958
|
+
// apply the cdk-touch-focused class rather than the cdk-program-focused class. This is a
|
|
1959
|
+
// relatively small edge-case that can be worked around by using
|
|
1960
|
+
// focusVia(parentEl, 'program') to focus the parent element.
|
|
1961
|
+
//
|
|
1962
|
+
// If we decide that we absolutely must handle this case correctly, we can do so by listening
|
|
1963
|
+
// for the first focus event after the touchstart, and then the first blur event after that
|
|
1964
|
+
// focus event. When that blur event fires we know that whatever follows is not a result of the
|
|
1965
|
+
// touchstart.
|
|
1871
1966
|
/** @type {?} */
|
|
1872
1967
|
let focusTarget = event.target;
|
|
1873
1968
|
return this._lastTouchTarget instanceof Node && focusTarget instanceof Node &&
|
|
@@ -1875,16 +1970,33 @@ class FocusMonitor {
|
|
|
1875
1970
|
}
|
|
1876
1971
|
/**
|
|
1877
1972
|
* Handles focus events on a registered element.
|
|
1973
|
+
* @private
|
|
1878
1974
|
* @param {?} event The focus event.
|
|
1879
1975
|
* @param {?} element The monitored element.
|
|
1880
1976
|
* @return {?}
|
|
1881
1977
|
*/
|
|
1882
1978
|
_onFocus(event, element) {
|
|
1979
|
+
// NOTE(mmalerba): We currently set the classes based on the focus origin of the most recent
|
|
1980
|
+
// focus event affecting the monitored element. If we want to use the origin of the first event
|
|
1981
|
+
// instead we should check for the cdk-focused class here and return if the element already has
|
|
1982
|
+
// it. (This only matters for elements that have includesChildren = true).
|
|
1983
|
+
// NOTE(mmalerba): We currently set the classes based on the focus origin of the most recent
|
|
1984
|
+
// focus event affecting the monitored element. If we want to use the origin of the first event
|
|
1985
|
+
// instead we should check for the cdk-focused class here and return if the element already has
|
|
1986
|
+
// it. (This only matters for elements that have includesChildren = true).
|
|
1987
|
+
// If we are not counting child-element-focus as focused, make sure that the event target is the
|
|
1988
|
+
// monitored element itself.
|
|
1883
1989
|
/** @type {?} */
|
|
1884
1990
|
const elementInfo = this._elementInfo.get(element);
|
|
1885
1991
|
if (!elementInfo || (!elementInfo.checkChildren && element !== event.target)) {
|
|
1886
1992
|
return;
|
|
1887
1993
|
}
|
|
1994
|
+
// If we couldn't detect a cause for the focus event, it's due to one of three reasons:
|
|
1995
|
+
// 1) The window has just regained focus, in which case we want to restore the focused state of
|
|
1996
|
+
// the element from before the window blurred.
|
|
1997
|
+
// 2) It was caused by a touch event, in which case we mark the origin as 'touch'.
|
|
1998
|
+
// 3) The element was programmatically focused, in which case we should mark the origin as
|
|
1999
|
+
// 'program'.
|
|
1888
2000
|
/** @type {?} */
|
|
1889
2001
|
let origin = this._origin;
|
|
1890
2002
|
if (!origin) {
|
|
@@ -1909,6 +2021,8 @@ class FocusMonitor {
|
|
|
1909
2021
|
* @return {?}
|
|
1910
2022
|
*/
|
|
1911
2023
|
_onBlur(event, element) {
|
|
2024
|
+
// If we are counting child-element-focus as focused, make sure that we aren't just blurring in
|
|
2025
|
+
// order to focus another child of the monitored element.
|
|
1912
2026
|
/** @type {?} */
|
|
1913
2027
|
const elementInfo = this._elementInfo.get(element);
|
|
1914
2028
|
if (!elementInfo || (elementInfo.checkChildren && event.relatedTarget instanceof Node &&
|
|
@@ -1919,6 +2033,7 @@ class FocusMonitor {
|
|
|
1919
2033
|
this._emitOrigin(elementInfo.subject, null);
|
|
1920
2034
|
}
|
|
1921
2035
|
/**
|
|
2036
|
+
* @private
|
|
1922
2037
|
* @param {?} subject
|
|
1923
2038
|
* @param {?} origin
|
|
1924
2039
|
* @return {?}
|
|
@@ -1927,31 +2042,39 @@ class FocusMonitor {
|
|
|
1927
2042
|
this._ngZone.run(() => subject.next(origin));
|
|
1928
2043
|
}
|
|
1929
2044
|
/**
|
|
2045
|
+
* @private
|
|
1930
2046
|
* @return {?}
|
|
1931
2047
|
*/
|
|
1932
2048
|
_incrementMonitoredElementCount() {
|
|
1933
2049
|
// Register global listeners when first element is monitored.
|
|
1934
|
-
if (++this._monitoredElementCount == 1) {
|
|
1935
|
-
|
|
2050
|
+
if (++this._monitoredElementCount == 1 && this._platform.isBrowser) {
|
|
2051
|
+
// Note: we listen to events in the capture phase so we
|
|
2052
|
+
// can detect them even if the user stops propagation.
|
|
2053
|
+
this._ngZone.runOutsideAngular(() => {
|
|
2054
|
+
document.addEventListener('keydown', this._documentKeydownListener, captureEventListenerOptions);
|
|
2055
|
+
document.addEventListener('mousedown', this._documentMousedownListener, captureEventListenerOptions);
|
|
2056
|
+
document.addEventListener('touchstart', this._documentTouchstartListener, captureEventListenerOptions);
|
|
2057
|
+
window.addEventListener('focus', this._windowFocusListener);
|
|
2058
|
+
});
|
|
1936
2059
|
}
|
|
1937
2060
|
}
|
|
1938
2061
|
/**
|
|
2062
|
+
* @private
|
|
1939
2063
|
* @return {?}
|
|
1940
2064
|
*/
|
|
1941
2065
|
_decrementMonitoredElementCount() {
|
|
1942
2066
|
// Unregister global listeners when last element is unmonitored.
|
|
1943
2067
|
if (!--this._monitoredElementCount) {
|
|
1944
|
-
this.
|
|
1945
|
-
this.
|
|
2068
|
+
document.removeEventListener('keydown', this._documentKeydownListener, captureEventListenerOptions);
|
|
2069
|
+
document.removeEventListener('mousedown', this._documentMousedownListener, captureEventListenerOptions);
|
|
2070
|
+
document.removeEventListener('touchstart', this._documentTouchstartListener, captureEventListenerOptions);
|
|
2071
|
+
window.removeEventListener('focus', this._windowFocusListener);
|
|
2072
|
+
// Clear timeouts for all potentially pending timeouts to prevent the leaks.
|
|
2073
|
+
clearTimeout(this._windowFocusTimeoutId);
|
|
2074
|
+
clearTimeout(this._touchTimeoutId);
|
|
2075
|
+
clearTimeout(this._originTimeoutId);
|
|
1946
2076
|
}
|
|
1947
2077
|
}
|
|
1948
|
-
/**
|
|
1949
|
-
* @param {?} element
|
|
1950
|
-
* @return {?}
|
|
1951
|
-
*/
|
|
1952
|
-
_getNativeElement(element) {
|
|
1953
|
-
return element instanceof ElementRef ? element.nativeElement : element;
|
|
1954
|
-
}
|
|
1955
2078
|
}
|
|
1956
2079
|
FocusMonitor.decorators = [
|
|
1957
2080
|
{ type: Injectable, args: [{ providedIn: 'root' },] },
|
|
@@ -2014,9 +2137,10 @@ CdkMonitorFocus.propDecorators = {
|
|
|
2014
2137
|
function FOCUS_MONITOR_PROVIDER_FACTORY(parentDispatcher, ngZone, platform) {
|
|
2015
2138
|
return parentDispatcher || new FocusMonitor(ngZone, platform);
|
|
2016
2139
|
}
|
|
2017
|
-
/**
|
|
2140
|
+
/**
|
|
2018
2141
|
* \@docs-private \@deprecated \@breaking-change 8.0.0
|
|
2019
|
-
|
|
2142
|
+
* @type {?}
|
|
2143
|
+
*/
|
|
2020
2144
|
const FOCUS_MONITOR_PROVIDER = {
|
|
2021
2145
|
// If there is already a FocusMonitor available, use that. Otherwise, provide a new one.
|
|
2022
2146
|
provide: FocusMonitor,
|
|
@@ -2026,7 +2150,7 @@ const FOCUS_MONITOR_PROVIDER = {
|
|
|
2026
2150
|
|
|
2027
2151
|
/**
|
|
2028
2152
|
* @fileoverview added by tsickle
|
|
2029
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
2153
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
2030
2154
|
*/
|
|
2031
2155
|
|
|
2032
2156
|
/**
|
|
@@ -2044,7 +2168,7 @@ function isFakeMousedownFromScreenReader(event) {
|
|
|
2044
2168
|
|
|
2045
2169
|
/**
|
|
2046
2170
|
* @fileoverview added by tsickle
|
|
2047
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
2171
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
2048
2172
|
*/
|
|
2049
2173
|
class A11yModule {
|
|
2050
2174
|
}
|
|
@@ -2058,12 +2182,12 @@ A11yModule.decorators = [
|
|
|
2058
2182
|
|
|
2059
2183
|
/**
|
|
2060
2184
|
* @fileoverview added by tsickle
|
|
2061
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
2185
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
2062
2186
|
*/
|
|
2063
2187
|
|
|
2064
2188
|
/**
|
|
2065
2189
|
* @fileoverview added by tsickle
|
|
2066
|
-
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
|
|
2190
|
+
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
2067
2191
|
*/
|
|
2068
2192
|
|
|
2069
2193
|
export { ARIA_DESCRIBER_PROVIDER_FACTORY, MESSAGES_CONTAINER_ID, CDK_DESCRIBEDBY_ID_PREFIX, CDK_DESCRIBEDBY_HOST_ATTRIBUTE, AriaDescriber, ARIA_DESCRIBER_PROVIDER, ActiveDescendantKeyManager, FocusKeyManager, ListKeyManager, FocusTrap, FocusTrapFactory, CdkTrapFocus, InteractivityChecker, LIVE_ANNOUNCER_PROVIDER_FACTORY, LiveAnnouncer, CdkAriaLive, LIVE_ANNOUNCER_PROVIDER, LIVE_ANNOUNCER_ELEMENT_TOKEN_FACTORY, LIVE_ANNOUNCER_ELEMENT_TOKEN, FOCUS_MONITOR_PROVIDER_FACTORY, TOUCH_BUFFER_MS, FocusMonitor, CdkMonitorFocus, FOCUS_MONITOR_PROVIDER, isFakeMousedownFromScreenReader, A11yModule };
|