@angular/cdk 2.0.0-beta.10 → 2.0.0-beta.11
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/a11y/package.json +2 -2
- package/a11y/typings/aria-describer.d.ts +51 -0
- package/a11y/typings/aria-reference.d.ts +15 -0
- package/a11y/typings/focus-monitor.d.ts +106 -0
- package/a11y/typings/index.metadata.json +1 -1
- package/a11y/typings/public_api.d.ts +5 -3
- package/bidi/package.json +2 -2
- package/bundles/cdk-a11y.umd.js +639 -25
- package/bundles/cdk-a11y.umd.js.map +1 -1
- package/bundles/cdk-a11y.umd.min.js +9 -0
- package/bundles/cdk-a11y.umd.min.js.map +1 -0
- package/bundles/cdk-bidi.umd.min.js +9 -0
- package/bundles/cdk-bidi.umd.min.js.map +1 -0
- package/bundles/cdk-coercion.umd.min.js +9 -0
- package/bundles/cdk-coercion.umd.min.js.map +1 -0
- package/bundles/cdk-collections.umd.min.js +9 -0
- package/bundles/cdk-collections.umd.min.js.map +1 -0
- package/bundles/cdk-keycodes.umd.min.js +9 -0
- package/bundles/cdk-keycodes.umd.min.js.map +1 -0
- package/bundles/cdk-observers.umd.min.js +9 -0
- package/bundles/cdk-observers.umd.min.js.map +1 -0
- package/bundles/cdk-overlay.umd.js +49 -75
- package/bundles/cdk-overlay.umd.js.map +1 -1
- package/bundles/cdk-overlay.umd.min.js +9 -0
- package/bundles/cdk-overlay.umd.min.js.map +1 -0
- package/bundles/cdk-platform.umd.min.js +9 -0
- package/bundles/cdk-platform.umd.min.js.map +1 -0
- package/bundles/cdk-portal.umd.min.js +9 -0
- package/bundles/cdk-portal.umd.min.js.map +1 -0
- package/bundles/cdk-rxjs.umd.js.map +1 -1
- package/bundles/cdk-rxjs.umd.min.js +9 -0
- package/bundles/cdk-rxjs.umd.min.js.map +1 -0
- package/bundles/cdk-scrolling.umd.min.js +9 -0
- package/bundles/cdk-scrolling.umd.min.js.map +1 -0
- package/bundles/cdk-stepper.umd.js +460 -0
- package/bundles/cdk-stepper.umd.js.map +1 -0
- package/bundles/cdk-stepper.umd.min.js +9 -0
- package/bundles/cdk-stepper.umd.min.js.map +1 -0
- package/bundles/cdk-table.umd.js +8 -8
- package/bundles/cdk-table.umd.js.map +1 -1
- package/bundles/cdk-table.umd.min.js +9 -0
- package/bundles/cdk-table.umd.min.js.map +1 -0
- package/bundles/cdk.umd.js +1 -1
- package/bundles/cdk.umd.js.map +1 -1
- package/bundles/cdk.umd.min.js +9 -0
- package/bundles/cdk.umd.min.js.map +1 -0
- package/coercion/package.json +2 -2
- package/collections/package.json +2 -2
- package/collections/typings/selection.d.ts +3 -3
- package/{@angular/cdk → esm2015}/a11y.js +617 -17
- package/esm2015/a11y.js.map +1 -0
- package/{@angular/cdk → esm2015}/bidi.js +0 -0
- package/{@angular/cdk → esm2015}/bidi.js.map +0 -0
- package/{@angular → esm2015}/cdk.js +1 -1
- package/{@angular → esm2015}/cdk.js.map +1 -1
- package/{@angular/cdk → esm2015}/coercion.js +0 -0
- package/{@angular/cdk → esm2015}/coercion.js.map +0 -0
- package/{@angular/cdk → esm2015}/collections.js +0 -0
- package/{@angular/cdk → esm2015}/collections.js.map +0 -0
- package/{@angular/cdk → esm2015}/keycodes.js +0 -0
- package/{@angular/cdk → esm2015}/keycodes.js.map +0 -0
- package/{@angular/cdk → esm2015}/observers.js +0 -0
- package/{@angular/cdk → esm2015}/observers.js.map +0 -0
- package/{@angular/cdk → esm2015}/overlay.js +44 -66
- package/esm2015/overlay.js.map +1 -0
- package/{@angular/cdk → esm2015}/platform.js +0 -0
- package/{@angular/cdk → esm2015}/platform.js.map +0 -0
- package/{@angular/cdk → esm2015}/portal.js +0 -0
- package/{@angular/cdk → esm2015}/portal.js.map +0 -0
- package/{@angular/cdk → esm2015}/rxjs.js +0 -0
- package/esm2015/rxjs.js.map +1 -0
- package/{@angular/cdk → esm2015}/scrolling.js +0 -0
- package/{@angular/cdk → esm2015}/scrolling.js.map +0 -0
- package/esm2015/stepper.js +418 -0
- package/esm2015/stepper.js.map +1 -0
- package/{@angular/cdk → esm2015}/table.js +8 -8
- package/esm2015/table.js.map +1 -0
- package/{@angular/cdk → esm5}/a11y.es5.js +622 -17
- package/esm5/a11y.es5.js.map +1 -0
- package/{@angular/cdk → esm5}/bidi.es5.js +0 -0
- package/{@angular/cdk → esm5}/bidi.es5.js.map +0 -0
- package/{@angular → esm5}/cdk.es5.js +1 -1
- package/{@angular → esm5}/cdk.es5.js.map +1 -1
- package/{@angular/cdk → esm5}/coercion.es5.js +0 -0
- package/{@angular/cdk → esm5}/coercion.es5.js.map +0 -0
- package/{@angular/cdk → esm5}/collections.es5.js +0 -0
- package/{@angular/cdk → esm5}/collections.es5.js.map +0 -0
- package/{@angular/cdk → esm5}/keycodes.es5.js +0 -0
- package/{@angular/cdk → esm5}/keycodes.es5.js.map +0 -0
- package/{@angular/cdk → esm5}/observers.es5.js +0 -0
- package/{@angular/cdk → esm5}/observers.es5.js.map +0 -0
- package/{@angular/cdk → esm5}/overlay.es5.js +46 -71
- package/esm5/overlay.es5.js.map +1 -0
- package/{@angular/cdk → esm5}/platform.es5.js +0 -0
- package/{@angular/cdk → esm5}/platform.es5.js.map +0 -0
- package/{@angular/cdk → esm5}/portal.es5.js +0 -0
- package/{@angular/cdk → esm5}/portal.es5.js.map +0 -0
- package/{@angular/cdk → esm5}/rxjs.es5.js +0 -0
- package/esm5/rxjs.es5.js.map +1 -0
- package/{@angular/cdk → esm5}/scrolling.es5.js +0 -0
- package/{@angular/cdk → esm5}/scrolling.es5.js.map +0 -0
- package/esm5/stepper.es5.js +451 -0
- package/esm5/stepper.es5.js.map +1 -0
- package/{@angular/cdk → esm5}/table.es5.js +8 -8
- package/esm5/table.es5.js.map +1 -0
- package/keycodes/package.json +2 -2
- package/observers/package.json +2 -2
- package/overlay/package.json +2 -2
- package/overlay/typings/index.metadata.json +1 -1
- package/overlay/typings/{overlay-state.d.ts → overlay-config.d.ts} +5 -7
- package/overlay/typings/overlay-container.d.ts +1 -6
- package/overlay/typings/overlay-ref.d.ts +3 -3
- package/overlay/typings/overlay.d.ts +2 -2
- package/overlay/typings/position/connected-position-strategy.d.ts +1 -3
- package/overlay/typings/public_api.d.ts +1 -1
- package/overlay/typings/scroll/reposition-scroll-strategy.d.ts +1 -1
- package/package.json +5 -5
- package/platform/package.json +2 -2
- package/portal/package.json +2 -2
- package/portal/typings/portal-injector.d.ts +19 -0
- package/rxjs/package.json +2 -2
- package/rxjs/typings/rx-chain.d.ts +1 -1
- package/rxjs/typings/rx-operators.d.ts +1 -1
- package/scrolling/package.json +2 -2
- package/stepper/index.d.ts +8 -0
- package/stepper/index.metadata.json +11 -0
- package/stepper/package.json +7 -0
- package/stepper/typings/index.d.ts +4 -0
- package/stepper/typings/index.metadata.json +1 -0
- package/stepper/typings/public_api.d.ts +5 -0
- package/stepper/typings/step-label.d.ts +12 -0
- package/stepper/typings/stepper-button.d.ts +11 -0
- package/stepper/typings/stepper.d.ts +93 -0
- package/stepper.d.ts +8 -0
- package/stepper.metadata.json +11 -0
- package/table/package.json +2 -2
- package/table/typings/index.metadata.json +1 -1
- package/typings/a11y/aria-describer.d.ts +51 -0
- package/typings/a11y/aria-reference.d.ts +15 -0
- package/typings/a11y/focus-monitor.d.ts +106 -0
- package/typings/a11y/index.metadata.json +1 -1
- package/typings/a11y/public_api.d.ts +5 -3
- package/typings/collections/selection.d.ts +3 -3
- package/typings/index.metadata.json +1 -1
- package/typings/overlay/index.metadata.json +1 -1
- package/typings/overlay/{overlay-state.d.ts → overlay-config.d.ts} +5 -7
- package/typings/overlay/overlay-container.d.ts +1 -6
- package/typings/overlay/overlay-ref.d.ts +3 -3
- package/typings/overlay/overlay.d.ts +2 -2
- package/typings/overlay/position/connected-position-strategy.d.ts +1 -3
- package/typings/overlay/public_api.d.ts +1 -1
- package/typings/overlay/scroll/reposition-scroll-strategy.d.ts +1 -1
- package/typings/portal/portal-injector.d.ts +19 -0
- package/typings/rxjs/rx-chain.d.ts +1 -1
- package/typings/rxjs/rx-operators.d.ts +1 -1
- package/typings/stepper/index.d.ts +4 -0
- package/typings/stepper/index.metadata.json +1 -0
- package/typings/stepper/public_api.d.ts +5 -0
- package/typings/stepper/step-label.d.ts +12 -0
- package/typings/stepper/stepper-button.d.ts +11 -0
- package/typings/stepper/stepper.d.ts +93 -0
- package/typings/table/index.metadata.json +1 -1
- package/@angular/cdk/a11y.es5.js.map +0 -1
- package/@angular/cdk/a11y.js.map +0 -1
- package/@angular/cdk/overlay.es5.js.map +0 -1
- package/@angular/cdk/overlay.js.map +0 -1
- package/@angular/cdk/rxjs.es5.js.map +0 -1
- package/@angular/cdk/rxjs.js.map +0 -1
- package/@angular/cdk/table.es5.js.map +0 -1
- package/@angular/cdk/table.js.map +0 -1
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
|
-
import { Directive, ElementRef, Inject, Injectable, InjectionToken, Input, NgModule, NgZone, Optional, SkipSelf } from '@angular/core';
|
|
8
|
+
import { Directive, ElementRef, EventEmitter, Inject, Injectable, InjectionToken, Input, NgModule, NgZone, Optional, Output, Renderer2, SkipSelf } from '@angular/core';
|
|
9
9
|
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
10
10
|
import { Platform, PlatformModule } from '@angular/cdk/platform';
|
|
11
11
|
import { RxChain, debounceTime, doOperator, filter, first, map } from '@angular/cdk/rxjs';
|
|
12
12
|
import { CommonModule } from '@angular/common';
|
|
13
13
|
import { Subject } from 'rxjs/Subject';
|
|
14
|
+
import { of } from 'rxjs/observable/of';
|
|
15
|
+
import { Subscription } from 'rxjs/Subscription';
|
|
14
16
|
import { A, DOWN_ARROW, NINE, TAB, UP_ARROW, Z, ZERO } from '@angular/cdk/keycodes';
|
|
15
17
|
|
|
16
18
|
/**
|
|
@@ -493,7 +495,7 @@ class FocusTrap {
|
|
|
493
495
|
fn();
|
|
494
496
|
}
|
|
495
497
|
else {
|
|
496
|
-
first.call(this._ngZone.onStable).subscribe(fn);
|
|
498
|
+
first.call(this._ngZone.onStable.asObservable()).subscribe(fn);
|
|
497
499
|
}
|
|
498
500
|
}
|
|
499
501
|
}
|
|
@@ -725,17 +727,596 @@ const LIVE_ANNOUNCER_PROVIDER = {
|
|
|
725
727
|
};
|
|
726
728
|
|
|
727
729
|
/**
|
|
728
|
-
*
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
* the
|
|
733
|
-
*
|
|
730
|
+
* IDs are deliminated by an empty space, as per the spec.
|
|
731
|
+
*/
|
|
732
|
+
const ID_DELIMINATOR = ' ';
|
|
733
|
+
/**
|
|
734
|
+
* Adds the given ID to the specified ARIA attribute on an element.
|
|
735
|
+
* Used for attributes such as aria-labelledby, aria-owns, etc.
|
|
736
|
+
* @param {?} el
|
|
737
|
+
* @param {?} attr
|
|
738
|
+
* @param {?} id
|
|
734
739
|
* @return {?}
|
|
735
740
|
*/
|
|
736
|
-
function
|
|
737
|
-
|
|
741
|
+
function addAriaReferencedId(el, attr, id) {
|
|
742
|
+
const /** @type {?} */ ids = getAriaReferenceIds(el, attr);
|
|
743
|
+
if (ids.some(existingId => existingId.trim() == id.trim())) {
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
ids.push(id.trim());
|
|
747
|
+
el.setAttribute(attr, ids.join(ID_DELIMINATOR));
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Removes the given ID from the specified ARIA attribute on an element.
|
|
751
|
+
* Used for attributes such as aria-labelledby, aria-owns, etc.
|
|
752
|
+
* @param {?} el
|
|
753
|
+
* @param {?} attr
|
|
754
|
+
* @param {?} id
|
|
755
|
+
* @return {?}
|
|
756
|
+
*/
|
|
757
|
+
function removeAriaReferencedId(el, attr, id) {
|
|
758
|
+
const /** @type {?} */ ids = getAriaReferenceIds(el, attr);
|
|
759
|
+
const /** @type {?} */ filteredIds = ids.filter(val => val != id.trim());
|
|
760
|
+
el.setAttribute(attr, filteredIds.join(ID_DELIMINATOR));
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Gets the list of IDs referenced by the given ARIA attribute on an element.
|
|
764
|
+
* Used for attributes such as aria-labelledby, aria-owns, etc.
|
|
765
|
+
* @param {?} el
|
|
766
|
+
* @param {?} attr
|
|
767
|
+
* @return {?}
|
|
768
|
+
*/
|
|
769
|
+
function getAriaReferenceIds(el, attr) {
|
|
770
|
+
// Get string array of all individual ids (whitespace deliminated) in the attribute value
|
|
771
|
+
return (el.getAttribute(attr) || '').match(/\S+/g) || [];
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* ID used for the body container where all messages are appended.
|
|
776
|
+
*/
|
|
777
|
+
const MESSAGES_CONTAINER_ID = 'cdk-describedby-message-container';
|
|
778
|
+
/**
|
|
779
|
+
* ID prefix used for each created message element.
|
|
780
|
+
*/
|
|
781
|
+
const CDK_DESCRIBEDBY_ID_PREFIX = 'cdk-describedby-message';
|
|
782
|
+
/**
|
|
783
|
+
* Attribute given to each host element that is described by a message element.
|
|
784
|
+
*/
|
|
785
|
+
const CDK_DESCRIBEDBY_HOST_ATTRIBUTE = 'cdk-describedby-host';
|
|
786
|
+
/**
|
|
787
|
+
* Global incremental identifier for each registered message element.
|
|
788
|
+
*/
|
|
789
|
+
let nextId = 0;
|
|
790
|
+
/**
|
|
791
|
+
* Global map of all registered message elements that have been placed into the document.
|
|
792
|
+
*/
|
|
793
|
+
const messageRegistry = new Map();
|
|
794
|
+
/**
|
|
795
|
+
* Container for all registered messages.
|
|
796
|
+
*/
|
|
797
|
+
let messagesContainer = null;
|
|
798
|
+
/**
|
|
799
|
+
* Utility that creates visually hidden elements with a message content. Useful for elements that
|
|
800
|
+
* want to use aria-describedby to further describe themselves without adding additional visual
|
|
801
|
+
* content.
|
|
802
|
+
* \@docs-private
|
|
803
|
+
*/
|
|
804
|
+
class AriaDescriber {
|
|
805
|
+
/**
|
|
806
|
+
* @param {?} _platform
|
|
807
|
+
*/
|
|
808
|
+
constructor(_platform) {
|
|
809
|
+
this._platform = _platform;
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Adds to the host element an aria-describedby reference to a hidden element that contains
|
|
813
|
+
* the message. If the same message has already been registered, then it will reuse the created
|
|
814
|
+
* message element.
|
|
815
|
+
* @param {?} hostElement
|
|
816
|
+
* @param {?} message
|
|
817
|
+
* @return {?}
|
|
818
|
+
*/
|
|
819
|
+
describe(hostElement, message) {
|
|
820
|
+
if (!this._platform.isBrowser || !message.trim()) {
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
if (!messageRegistry.has(message)) {
|
|
824
|
+
createMessageElement(message);
|
|
825
|
+
}
|
|
826
|
+
if (!isElementDescribedByMessage(hostElement, message)) {
|
|
827
|
+
addMessageReference(hostElement, message);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Removes the host element's aria-describedby reference to the message element.
|
|
832
|
+
* @param {?} hostElement
|
|
833
|
+
* @param {?} message
|
|
834
|
+
* @return {?}
|
|
835
|
+
*/
|
|
836
|
+
removeDescription(hostElement, message) {
|
|
837
|
+
if (!this._platform.isBrowser || !message.trim()) {
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
if (isElementDescribedByMessage(hostElement, message)) {
|
|
841
|
+
removeMessageReference(hostElement, message);
|
|
842
|
+
}
|
|
843
|
+
const /** @type {?} */ registeredMessage = messageRegistry.get(message);
|
|
844
|
+
if (registeredMessage && registeredMessage.referenceCount === 0) {
|
|
845
|
+
deleteMessageElement(message);
|
|
846
|
+
}
|
|
847
|
+
if (messagesContainer && messagesContainer.childNodes.length === 0) {
|
|
848
|
+
deleteMessagesContainer();
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* Unregisters all created message elements and removes the message container.
|
|
853
|
+
* @return {?}
|
|
854
|
+
*/
|
|
855
|
+
ngOnDestroy() {
|
|
856
|
+
if (!this._platform.isBrowser) {
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
const /** @type {?} */ describedElements = document.querySelectorAll(`[${CDK_DESCRIBEDBY_HOST_ATTRIBUTE}]`);
|
|
860
|
+
for (let /** @type {?} */ i = 0; i < describedElements.length; i++) {
|
|
861
|
+
removeCdkDescribedByReferenceIds(describedElements[i]);
|
|
862
|
+
describedElements[i].removeAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE);
|
|
863
|
+
}
|
|
864
|
+
if (messagesContainer) {
|
|
865
|
+
deleteMessagesContainer();
|
|
866
|
+
}
|
|
867
|
+
messageRegistry.clear();
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
AriaDescriber.decorators = [
|
|
871
|
+
{ type: Injectable },
|
|
872
|
+
];
|
|
873
|
+
/**
|
|
874
|
+
* @nocollapse
|
|
875
|
+
*/
|
|
876
|
+
AriaDescriber.ctorParameters = () => [
|
|
877
|
+
{ type: Platform, },
|
|
878
|
+
];
|
|
879
|
+
/**
|
|
880
|
+
* Creates a new element in the visually hidden message container element with the message
|
|
881
|
+
* as its content and adds it to the message registry.
|
|
882
|
+
* @param {?} message
|
|
883
|
+
* @return {?}
|
|
884
|
+
*/
|
|
885
|
+
function createMessageElement(message) {
|
|
886
|
+
const /** @type {?} */ messageElement = document.createElement('div');
|
|
887
|
+
messageElement.setAttribute('id', `${CDK_DESCRIBEDBY_ID_PREFIX}-${nextId++}`);
|
|
888
|
+
messageElement.appendChild(/** @type {?} */ ((document.createTextNode(message))));
|
|
889
|
+
if (!messagesContainer) {
|
|
890
|
+
createMessagesContainer();
|
|
891
|
+
} /** @type {?} */
|
|
892
|
+
((messagesContainer)).appendChild(messageElement);
|
|
893
|
+
messageRegistry.set(message, { messageElement, referenceCount: 0 });
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Deletes the message element from the global messages container.
|
|
897
|
+
* @param {?} message
|
|
898
|
+
* @return {?}
|
|
899
|
+
*/
|
|
900
|
+
function deleteMessageElement(message) {
|
|
901
|
+
const /** @type {?} */ registeredMessage = messageRegistry.get(message);
|
|
902
|
+
const /** @type {?} */ messageElement = registeredMessage && registeredMessage.messageElement;
|
|
903
|
+
if (messagesContainer && messageElement) {
|
|
904
|
+
messagesContainer.removeChild(messageElement);
|
|
905
|
+
}
|
|
906
|
+
messageRegistry.delete(message);
|
|
907
|
+
}
|
|
908
|
+
/**
|
|
909
|
+
* Creates the global container for all aria-describedby messages.
|
|
910
|
+
* @return {?}
|
|
911
|
+
*/
|
|
912
|
+
function createMessagesContainer() {
|
|
913
|
+
messagesContainer = document.createElement('div');
|
|
914
|
+
messagesContainer.setAttribute('id', MESSAGES_CONTAINER_ID);
|
|
915
|
+
messagesContainer.setAttribute('aria-hidden', 'true');
|
|
916
|
+
messagesContainer.style.display = 'none';
|
|
917
|
+
document.body.appendChild(messagesContainer);
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* Deletes the global messages container.
|
|
921
|
+
* @return {?}
|
|
922
|
+
*/
|
|
923
|
+
function deleteMessagesContainer() {
|
|
924
|
+
document.body.removeChild(/** @type {?} */ ((messagesContainer)));
|
|
925
|
+
messagesContainer = null;
|
|
926
|
+
}
|
|
927
|
+
/**
|
|
928
|
+
* Removes all cdk-describedby messages that are hosted through the element.
|
|
929
|
+
* @param {?} element
|
|
930
|
+
* @return {?}
|
|
931
|
+
*/
|
|
932
|
+
function removeCdkDescribedByReferenceIds(element) {
|
|
933
|
+
// Remove all aria-describedby reference IDs that are prefixed by CDK_DESCRIBEDBY_ID_PREFIX
|
|
934
|
+
const /** @type {?} */ originalReferenceIds = getAriaReferenceIds(element, 'aria-describedby')
|
|
935
|
+
.filter(id => id.indexOf(CDK_DESCRIBEDBY_ID_PREFIX) != 0);
|
|
936
|
+
element.setAttribute('aria-describedby', originalReferenceIds.join(' '));
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* Adds a message reference to the element using aria-describedby and increments the registered
|
|
940
|
+
* message's reference count.
|
|
941
|
+
* @param {?} element
|
|
942
|
+
* @param {?} message
|
|
943
|
+
* @return {?}
|
|
944
|
+
*/
|
|
945
|
+
function addMessageReference(element, message) {
|
|
946
|
+
const /** @type {?} */ registeredMessage = ((messageRegistry.get(message)));
|
|
947
|
+
// Add the aria-describedby reference and set the describedby_host attribute to mark the element.
|
|
948
|
+
addAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id);
|
|
949
|
+
element.setAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE, '');
|
|
950
|
+
registeredMessage.referenceCount++;
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* Removes a message reference from the element using aria-describedby and decrements the registered
|
|
954
|
+
* message's reference count.
|
|
955
|
+
* @param {?} element
|
|
956
|
+
* @param {?} message
|
|
957
|
+
* @return {?}
|
|
958
|
+
*/
|
|
959
|
+
function removeMessageReference(element, message) {
|
|
960
|
+
const /** @type {?} */ registeredMessage = ((messageRegistry.get(message)));
|
|
961
|
+
registeredMessage.referenceCount--;
|
|
962
|
+
removeAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id);
|
|
963
|
+
element.removeAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE);
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Returns true if the element has been described by the provided message ID.
|
|
967
|
+
* @param {?} element
|
|
968
|
+
* @param {?} message
|
|
969
|
+
* @return {?}
|
|
970
|
+
*/
|
|
971
|
+
function isElementDescribedByMessage(element, message) {
|
|
972
|
+
const /** @type {?} */ referenceIds = getAriaReferenceIds(element, 'aria-describedby');
|
|
973
|
+
const /** @type {?} */ registeredMessage = messageRegistry.get(message);
|
|
974
|
+
const /** @type {?} */ messageId = registeredMessage && registeredMessage.messageElement.id;
|
|
975
|
+
return !!messageId && referenceIds.indexOf(messageId) != -1;
|
|
976
|
+
}
|
|
977
|
+
/**
|
|
978
|
+
* \@docs-private
|
|
979
|
+
* @param {?} parentDispatcher
|
|
980
|
+
* @param {?} platform
|
|
981
|
+
* @return {?}
|
|
982
|
+
*/
|
|
983
|
+
function ARIA_DESCRIBER_PROVIDER_FACTORY(parentDispatcher, platform) {
|
|
984
|
+
return parentDispatcher || new AriaDescriber(platform);
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* \@docs-private
|
|
988
|
+
*/
|
|
989
|
+
const ARIA_DESCRIBER_PROVIDER = {
|
|
990
|
+
// If there is already an AriaDescriber available, use that. Otherwise, provide a new one.
|
|
991
|
+
provide: AriaDescriber,
|
|
992
|
+
deps: [
|
|
993
|
+
[new Optional(), new SkipSelf(), AriaDescriber],
|
|
994
|
+
Platform
|
|
995
|
+
],
|
|
996
|
+
useFactory: ARIA_DESCRIBER_PROVIDER_FACTORY
|
|
997
|
+
};
|
|
998
|
+
|
|
999
|
+
// This is the value used by AngularJS Material. Through trial and error (on iPhone 6S) they found
|
|
1000
|
+
// that a value of around 650ms seems appropriate.
|
|
1001
|
+
const TOUCH_BUFFER_MS = 650;
|
|
1002
|
+
/**
|
|
1003
|
+
* Monitors mouse and keyboard events to determine the cause of focus events.
|
|
1004
|
+
*/
|
|
1005
|
+
class FocusMonitor {
|
|
1006
|
+
/**
|
|
1007
|
+
* @param {?} _ngZone
|
|
1008
|
+
* @param {?} _platform
|
|
1009
|
+
*/
|
|
1010
|
+
constructor(_ngZone, _platform) {
|
|
1011
|
+
this._ngZone = _ngZone;
|
|
1012
|
+
this._platform = _platform;
|
|
1013
|
+
/**
|
|
1014
|
+
* The focus origin that the next focus event is a result of.
|
|
1015
|
+
*/
|
|
1016
|
+
this._origin = null;
|
|
1017
|
+
/**
|
|
1018
|
+
* Whether the window has just been focused.
|
|
1019
|
+
*/
|
|
1020
|
+
this._windowFocused = false;
|
|
1021
|
+
/**
|
|
1022
|
+
* Weak map of elements being monitored to their info.
|
|
1023
|
+
*/
|
|
1024
|
+
this._elementInfo = new WeakMap();
|
|
1025
|
+
this._ngZone.runOutsideAngular(() => this._registerDocumentEvents());
|
|
1026
|
+
}
|
|
1027
|
+
/**
|
|
1028
|
+
* Monitors focus on an element and applies appropriate CSS classes.
|
|
1029
|
+
* @param {?} element The element to monitor
|
|
1030
|
+
* @param {?} renderer The renderer to use to apply CSS classes to the element.
|
|
1031
|
+
* @param {?} checkChildren Whether to count the element as focused when its children are focused.
|
|
1032
|
+
* @return {?} An observable that emits when the focus state of the element changes.
|
|
1033
|
+
* When the element is blurred, null will be emitted.
|
|
1034
|
+
*/
|
|
1035
|
+
monitor(element, renderer, checkChildren) {
|
|
1036
|
+
// Do nothing if we're not on the browser platform.
|
|
1037
|
+
if (!this._platform.isBrowser) {
|
|
1038
|
+
return of(null);
|
|
1039
|
+
}
|
|
1040
|
+
// Check if we're already monitoring this element.
|
|
1041
|
+
if (this._elementInfo.has(element)) {
|
|
1042
|
+
let /** @type {?} */ cachedInfo = this._elementInfo.get(element); /** @type {?} */
|
|
1043
|
+
((cachedInfo)).checkChildren = checkChildren;
|
|
1044
|
+
return ((cachedInfo)).subject.asObservable();
|
|
1045
|
+
}
|
|
1046
|
+
// Create monitored element info.
|
|
1047
|
+
let /** @type {?} */ info = {
|
|
1048
|
+
unlisten: () => { },
|
|
1049
|
+
checkChildren: checkChildren,
|
|
1050
|
+
renderer: renderer,
|
|
1051
|
+
subject: new Subject()
|
|
1052
|
+
};
|
|
1053
|
+
this._elementInfo.set(element, info);
|
|
1054
|
+
// Start listening. We need to listen in capture phase since focus events don't bubble.
|
|
1055
|
+
let /** @type {?} */ focusListener = (event) => this._onFocus(event, element);
|
|
1056
|
+
let /** @type {?} */ blurListener = (event) => this._onBlur(event, element);
|
|
1057
|
+
this._ngZone.runOutsideAngular(() => {
|
|
1058
|
+
element.addEventListener('focus', focusListener, true);
|
|
1059
|
+
element.addEventListener('blur', blurListener, true);
|
|
1060
|
+
});
|
|
1061
|
+
// Create an unlisten function for later.
|
|
1062
|
+
info.unlisten = () => {
|
|
1063
|
+
element.removeEventListener('focus', focusListener, true);
|
|
1064
|
+
element.removeEventListener('blur', blurListener, true);
|
|
1065
|
+
};
|
|
1066
|
+
return info.subject.asObservable();
|
|
1067
|
+
}
|
|
1068
|
+
/**
|
|
1069
|
+
* Stops monitoring an element and removes all focus classes.
|
|
1070
|
+
* @param {?} element The element to stop monitoring.
|
|
1071
|
+
* @return {?}
|
|
1072
|
+
*/
|
|
1073
|
+
stopMonitoring(element) {
|
|
1074
|
+
let /** @type {?} */ elementInfo = this._elementInfo.get(element);
|
|
1075
|
+
if (elementInfo) {
|
|
1076
|
+
elementInfo.unlisten();
|
|
1077
|
+
elementInfo.subject.complete();
|
|
1078
|
+
this._setClasses(element);
|
|
1079
|
+
this._elementInfo.delete(element);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
/**
|
|
1083
|
+
* Focuses the element via the specified focus origin.
|
|
1084
|
+
* @param {?} element The element to focus.
|
|
1085
|
+
* @param {?} origin The focus origin.
|
|
1086
|
+
* @return {?}
|
|
1087
|
+
*/
|
|
1088
|
+
focusVia(element, origin) {
|
|
1089
|
+
this._setOriginForCurrentEventQueue(origin);
|
|
1090
|
+
element.focus();
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Register necessary event listeners on the document and window.
|
|
1094
|
+
* @return {?}
|
|
1095
|
+
*/
|
|
1096
|
+
_registerDocumentEvents() {
|
|
1097
|
+
// Do nothing if we're not on the browser platform.
|
|
1098
|
+
if (!this._platform.isBrowser) {
|
|
1099
|
+
return;
|
|
1100
|
+
}
|
|
1101
|
+
// Note: we listen to events in the capture phase so we can detect them even if the user stops
|
|
1102
|
+
// propagation.
|
|
1103
|
+
// On keydown record the origin and clear any touch event that may be in progress.
|
|
1104
|
+
document.addEventListener('keydown', () => {
|
|
1105
|
+
this._lastTouchTarget = null;
|
|
1106
|
+
this._setOriginForCurrentEventQueue('keyboard');
|
|
1107
|
+
}, true);
|
|
1108
|
+
// On mousedown record the origin only if there is not touch target, since a mousedown can
|
|
1109
|
+
// happen as a result of a touch event.
|
|
1110
|
+
document.addEventListener('mousedown', () => {
|
|
1111
|
+
if (!this._lastTouchTarget) {
|
|
1112
|
+
this._setOriginForCurrentEventQueue('mouse');
|
|
1113
|
+
}
|
|
1114
|
+
}, true);
|
|
1115
|
+
// When the touchstart event fires the focus event is not yet in the event queue. This means
|
|
1116
|
+
// we can't rely on the trick used above (setting timeout of 0ms). Instead we wait 650ms to
|
|
1117
|
+
// see if a focus happens.
|
|
1118
|
+
document.addEventListener('touchstart', (event) => {
|
|
1119
|
+
if (this._touchTimeout != null) {
|
|
1120
|
+
clearTimeout(this._touchTimeout);
|
|
1121
|
+
}
|
|
1122
|
+
this._lastTouchTarget = event.target;
|
|
1123
|
+
this._touchTimeout = setTimeout(() => this._lastTouchTarget = null, TOUCH_BUFFER_MS);
|
|
1124
|
+
}, true);
|
|
1125
|
+
// Make a note of when the window regains focus, so we can restore the origin info for the
|
|
1126
|
+
// focused element.
|
|
1127
|
+
window.addEventListener('focus', () => {
|
|
1128
|
+
this._windowFocused = true;
|
|
1129
|
+
setTimeout(() => this._windowFocused = false, 0);
|
|
1130
|
+
});
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Sets the focus classes on the element based on the given focus origin.
|
|
1134
|
+
* @param {?} element The element to update the classes on.
|
|
1135
|
+
* @param {?=} origin The focus origin.
|
|
1136
|
+
* @return {?}
|
|
1137
|
+
*/
|
|
1138
|
+
_setClasses(element, origin) {
|
|
1139
|
+
const /** @type {?} */ elementInfo = this._elementInfo.get(element);
|
|
1140
|
+
if (elementInfo) {
|
|
1141
|
+
const /** @type {?} */ toggleClass = (className, shouldSet) => {
|
|
1142
|
+
shouldSet ? elementInfo.renderer.addClass(element, className) :
|
|
1143
|
+
elementInfo.renderer.removeClass(element, className);
|
|
1144
|
+
};
|
|
1145
|
+
toggleClass('cdk-focused', !!origin);
|
|
1146
|
+
toggleClass('cdk-touch-focused', origin === 'touch');
|
|
1147
|
+
toggleClass('cdk-keyboard-focused', origin === 'keyboard');
|
|
1148
|
+
toggleClass('cdk-mouse-focused', origin === 'mouse');
|
|
1149
|
+
toggleClass('cdk-program-focused', origin === 'program');
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Sets the origin and schedules an async function to clear it at the end of the event queue.
|
|
1154
|
+
* @param {?} origin The origin to set.
|
|
1155
|
+
* @return {?}
|
|
1156
|
+
*/
|
|
1157
|
+
_setOriginForCurrentEventQueue(origin) {
|
|
1158
|
+
this._origin = origin;
|
|
1159
|
+
setTimeout(() => this._origin = null, 0);
|
|
1160
|
+
}
|
|
1161
|
+
/**
|
|
1162
|
+
* Checks whether the given focus event was caused by a touchstart event.
|
|
1163
|
+
* @param {?} event The focus event to check.
|
|
1164
|
+
* @return {?} Whether the event was caused by a touch.
|
|
1165
|
+
*/
|
|
1166
|
+
_wasCausedByTouch(event) {
|
|
1167
|
+
// Note(mmalerba): This implementation is not quite perfect, there is a small edge case.
|
|
1168
|
+
// Consider the following dom structure:
|
|
1169
|
+
//
|
|
1170
|
+
// <div #parent tabindex="0" cdkFocusClasses>
|
|
1171
|
+
// <div #child (click)="#parent.focus()"></div>
|
|
1172
|
+
// </div>
|
|
1173
|
+
//
|
|
1174
|
+
// If the user touches the #child element and the #parent is programmatically focused as a
|
|
1175
|
+
// result, this code will still consider it to have been caused by the touch event and will
|
|
1176
|
+
// apply the cdk-touch-focused class rather than the cdk-program-focused class. This is a
|
|
1177
|
+
// relatively small edge-case that can be worked around by using
|
|
1178
|
+
// focusVia(parentEl, renderer, 'program') to focus the parent element.
|
|
1179
|
+
//
|
|
1180
|
+
// If we decide that we absolutely must handle this case correctly, we can do so by listening
|
|
1181
|
+
// for the first focus event after the touchstart, and then the first blur event after that
|
|
1182
|
+
// focus event. When that blur event fires we know that whatever follows is not a result of the
|
|
1183
|
+
// touchstart.
|
|
1184
|
+
let /** @type {?} */ focusTarget = event.target;
|
|
1185
|
+
return this._lastTouchTarget instanceof Node && focusTarget instanceof Node &&
|
|
1186
|
+
(focusTarget === this._lastTouchTarget || focusTarget.contains(this._lastTouchTarget));
|
|
1187
|
+
}
|
|
1188
|
+
/**
|
|
1189
|
+
* Handles focus events on a registered element.
|
|
1190
|
+
* @param {?} event The focus event.
|
|
1191
|
+
* @param {?} element The monitored element.
|
|
1192
|
+
* @return {?}
|
|
1193
|
+
*/
|
|
1194
|
+
_onFocus(event, element) {
|
|
1195
|
+
// NOTE(mmalerba): We currently set the classes based on the focus origin of the most recent
|
|
1196
|
+
// focus event affecting the monitored element. If we want to use the origin of the first event
|
|
1197
|
+
// instead we should check for the cdk-focused class here and return if the element already has
|
|
1198
|
+
// it. (This only matters for elements that have includesChildren = true).
|
|
1199
|
+
// If we are not counting child-element-focus as focused, make sure that the event target is the
|
|
1200
|
+
// monitored element itself.
|
|
1201
|
+
const /** @type {?} */ elementInfo = this._elementInfo.get(element);
|
|
1202
|
+
if (!elementInfo || (!elementInfo.checkChildren && element !== event.target)) {
|
|
1203
|
+
return;
|
|
1204
|
+
}
|
|
1205
|
+
// If we couldn't detect a cause for the focus event, it's due to one of three reasons:
|
|
1206
|
+
// 1) The window has just regained focus, in which case we want to restore the focused state of
|
|
1207
|
+
// the element from before the window blurred.
|
|
1208
|
+
// 2) It was caused by a touch event, in which case we mark the origin as 'touch'.
|
|
1209
|
+
// 3) The element was programmatically focused, in which case we should mark the origin as
|
|
1210
|
+
// 'program'.
|
|
1211
|
+
if (!this._origin) {
|
|
1212
|
+
if (this._windowFocused && this._lastFocusOrigin) {
|
|
1213
|
+
this._origin = this._lastFocusOrigin;
|
|
1214
|
+
}
|
|
1215
|
+
else if (this._wasCausedByTouch(event)) {
|
|
1216
|
+
this._origin = 'touch';
|
|
1217
|
+
}
|
|
1218
|
+
else {
|
|
1219
|
+
this._origin = 'program';
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
this._setClasses(element, this._origin);
|
|
1223
|
+
elementInfo.subject.next(this._origin);
|
|
1224
|
+
this._lastFocusOrigin = this._origin;
|
|
1225
|
+
this._origin = null;
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Handles blur events on a registered element.
|
|
1229
|
+
* @param {?} event The blur event.
|
|
1230
|
+
* @param {?} element The monitored element.
|
|
1231
|
+
* @return {?}
|
|
1232
|
+
*/
|
|
1233
|
+
_onBlur(event, element) {
|
|
1234
|
+
// If we are counting child-element-focus as focused, make sure that we aren't just blurring in
|
|
1235
|
+
// order to focus another child of the monitored element.
|
|
1236
|
+
const /** @type {?} */ elementInfo = this._elementInfo.get(element);
|
|
1237
|
+
if (!elementInfo || (elementInfo.checkChildren && event.relatedTarget instanceof Node &&
|
|
1238
|
+
element.contains(event.relatedTarget))) {
|
|
1239
|
+
return;
|
|
1240
|
+
}
|
|
1241
|
+
this._setClasses(element);
|
|
1242
|
+
elementInfo.subject.next(null);
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
FocusMonitor.decorators = [
|
|
1246
|
+
{ type: Injectable },
|
|
1247
|
+
];
|
|
1248
|
+
/**
|
|
1249
|
+
* @nocollapse
|
|
1250
|
+
*/
|
|
1251
|
+
FocusMonitor.ctorParameters = () => [
|
|
1252
|
+
{ type: NgZone, },
|
|
1253
|
+
{ type: Platform, },
|
|
1254
|
+
];
|
|
1255
|
+
/**
|
|
1256
|
+
* Directive that determines how a particular element was focused (via keyboard, mouse, touch, or
|
|
1257
|
+
* programmatically) and adds corresponding classes to the element.
|
|
1258
|
+
*
|
|
1259
|
+
* There are two variants of this directive:
|
|
1260
|
+
* 1) cdkMonitorElementFocus: does not consider an element to be focused if one of its children is
|
|
1261
|
+
* focused.
|
|
1262
|
+
* 2) cdkMonitorSubtreeFocus: considers an element focused if it or any of its children are focused.
|
|
1263
|
+
*/
|
|
1264
|
+
class CdkMonitorFocus {
|
|
1265
|
+
/**
|
|
1266
|
+
* @param {?} _elementRef
|
|
1267
|
+
* @param {?} _focusMonitor
|
|
1268
|
+
* @param {?} renderer
|
|
1269
|
+
*/
|
|
1270
|
+
constructor(_elementRef, _focusMonitor, renderer) {
|
|
1271
|
+
this._elementRef = _elementRef;
|
|
1272
|
+
this._focusMonitor = _focusMonitor;
|
|
1273
|
+
this.cdkFocusChange = new EventEmitter();
|
|
1274
|
+
this._monitorSubscription = this._focusMonitor.monitor(this._elementRef.nativeElement, renderer, this._elementRef.nativeElement.hasAttribute('cdkMonitorSubtreeFocus'))
|
|
1275
|
+
.subscribe(origin => this.cdkFocusChange.emit(origin));
|
|
1276
|
+
}
|
|
1277
|
+
/**
|
|
1278
|
+
* @return {?}
|
|
1279
|
+
*/
|
|
1280
|
+
ngOnDestroy() {
|
|
1281
|
+
this._focusMonitor.stopMonitoring(this._elementRef.nativeElement);
|
|
1282
|
+
this._monitorSubscription.unsubscribe();
|
|
1283
|
+
}
|
|
738
1284
|
}
|
|
1285
|
+
CdkMonitorFocus.decorators = [
|
|
1286
|
+
{ type: Directive, args: [{
|
|
1287
|
+
selector: '[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]',
|
|
1288
|
+
},] },
|
|
1289
|
+
];
|
|
1290
|
+
/**
|
|
1291
|
+
* @nocollapse
|
|
1292
|
+
*/
|
|
1293
|
+
CdkMonitorFocus.ctorParameters = () => [
|
|
1294
|
+
{ type: ElementRef, },
|
|
1295
|
+
{ type: FocusMonitor, },
|
|
1296
|
+
{ type: Renderer2, },
|
|
1297
|
+
];
|
|
1298
|
+
CdkMonitorFocus.propDecorators = {
|
|
1299
|
+
'cdkFocusChange': [{ type: Output },],
|
|
1300
|
+
};
|
|
1301
|
+
/**
|
|
1302
|
+
* \@docs-private
|
|
1303
|
+
* @param {?} parentDispatcher
|
|
1304
|
+
* @param {?} ngZone
|
|
1305
|
+
* @param {?} platform
|
|
1306
|
+
* @return {?}
|
|
1307
|
+
*/
|
|
1308
|
+
function FOCUS_MONITOR_PROVIDER_FACTORY(parentDispatcher, ngZone, platform) {
|
|
1309
|
+
return parentDispatcher || new FocusMonitor(ngZone, platform);
|
|
1310
|
+
}
|
|
1311
|
+
/**
|
|
1312
|
+
* \@docs-private
|
|
1313
|
+
*/
|
|
1314
|
+
const FOCUS_MONITOR_PROVIDER = {
|
|
1315
|
+
// If there is already a FocusMonitor available, use that. Otherwise, provide a new one.
|
|
1316
|
+
provide: FocusMonitor,
|
|
1317
|
+
deps: [[new Optional(), new SkipSelf(), FocusMonitor], NgZone, Platform],
|
|
1318
|
+
useFactory: FOCUS_MONITOR_PROVIDER_FACTORY
|
|
1319
|
+
};
|
|
739
1320
|
|
|
740
1321
|
/**
|
|
741
1322
|
* This class manages keyboard events for selectable lists. If you pass it a query list
|
|
@@ -750,6 +1331,7 @@ class ListKeyManager {
|
|
|
750
1331
|
this._activeItemIndex = -1;
|
|
751
1332
|
this._wrap = false;
|
|
752
1333
|
this._letterKeyStream = new Subject();
|
|
1334
|
+
this._typeaheadSubscription = Subscription.EMPTY;
|
|
753
1335
|
this._pressedLetters = [];
|
|
754
1336
|
/**
|
|
755
1337
|
* Stream that emits any time the TAB key is pressed, so components can react
|
|
@@ -775,9 +1357,7 @@ class ListKeyManager {
|
|
|
775
1357
|
if (this._items.length && this._items.some(item => typeof item.getLabel !== 'function')) {
|
|
776
1358
|
throw Error('ListKeyManager items in typeahead mode must implement the `getLabel` method.');
|
|
777
1359
|
}
|
|
778
|
-
|
|
779
|
-
this._typeaheadSubscription.unsubscribe();
|
|
780
|
-
}
|
|
1360
|
+
this._typeaheadSubscription.unsubscribe();
|
|
781
1361
|
// Debounce the presses of non-navigational keys, collect the ones that correspond to letters
|
|
782
1362
|
// and convert those letters back into a string. Afterwards find the first item that starts
|
|
783
1363
|
// with that string and select it.
|
|
@@ -978,6 +1558,19 @@ class ActiveDescendantKeyManager extends ListKeyManager {
|
|
|
978
1558
|
}
|
|
979
1559
|
}
|
|
980
1560
|
|
|
1561
|
+
/**
|
|
1562
|
+
* Screenreaders will often fire fake mousedown events when a focusable element
|
|
1563
|
+
* is activated using the keyboard. We can typically distinguish between these faked
|
|
1564
|
+
* mousedown events and real mousedown events using the "buttons" property. While
|
|
1565
|
+
* real mousedowns will indicate the mouse button that was pressed (e.g. "1" for
|
|
1566
|
+
* the left mouse button), faked mousedowns will usually set the property value to 0.
|
|
1567
|
+
* @param {?} event
|
|
1568
|
+
* @return {?}
|
|
1569
|
+
*/
|
|
1570
|
+
function isFakeMousedownFromScreenReader(event) {
|
|
1571
|
+
return event.buttons === 0;
|
|
1572
|
+
}
|
|
1573
|
+
|
|
981
1574
|
class FocusKeyManager extends ListKeyManager {
|
|
982
1575
|
/**
|
|
983
1576
|
* This method sets the active item to the item at the specified index.
|
|
@@ -998,9 +1591,16 @@ class A11yModule {
|
|
|
998
1591
|
A11yModule.decorators = [
|
|
999
1592
|
{ type: NgModule, args: [{
|
|
1000
1593
|
imports: [CommonModule, PlatformModule],
|
|
1001
|
-
declarations: [FocusTrapDirective, FocusTrapDeprecatedDirective],
|
|
1002
|
-
exports: [FocusTrapDirective, FocusTrapDeprecatedDirective],
|
|
1003
|
-
providers: [
|
|
1594
|
+
declarations: [FocusTrapDirective, FocusTrapDeprecatedDirective, CdkMonitorFocus],
|
|
1595
|
+
exports: [FocusTrapDirective, FocusTrapDeprecatedDirective, CdkMonitorFocus],
|
|
1596
|
+
providers: [
|
|
1597
|
+
InteractivityChecker,
|
|
1598
|
+
FocusTrapFactory,
|
|
1599
|
+
AriaDescriber,
|
|
1600
|
+
LIVE_ANNOUNCER_PROVIDER,
|
|
1601
|
+
ARIA_DESCRIBER_PROVIDER,
|
|
1602
|
+
FOCUS_MONITOR_PROVIDER,
|
|
1603
|
+
]
|
|
1004
1604
|
},] },
|
|
1005
1605
|
];
|
|
1006
1606
|
/**
|
|
@@ -1012,5 +1612,5 @@ A11yModule.ctorParameters = () => [];
|
|
|
1012
1612
|
* Generated bundle index. Do not edit.
|
|
1013
1613
|
*/
|
|
1014
1614
|
|
|
1015
|
-
export { A11yModule,
|
|
1615
|
+
export { A11yModule, ActiveDescendantKeyManager, MESSAGES_CONTAINER_ID, CDK_DESCRIBEDBY_ID_PREFIX, CDK_DESCRIBEDBY_HOST_ATTRIBUTE, AriaDescriber, ARIA_DESCRIBER_PROVIDER_FACTORY, ARIA_DESCRIBER_PROVIDER, isFakeMousedownFromScreenReader, FocusKeyManager, FocusTrap, FocusTrapFactory, FocusTrapDeprecatedDirective, FocusTrapDirective, InteractivityChecker, ListKeyManager, LIVE_ANNOUNCER_ELEMENT_TOKEN, LiveAnnouncer, LIVE_ANNOUNCER_PROVIDER_FACTORY, LIVE_ANNOUNCER_PROVIDER, TOUCH_BUFFER_MS, FocusMonitor, CdkMonitorFocus, FOCUS_MONITOR_PROVIDER_FACTORY, FOCUS_MONITOR_PROVIDER };
|
|
1016
1616
|
//# sourceMappingURL=a11y.js.map
|