@angular/cdk 7.0.4 → 7.2.1

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.
Files changed (271) hide show
  1. package/LICENSE +1 -1
  2. package/_a11y.scss +1 -1
  3. package/a11y/typings/focus-monitor/focus-monitor.d.ts +20 -5
  4. package/a11y/typings/focus-trap/focus-trap.d.ts +2 -0
  5. package/a11y/typings/index.metadata.json +1 -1
  6. package/a11y/typings/live-announcer/live-announcer.d.ts +34 -3
  7. package/bundles/cdk-a11y.umd.js +477 -216
  8. package/bundles/cdk-a11y.umd.js.map +1 -1
  9. package/bundles/cdk-a11y.umd.min.js +1 -1
  10. package/bundles/cdk-a11y.umd.min.js.map +1 -1
  11. package/bundles/cdk-accordion.umd.js +16 -9
  12. package/bundles/cdk-accordion.umd.js.map +1 -1
  13. package/bundles/cdk-accordion.umd.min.js.map +1 -1
  14. package/bundles/cdk-bidi.umd.js +11 -6
  15. package/bundles/cdk-bidi.umd.js.map +1 -1
  16. package/bundles/cdk-bidi.umd.min.js.map +1 -1
  17. package/bundles/cdk-coercion.umd.js +25 -9
  18. package/bundles/cdk-coercion.umd.js.map +1 -1
  19. package/bundles/cdk-coercion.umd.min.js +1 -1
  20. package/bundles/cdk-coercion.umd.min.js.map +1 -1
  21. package/bundles/cdk-collections.umd.js +28 -5
  22. package/bundles/cdk-collections.umd.js.map +1 -1
  23. package/bundles/cdk-collections.umd.min.js.map +1 -1
  24. package/bundles/cdk-drag-drop.umd.js +2177 -915
  25. package/bundles/cdk-drag-drop.umd.js.map +1 -1
  26. package/bundles/cdk-drag-drop.umd.min.js +2 -1
  27. package/bundles/cdk-drag-drop.umd.min.js.map +1 -1
  28. package/bundles/cdk-keycodes.umd.js +33 -1
  29. package/bundles/cdk-keycodes.umd.js.map +1 -1
  30. package/bundles/cdk-keycodes.umd.min.js +1 -1
  31. package/bundles/cdk-keycodes.umd.min.js.map +1 -1
  32. package/bundles/cdk-layout.umd.js +29 -22
  33. package/bundles/cdk-layout.umd.js.map +1 -1
  34. package/bundles/cdk-layout.umd.min.js +1 -1
  35. package/bundles/cdk-layout.umd.min.js.map +1 -1
  36. package/bundles/cdk-observers.umd.js +26 -7
  37. package/bundles/cdk-observers.umd.js.map +1 -1
  38. package/bundles/cdk-observers.umd.min.js +1 -1
  39. package/bundles/cdk-observers.umd.min.js.map +1 -1
  40. package/bundles/cdk-overlay.umd.js +605 -258
  41. package/bundles/cdk-overlay.umd.js.map +1 -1
  42. package/bundles/cdk-overlay.umd.min.js +2 -2
  43. package/bundles/cdk-overlay.umd.min.js.map +1 -1
  44. package/bundles/cdk-platform.umd.js +50 -28
  45. package/bundles/cdk-platform.umd.js.map +1 -1
  46. package/bundles/cdk-platform.umd.min.js.map +1 -1
  47. package/bundles/cdk-portal.umd.js +14 -7
  48. package/bundles/cdk-portal.umd.js.map +1 -1
  49. package/bundles/cdk-portal.umd.min.js.map +1 -1
  50. package/bundles/cdk-scrolling.umd.js +139 -44
  51. package/bundles/cdk-scrolling.umd.js.map +1 -1
  52. package/bundles/cdk-scrolling.umd.min.js +1 -1
  53. package/bundles/cdk-scrolling.umd.min.js.map +1 -1
  54. package/bundles/cdk-stepper.umd.js +103 -19
  55. package/bundles/cdk-stepper.umd.js.map +1 -1
  56. package/bundles/cdk-stepper.umd.min.js +1 -1
  57. package/bundles/cdk-stepper.umd.min.js.map +1 -1
  58. package/bundles/cdk-table.umd.js +182 -48
  59. package/bundles/cdk-table.umd.js.map +1 -1
  60. package/bundles/cdk-table.umd.min.js.map +1 -1
  61. package/bundles/cdk-text-field.umd.js +76 -38
  62. package/bundles/cdk-text-field.umd.js.map +1 -1
  63. package/bundles/cdk-text-field.umd.min.js +1 -1
  64. package/bundles/cdk-text-field.umd.min.js.map +1 -1
  65. package/bundles/cdk-tree.umd.js +71 -34
  66. package/bundles/cdk-tree.umd.js.map +1 -1
  67. package/bundles/cdk-tree.umd.min.js +1 -1
  68. package/bundles/cdk-tree.umd.min.js.map +1 -1
  69. package/bundles/cdk.umd.js +5 -4
  70. package/bundles/cdk.umd.js.map +1 -1
  71. package/bundles/cdk.umd.min.js +1 -1
  72. package/bundles/cdk.umd.min.js.map +1 -1
  73. package/coercion/typings/element.d.ts +13 -0
  74. package/coercion/typings/index.metadata.json +1 -1
  75. package/coercion/typings/public-api.d.ts +1 -0
  76. package/drag-drop/typings/{drag-handle.d.ts → directives/drag-handle.d.ts} +3 -0
  77. package/drag-drop/typings/{drag-placeholder.d.ts → directives/drag-placeholder.d.ts} +0 -0
  78. package/drag-drop/typings/{drag-preview.d.ts → directives/drag-preview.d.ts} +0 -0
  79. package/drag-drop/typings/directives/drag.d.ts +109 -0
  80. package/{typings/drag-drop → drag-drop/typings/directives}/drop-list-group.d.ts +3 -0
  81. package/drag-drop/typings/directives/drop-list.d.ts +135 -0
  82. package/drag-drop/typings/drag-drop-registry.d.ts +8 -3
  83. package/drag-drop/typings/drag-events.d.ts +14 -7
  84. package/{typings/esm5/drag-drop/drag.d.ts → drag-drop/typings/drag-ref.d.ts} +152 -82
  85. package/drag-drop/typings/drop-list-container.d.ts +21 -3
  86. package/drag-drop/typings/{drop-list.d.ts → drop-list-ref.d.ts} +132 -81
  87. package/drag-drop/typings/index.d.ts +1 -0
  88. package/drag-drop/typings/index.metadata.json +1 -1
  89. package/drag-drop/typings/public-api.d.ts +13 -6
  90. package/esm2015/a11y.js +337 -190
  91. package/esm2015/a11y.js.map +1 -1
  92. package/esm2015/accordion.js +16 -11
  93. package/esm2015/accordion.js.map +1 -1
  94. package/esm2015/bidi.js +13 -8
  95. package/esm2015/bidi.js.map +1 -1
  96. package/esm2015/cdk.js +7 -6
  97. package/esm2015/cdk.js.map +1 -1
  98. package/esm2015/coercion.js +25 -8
  99. package/esm2015/coercion.js.map +1 -1
  100. package/esm2015/collections.js +22 -7
  101. package/esm2015/collections.js.map +1 -1
  102. package/esm2015/drag-drop.js +1587 -691
  103. package/esm2015/drag-drop.js.map +1 -1
  104. package/esm2015/keycodes.js +31 -4
  105. package/esm2015/keycodes.js.map +1 -1
  106. package/esm2015/layout.js +29 -19
  107. package/esm2015/layout.js.map +1 -1
  108. package/esm2015/observers.js +15 -10
  109. package/esm2015/observers.js.map +1 -1
  110. package/esm2015/overlay.js +393 -232
  111. package/esm2015/overlay.js.map +1 -1
  112. package/esm2015/platform.js +53 -31
  113. package/esm2015/platform.js.map +1 -1
  114. package/esm2015/portal.js +13 -9
  115. package/esm2015/portal.js.map +1 -1
  116. package/esm2015/scrolling.js +102 -45
  117. package/esm2015/scrolling.js.map +1 -1
  118. package/esm2015/stepper.js +93 -24
  119. package/esm2015/stepper.js.map +1 -1
  120. package/esm2015/table.js +89 -45
  121. package/esm2015/table.js.map +1 -1
  122. package/esm2015/text-field.js +54 -37
  123. package/esm2015/text-field.js.map +1 -1
  124. package/esm2015/tree.js +55 -36
  125. package/esm2015/tree.js.map +1 -1
  126. package/esm5/a11y.es5.js +481 -220
  127. package/esm5/a11y.es5.js.map +1 -1
  128. package/esm5/accordion.es5.js +18 -11
  129. package/esm5/accordion.es5.js.map +1 -1
  130. package/esm5/bidi.es5.js +13 -8
  131. package/esm5/bidi.es5.js.map +1 -1
  132. package/esm5/cdk.es5.js +7 -6
  133. package/esm5/cdk.es5.js.map +1 -1
  134. package/esm5/coercion.es5.js +25 -8
  135. package/esm5/coercion.es5.js.map +1 -1
  136. package/esm5/collections.es5.js +35 -7
  137. package/esm5/collections.es5.js.map +1 -1
  138. package/esm5/drag-drop.es5.js +2233 -972
  139. package/esm5/drag-drop.es5.js.map +1 -1
  140. package/esm5/keycodes.es5.js +35 -4
  141. package/esm5/keycodes.es5.js.map +1 -1
  142. package/esm5/layout.es5.js +31 -24
  143. package/esm5/layout.es5.js.map +1 -1
  144. package/esm5/observers.es5.js +29 -10
  145. package/esm5/observers.es5.js.map +1 -1
  146. package/esm5/overlay.es5.js +609 -262
  147. package/esm5/overlay.es5.js.map +1 -1
  148. package/esm5/platform.es5.js +52 -30
  149. package/esm5/platform.es5.js.map +1 -1
  150. package/esm5/portal.es5.js +16 -9
  151. package/esm5/portal.es5.js.map +1 -1
  152. package/esm5/scrolling.es5.js +141 -46
  153. package/esm5/scrolling.es5.js.map +1 -1
  154. package/esm5/stepper.es5.js +106 -24
  155. package/esm5/stepper.es5.js.map +1 -1
  156. package/esm5/table.es5.js +184 -50
  157. package/esm5/table.es5.js.map +1 -1
  158. package/esm5/text-field.es5.js +75 -37
  159. package/esm5/text-field.es5.js.map +1 -1
  160. package/esm5/tree.es5.js +74 -37
  161. package/esm5/tree.es5.js.map +1 -1
  162. package/keycodes/typings/index.metadata.json +1 -1
  163. package/keycodes/typings/modifiers.d.ts +14 -0
  164. package/keycodes/typings/public-api.d.ts +1 -0
  165. package/overlay/typings/index.metadata.json +1 -1
  166. package/overlay/typings/overlay-directives.d.ts +0 -2
  167. package/package.json +4 -4
  168. package/schematics/ng-generate/drag-drop/files/__path__/__name@dasherize@if-flat__/__name@dasherize__.component.ts +2 -2
  169. package/schematics/ng-update/upgrade-data.js +2 -1
  170. package/schematics/ng-update/upgrade-data.js.map +1 -1
  171. package/schematics/ng-update/upgrade-rules/index.js +3 -2
  172. package/schematics/ng-update/upgrade-rules/index.js.map +1 -1
  173. package/schematics/utils/ast/ng-module-imports.d.ts +1 -1
  174. package/schematics/utils/ast/ng-module-imports.js +25 -13
  175. package/schematics/utils/ast/ng-module-imports.js.map +1 -1
  176. package/schematics/utils/get-project.js +2 -1
  177. package/schematics/utils/get-project.js.map +1 -1
  178. package/schematics/utils/parse5-element.js +3 -2
  179. package/schematics/utils/parse5-element.js.map +1 -1
  180. package/schematics/utils/project-targets.js +2 -1
  181. package/schematics/utils/project-targets.js.map +1 -1
  182. package/schematics/utils/version-agnostic-typescript.js +3 -2
  183. package/schematics/utils/version-agnostic-typescript.js.map +1 -1
  184. package/scrolling/typings/index.metadata.json +1 -1
  185. package/stepper/typings/index.metadata.json +1 -1
  186. package/stepper/typings/public-api.d.ts +1 -0
  187. package/stepper/typings/step-header.d.ts +15 -0
  188. package/stepper/typings/stepper.d.ts +11 -1
  189. package/text-field/typings/autosize.d.ts +6 -0
  190. package/text-field/typings/index.metadata.json +1 -1
  191. package/tree/typings/control/base-tree-control.d.ts +1 -1
  192. package/tree/typings/control/nested-tree-control.d.ts +2 -2
  193. package/tree/typings/control/tree-control.d.ts +1 -1
  194. package/tree/typings/nested-node.d.ts +5 -5
  195. package/typings/a11y/focus-monitor/focus-monitor.d.ts +20 -5
  196. package/typings/a11y/focus-trap/focus-trap.d.ts +2 -0
  197. package/typings/a11y/index.metadata.json +1 -1
  198. package/typings/a11y/live-announcer/live-announcer.d.ts +34 -3
  199. package/typings/coercion/element.d.ts +13 -0
  200. package/typings/coercion/index.metadata.json +1 -1
  201. package/typings/coercion/public-api.d.ts +1 -0
  202. package/typings/{esm5/drag-drop → drag-drop/directives}/drag-handle.d.ts +3 -0
  203. package/typings/drag-drop/{drag-placeholder.d.ts → directives/drag-placeholder.d.ts} +0 -0
  204. package/typings/drag-drop/{drag-preview.d.ts → directives/drag-preview.d.ts} +0 -0
  205. package/typings/drag-drop/directives/drag.d.ts +109 -0
  206. package/typings/{esm5/drag-drop → drag-drop/directives}/drop-list-group.d.ts +3 -0
  207. package/typings/drag-drop/directives/drop-list.d.ts +135 -0
  208. package/typings/drag-drop/drag-drop-registry.d.ts +8 -3
  209. package/typings/drag-drop/drag-events.d.ts +14 -7
  210. package/typings/drag-drop/{drag.d.ts → drag-ref.d.ts} +152 -82
  211. package/typings/drag-drop/drop-list-container.d.ts +21 -3
  212. package/typings/{esm5/drag-drop/drop-list.d.ts → drag-drop/drop-list-ref.d.ts} +132 -81
  213. package/typings/drag-drop/index.d.ts +1 -0
  214. package/typings/drag-drop/index.metadata.json +1 -1
  215. package/typings/drag-drop/public-api.d.ts +13 -6
  216. package/typings/esm5/a11y/focus-monitor/focus-monitor.d.ts +20 -5
  217. package/typings/esm5/a11y/focus-trap/focus-trap.d.ts +2 -0
  218. package/typings/esm5/a11y/index.metadata.json +1 -1
  219. package/typings/esm5/a11y/live-announcer/live-announcer.d.ts +34 -3
  220. package/typings/esm5/coercion/element.d.ts +13 -0
  221. package/typings/esm5/coercion/index.metadata.json +1 -1
  222. package/typings/esm5/coercion/public-api.d.ts +1 -0
  223. package/typings/{drag-drop → esm5/drag-drop/directives}/drag-handle.d.ts +3 -0
  224. package/typings/esm5/drag-drop/{drag-placeholder.d.ts → directives/drag-placeholder.d.ts} +0 -0
  225. package/typings/esm5/drag-drop/{drag-preview.d.ts → directives/drag-preview.d.ts} +0 -0
  226. package/typings/esm5/drag-drop/directives/drag.d.ts +109 -0
  227. package/{drag-drop/typings → typings/esm5/drag-drop/directives}/drop-list-group.d.ts +3 -0
  228. package/typings/esm5/drag-drop/directives/drop-list.d.ts +135 -0
  229. package/typings/esm5/drag-drop/drag-drop-registry.d.ts +8 -3
  230. package/typings/esm5/drag-drop/drag-events.d.ts +14 -7
  231. package/{drag-drop/typings/drag.d.ts → typings/esm5/drag-drop/drag-ref.d.ts} +152 -82
  232. package/typings/esm5/drag-drop/drop-list-container.d.ts +21 -3
  233. package/typings/{drag-drop/drop-list.d.ts → esm5/drag-drop/drop-list-ref.d.ts} +132 -81
  234. package/typings/esm5/drag-drop/index.d.ts +1 -0
  235. package/typings/esm5/drag-drop/index.metadata.json +1 -1
  236. package/typings/esm5/drag-drop/public-api.d.ts +13 -6
  237. package/typings/esm5/index.metadata.json +1 -1
  238. package/typings/esm5/keycodes/index.metadata.json +1 -1
  239. package/typings/esm5/keycodes/modifiers.d.ts +14 -0
  240. package/typings/esm5/keycodes/public-api.d.ts +1 -0
  241. package/typings/esm5/overlay/index.metadata.json +1 -1
  242. package/typings/esm5/overlay/overlay-directives.d.ts +0 -2
  243. package/typings/esm5/scrolling/index.metadata.json +1 -1
  244. package/typings/esm5/stepper/index.metadata.json +1 -1
  245. package/typings/esm5/stepper/public-api.d.ts +1 -0
  246. package/typings/esm5/stepper/step-header.d.ts +15 -0
  247. package/typings/esm5/stepper/stepper.d.ts +11 -1
  248. package/typings/esm5/text-field/autosize.d.ts +6 -0
  249. package/typings/esm5/text-field/index.metadata.json +1 -1
  250. package/typings/esm5/tree/control/base-tree-control.d.ts +1 -1
  251. package/typings/esm5/tree/control/nested-tree-control.d.ts +2 -2
  252. package/typings/esm5/tree/control/tree-control.d.ts +1 -1
  253. package/typings/esm5/tree/nested-node.d.ts +5 -5
  254. package/typings/index.metadata.json +1 -1
  255. package/typings/keycodes/index.metadata.json +1 -1
  256. package/typings/keycodes/modifiers.d.ts +14 -0
  257. package/typings/keycodes/public-api.d.ts +1 -0
  258. package/typings/overlay/index.metadata.json +1 -1
  259. package/typings/overlay/overlay-directives.d.ts +0 -2
  260. package/typings/schematics/utils/ast/ng-module-imports.d.ts +1 -1
  261. package/typings/scrolling/index.metadata.json +1 -1
  262. package/typings/stepper/index.metadata.json +1 -1
  263. package/typings/stepper/public-api.d.ts +1 -0
  264. package/typings/stepper/step-header.d.ts +15 -0
  265. package/typings/stepper/stepper.d.ts +11 -1
  266. package/typings/text-field/autosize.d.ts +6 -0
  267. package/typings/text-field/index.metadata.json +1 -1
  268. package/typings/tree/control/base-tree-control.d.ts +1 -1
  269. package/typings/tree/control/nested-tree-control.d.ts +2 -2
  270. package/typings/tree/control/tree-control.d.ts +1 -1
  271. 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
- @type {?} */
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
- @type {?} */
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
- @type {?} */
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
- @type {?} */
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
- @type {?} */
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
- @type {?} */
97
+ * @type {?}
98
+ */
93
99
  const messageRegistry = new Map();
94
- /** *
100
+ /**
95
101
  * Container for all registered messages.
96
- @type {?} */
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 {?} */ ((this._document.createTextNode(message))));
179
- this._createMessagesContainer(); /** @type {?} */
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 {?} */ ((preExistingContainer.parentNode)).removeChild(preExistingContainer);
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 {?} */ ((messageRegistry.get(message)));
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 {?} */ ((messageRegistry.get(message)));
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
- @type {?} */
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 (!this._skipPredicateFn(item) && /** @type {?} */ ((item.getLabel))().toUpperCase().trim().indexOf(inputString) === 0) {
454
- this.setActiveItem(index);
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
- // Attempt to use the `event.key` which also maps it to the user's keyboard language,
526
- // otherwise fall back to resolving alphanumeric characters via the keyCode.
527
- if (event.key && event.key.length === 1) {
528
- this._letterKeyStream.next(event.key.toLocaleUpperCase());
529
- }
530
- else if ((keyCode >= A && keyCode <= Z) || (keyCode >= ZERO && keyCode <= NINE)) {
531
- this._letterKeyStream.next(String.fromCharCode(keyCode));
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.
@@ -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
- if (this._startAnchor && this._startAnchor.parentNode) {
1058
- this._startAnchor.parentNode.removeChild(this._startAnchor);
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 (this._endAnchor && this._endAnchor.parentNode) {
1061
- this._endAnchor.parentNode.removeChild(this._endAnchor);
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(); /** @type {?} */
1079
- ((this._startAnchor)).addEventListener('focus', () => this.focusLastTabbableElement());
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(); /** @type {?} */
1083
- ((this._endAnchor)).addEventListener('focus', () => this.focusFirstTabbableElement());
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 {?} */ ((this._startAnchor)), this._element);
1088
- this._element.parentNode.insertBefore(/** @type {?} */ ((this._endAnchor)), this._element.nextSibling);
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() {
@@ -1266,6 +1336,7 @@ class FocusTrap {
1266
1336
  }
1267
1337
  /**
1268
1338
  * Toggles the `tabindex` of an anchor, based on the enabled state of the focus trap.
1339
+ * @private
1269
1340
  * @param {?} isEnabled Whether the focus trap is enabled.
1270
1341
  * @param {?} anchor Anchor on which to toggle the tabindex.
1271
1342
  * @return {?}
@@ -1277,6 +1348,7 @@ class FocusTrap {
1277
1348
  }
1278
1349
  /**
1279
1350
  * Executes a function when the zone is stable.
1351
+ * @private
1280
1352
  * @param {?} fn
1281
1353
  * @return {?}
1282
1354
  */
@@ -1382,7 +1454,7 @@ class CdkTrapFocus {
1382
1454
  ngAfterContentInit() {
1383
1455
  this.focusTrap.attachAnchors();
1384
1456
  if (this.autoCapture) {
1385
- this._previouslyFocusedElement = /** @type {?} */ (this._document.activeElement);
1457
+ this._previouslyFocusedElement = (/** @type {?} */ (this._document.activeElement));
1386
1458
  this.focusTrap.focusInitialElementWhenReady();
1387
1459
  }
1388
1460
  }
@@ -1414,8 +1486,10 @@ CdkTrapFocus.propDecorators = {
1414
1486
 
1415
1487
  /**
1416
1488
  * @fileoverview added by tsickle
1417
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1489
+ * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
1418
1490
  */
1491
+ // The token for the live announcer element is defined in a separate file from LiveAnnouncer
1492
+ // as a workaround for https://github.com/angular/angular/issues/22559
1419
1493
  /** @type {?} */
1420
1494
  const LIVE_ANNOUNCER_ELEMENT_TOKEN = new InjectionToken('liveAnnouncerElement', {
1421
1495
  providedIn: 'root',
@@ -1431,7 +1505,7 @@ function LIVE_ANNOUNCER_ELEMENT_TOKEN_FACTORY() {
1431
1505
 
1432
1506
  /**
1433
1507
  * @fileoverview added by tsickle
1434
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1508
+ * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
1435
1509
  */
1436
1510
  class LiveAnnouncer {
1437
1511
  /**
@@ -1448,15 +1522,25 @@ class LiveAnnouncer {
1448
1522
  this._liveElement = elementToken || this._createLiveElement();
1449
1523
  }
1450
1524
  /**
1451
- * Announces a message to screenreaders.
1452
- * @param {?} message Message to be announced to the screenreader
1453
- * @param {?=} politeness The politeness of the announcer element
1454
- * @return {?} Promise that will be resolved when the message is added to the DOM.
1525
+ * @param {?} message
1526
+ * @param {...?} args
1527
+ * @return {?}
1455
1528
  */
1456
- announce(message, politeness = 'polite') {
1457
- this._liveElement.textContent = '';
1529
+ announce(message, ...args) {
1530
+ /** @type {?} */
1531
+ let politeness;
1532
+ /** @type {?} */
1533
+ let duration;
1534
+ if (args.length === 1 && typeof args[0] === 'number') {
1535
+ duration = args[0];
1536
+ }
1537
+ else {
1538
+ [politeness, duration] = args;
1539
+ }
1540
+ this.clear();
1541
+ clearTimeout(this._previousTimeout);
1458
1542
  // TODO: ensure changing the politeness works on all environments we support.
1459
- this._liveElement.setAttribute('aria-live', politeness);
1543
+ this._liveElement.setAttribute('aria-live', (/** @type {?} */ (politeness)) || 'polite');
1460
1544
  // This 100ms timeout is necessary for some browser + screen-reader combinations:
1461
1545
  // - Both JAWS and NVDA over IE11 will not announce anything without a non-zero timeout.
1462
1546
  // - With Chrome and IE11 with NVDA or JAWS, a repeated (identical) message won't be read a
@@ -1468,10 +1552,24 @@ class LiveAnnouncer {
1468
1552
  this._previousTimeout = setTimeout(() => {
1469
1553
  this._liveElement.textContent = message;
1470
1554
  resolve();
1555
+ if (typeof duration === 'number') {
1556
+ this._previousTimeout = setTimeout(() => this.clear(), duration);
1557
+ }
1471
1558
  }, 100);
1472
1559
  });
1473
1560
  });
1474
1561
  }
1562
+ /**
1563
+ * Clears the current text from the announcer element. Can be used to prevent
1564
+ * screen readers from reading the text out again while the user is going
1565
+ * through the page landmarks.
1566
+ * @return {?}
1567
+ */
1568
+ clear() {
1569
+ if (this._liveElement) {
1570
+ this._liveElement.textContent = '';
1571
+ }
1572
+ }
1475
1573
  /**
1476
1574
  * @return {?}
1477
1575
  */
@@ -1479,10 +1577,11 @@ class LiveAnnouncer {
1479
1577
  clearTimeout(this._previousTimeout);
1480
1578
  if (this._liveElement && this._liveElement.parentNode) {
1481
1579
  this._liveElement.parentNode.removeChild(this._liveElement);
1482
- this._liveElement = /** @type {?} */ ((null));
1580
+ this._liveElement = (/** @type {?} */ (null));
1483
1581
  }
1484
1582
  }
1485
1583
  /**
1584
+ * @private
1486
1585
  * @return {?}
1487
1586
  */
1488
1587
  _createLiveElement() {
@@ -1494,7 +1593,7 @@ class LiveAnnouncer {
1494
1593
  const liveEl = this._document.createElement('div');
1495
1594
  // Remove any old containers. This can happen when coming in from a server-side-rendered page.
1496
1595
  for (let i = 0; i < previousElements.length; i++) {
1497
- /** @type {?} */ ((previousElements[i].parentNode)).removeChild(previousElements[i]);
1596
+ (/** @type {?} */ (previousElements[i].parentNode)).removeChild(previousElements[i]);
1498
1597
  }
1499
1598
  liveEl.classList.add(elementClass);
1500
1599
  liveEl.classList.add('cdk-visually-hidden');
@@ -1554,6 +1653,7 @@ class CdkAriaLive {
1554
1653
  return this._contentObserver
1555
1654
  .observe(this._elementRef)
1556
1655
  .subscribe(() => {
1656
+ // Note that we use textContent here, rather than innerText, in order to avoid a reflow.
1557
1657
  /** @type {?} */
1558
1658
  const elementText = this._elementRef.nativeElement.textContent;
1559
1659
  // The `MutationObserver` fires also for attribute
@@ -1593,18 +1693,19 @@ CdkAriaLive.propDecorators = {
1593
1693
  };
1594
1694
  /**
1595
1695
  * \@docs-private \@deprecated \@breaking-change 8.0.0
1596
- * @param {?} parentDispatcher
1696
+ * @param {?} parentAnnouncer
1597
1697
  * @param {?} liveElement
1598
1698
  * @param {?} _document
1599
1699
  * @param {?} ngZone
1600
1700
  * @return {?}
1601
1701
  */
1602
- function LIVE_ANNOUNCER_PROVIDER_FACTORY(parentDispatcher, liveElement, _document, ngZone) {
1603
- return parentDispatcher || new LiveAnnouncer(liveElement, _document, ngZone);
1702
+ function LIVE_ANNOUNCER_PROVIDER_FACTORY(parentAnnouncer, liveElement, _document, ngZone) {
1703
+ return parentAnnouncer || new LiveAnnouncer(liveElement, ngZone, _document);
1604
1704
  }
1605
- /** *
1705
+ /**
1606
1706
  * \@docs-private \@deprecated \@breaking-change 8.0.0
1607
- @type {?} */
1707
+ * @type {?}
1708
+ */
1608
1709
  const LIVE_ANNOUNCER_PROVIDER = {
1609
1710
  // If there is already a LiveAnnouncer available, use that. Otherwise, provide a new one.
1610
1711
  provide: LiveAnnouncer,
@@ -1619,10 +1720,21 @@ const LIVE_ANNOUNCER_PROVIDER = {
1619
1720
 
1620
1721
  /**
1621
1722
  * @fileoverview added by tsickle
1622
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1723
+ * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
1623
1724
  */
1725
+ // This is the value used by AngularJS Material. Through trial and error (on iPhone 6S) they found
1726
+ // that a value of around 650ms seems appropriate.
1624
1727
  /** @type {?} */
1625
1728
  const TOUCH_BUFFER_MS = 650;
1729
+ /**
1730
+ * Event listener options that enable capturing and also
1731
+ * mark the the listener as passive if the browser supports it.
1732
+ * @type {?}
1733
+ */
1734
+ const captureEventListenerOptions = normalizePassiveListenerOptions({
1735
+ passive: true,
1736
+ capture: true
1737
+ });
1626
1738
  /**
1627
1739
  * Monitors mouse and keyboard events to determine the cause of focus events.
1628
1740
  */
@@ -1646,14 +1758,54 @@ class FocusMonitor {
1646
1758
  * Map of elements being monitored to their info.
1647
1759
  */
1648
1760
  this._elementInfo = new Map();
1649
- /**
1650
- * A map of global objects to lists of current listeners.
1651
- */
1652
- this._unregisterGlobalListeners = () => { };
1653
1761
  /**
1654
1762
  * The number of elements currently being monitored.
1655
1763
  */
1656
1764
  this._monitoredElementCount = 0;
1765
+ /**
1766
+ * Event listener for `keydown` events on the document.
1767
+ * Needs to be an arrow function in order to preserve the context when it gets bound.
1768
+ */
1769
+ this._documentKeydownListener = () => {
1770
+ // On keydown record the origin and clear any touch event that may be in progress.
1771
+ this._lastTouchTarget = null;
1772
+ this._setOriginForCurrentEventQueue('keyboard');
1773
+ };
1774
+ /**
1775
+ * Event listener for `mousedown` events on the document.
1776
+ * Needs to be an arrow function in order to preserve the context when it gets bound.
1777
+ */
1778
+ this._documentMousedownListener = () => {
1779
+ // On mousedown record the origin only if there is not touch
1780
+ // target, since a mousedown can happen as a result of a touch event.
1781
+ if (!this._lastTouchTarget) {
1782
+ this._setOriginForCurrentEventQueue('mouse');
1783
+ }
1784
+ };
1785
+ /**
1786
+ * Event listener for `touchstart` events on the document.
1787
+ * Needs to be an arrow function in order to preserve the context when it gets bound.
1788
+ */
1789
+ this._documentTouchstartListener = (event) => {
1790
+ // When the touchstart event fires the focus event is not yet in the event queue. This means
1791
+ // we can't rely on the trick used above (setting timeout of 1ms). Instead we wait 650ms to
1792
+ // see if a focus happens.
1793
+ if (this._touchTimeoutId != null) {
1794
+ clearTimeout(this._touchTimeoutId);
1795
+ }
1796
+ this._lastTouchTarget = event.target;
1797
+ this._touchTimeoutId = setTimeout(() => this._lastTouchTarget = null, TOUCH_BUFFER_MS);
1798
+ };
1799
+ /**
1800
+ * Event listener for `focus` events on the window.
1801
+ * Needs to be an arrow function in order to preserve the context when it gets bound.
1802
+ */
1803
+ this._windowFocusListener = () => {
1804
+ // Make a note of when the window regains focus, so we can
1805
+ // restore the origin info for the focused element.
1806
+ this._windowFocused = true;
1807
+ this._windowFocusTimeoutId = setTimeout(() => this._windowFocused = false);
1808
+ };
1657
1809
  }
1658
1810
  /**
1659
1811
  * @param {?} element
@@ -1666,14 +1818,15 @@ class FocusMonitor {
1666
1818
  return of(null);
1667
1819
  }
1668
1820
  /** @type {?} */
1669
- const nativeElement = this._getNativeElement(element);
1821
+ const nativeElement = coerceElement(element);
1670
1822
  // Check if we're already monitoring this element.
1671
1823
  if (this._elementInfo.has(nativeElement)) {
1672
1824
  /** @type {?} */
1673
- let cachedInfo = this._elementInfo.get(nativeElement); /** @type {?} */
1674
- ((cachedInfo)).checkChildren = checkChildren;
1675
- return /** @type {?} */ ((cachedInfo)).subject.asObservable();
1825
+ let cachedInfo = this._elementInfo.get(nativeElement);
1826
+ (/** @type {?} */ (cachedInfo)).checkChildren = checkChildren;
1827
+ return (/** @type {?} */ (cachedInfo)).subject.asObservable();
1676
1828
  }
1829
+ // Create monitored element info.
1677
1830
  /** @type {?} */
1678
1831
  let info = {
1679
1832
  unlisten: () => { },
@@ -1682,6 +1835,7 @@ class FocusMonitor {
1682
1835
  };
1683
1836
  this._elementInfo.set(nativeElement, info);
1684
1837
  this._incrementMonitoredElementCount();
1838
+ // Start listening. We need to listen in capture phase since focus events don't bubble.
1685
1839
  /** @type {?} */
1686
1840
  let focusListener = (event) => this._onFocus(event, nativeElement);
1687
1841
  /** @type {?} */
@@ -1703,7 +1857,7 @@ class FocusMonitor {
1703
1857
  */
1704
1858
  stopMonitoring(element) {
1705
1859
  /** @type {?} */
1706
- const nativeElement = this._getNativeElement(element);
1860
+ const nativeElement = coerceElement(element);
1707
1861
  /** @type {?} */
1708
1862
  const elementInfo = this._elementInfo.get(nativeElement);
1709
1863
  if (elementInfo) {
@@ -1722,12 +1876,12 @@ class FocusMonitor {
1722
1876
  */
1723
1877
  focusVia(element, origin, options) {
1724
1878
  /** @type {?} */
1725
- const nativeElement = this._getNativeElement(element);
1879
+ const nativeElement = coerceElement(element);
1726
1880
  this._setOriginForCurrentEventQueue(origin);
1727
1881
  // `focus` isn't available on the server
1728
1882
  if (typeof nativeElement.focus === 'function') {
1729
1883
  // Cast the element to `any`, because the TS typings don't have the `options` parameter yet.
1730
- (/** @type {?} */ (nativeElement)).focus(options);
1884
+ ((/** @type {?} */ (nativeElement))).focus(options);
1731
1885
  }
1732
1886
  }
1733
1887
  /**
@@ -1737,63 +1891,7 @@ class FocusMonitor {
1737
1891
  this._elementInfo.forEach((_info, element) => this.stopMonitoring(element));
1738
1892
  }
1739
1893
  /**
1740
- * Register necessary event listeners on the document and window.
1741
- * @return {?}
1742
- */
1743
- _registerGlobalListeners() {
1744
- // Do nothing if we're not on the browser platform.
1745
- if (!this._platform.isBrowser) {
1746
- return;
1747
- }
1748
- /** @type {?} */
1749
- let documentKeydownListener = () => {
1750
- this._lastTouchTarget = null;
1751
- this._setOriginForCurrentEventQueue('keyboard');
1752
- };
1753
- /** @type {?} */
1754
- let documentMousedownListener = () => {
1755
- if (!this._lastTouchTarget) {
1756
- this._setOriginForCurrentEventQueue('mouse');
1757
- }
1758
- };
1759
- /** @type {?} */
1760
- let documentTouchstartListener = (event) => {
1761
- if (this._touchTimeoutId != null) {
1762
- clearTimeout(this._touchTimeoutId);
1763
- }
1764
- this._lastTouchTarget = event.target;
1765
- this._touchTimeoutId = setTimeout(() => this._lastTouchTarget = null, TOUCH_BUFFER_MS);
1766
- };
1767
- /** @type {?} */
1768
- let windowFocusListener = () => {
1769
- this._windowFocused = true;
1770
- this._windowFocusTimeoutId = setTimeout(() => this._windowFocused = false);
1771
- };
1772
- /** @type {?} */
1773
- const captureEventListenerOptions = normalizePassiveListenerOptions({
1774
- passive: true,
1775
- capture: true
1776
- });
1777
- // Note: we listen to events in the capture phase so we can detect them even if the user stops
1778
- // propagation.
1779
- this._ngZone.runOutsideAngular(() => {
1780
- document.addEventListener('keydown', documentKeydownListener, captureEventListenerOptions);
1781
- document.addEventListener('mousedown', documentMousedownListener, captureEventListenerOptions);
1782
- document.addEventListener('touchstart', documentTouchstartListener, captureEventListenerOptions);
1783
- window.addEventListener('focus', windowFocusListener);
1784
- });
1785
- this._unregisterGlobalListeners = () => {
1786
- document.removeEventListener('keydown', documentKeydownListener, captureEventListenerOptions);
1787
- document.removeEventListener('mousedown', documentMousedownListener, captureEventListenerOptions);
1788
- document.removeEventListener('touchstart', documentTouchstartListener, captureEventListenerOptions);
1789
- window.removeEventListener('focus', windowFocusListener);
1790
- // Clear timeouts for all potentially pending timeouts to prevent the leaks.
1791
- clearTimeout(this._windowFocusTimeoutId);
1792
- clearTimeout(this._touchTimeoutId);
1793
- clearTimeout(this._originTimeoutId);
1794
- };
1795
- }
1796
- /**
1894
+ * @private
1797
1895
  * @param {?} element
1798
1896
  * @param {?} className
1799
1897
  * @param {?} shouldSet
@@ -1809,6 +1907,7 @@ class FocusMonitor {
1809
1907
  }
1810
1908
  /**
1811
1909
  * Sets the focus classes on the element based on the given focus origin.
1910
+ * @private
1812
1911
  * @param {?} element The element to update the classes on.
1813
1912
  * @param {?=} origin The focus origin.
1814
1913
  * @return {?}
@@ -1826,6 +1925,7 @@ class FocusMonitor {
1826
1925
  }
1827
1926
  /**
1828
1927
  * Sets the origin and schedules an async function to clear it at the end of the event queue.
1928
+ * @private
1829
1929
  * @param {?} origin The origin to set.
1830
1930
  * @return {?}
1831
1931
  */
@@ -1840,10 +1940,28 @@ class FocusMonitor {
1840
1940
  }
1841
1941
  /**
1842
1942
  * Checks whether the given focus event was caused by a touchstart event.
1943
+ * @private
1843
1944
  * @param {?} event The focus event to check.
1844
1945
  * @return {?} Whether the event was caused by a touch.
1845
1946
  */
1846
1947
  _wasCausedByTouch(event) {
1948
+ // Note(mmalerba): This implementation is not quite perfect, there is a small edge case.
1949
+ // Consider the following dom structure:
1950
+ //
1951
+ // <div #parent tabindex="0" cdkFocusClasses>
1952
+ // <div #child (click)="#parent.focus()"></div>
1953
+ // </div>
1954
+ //
1955
+ // If the user touches the #child element and the #parent is programmatically focused as a
1956
+ // result, this code will still consider it to have been caused by the touch event and will
1957
+ // apply the cdk-touch-focused class rather than the cdk-program-focused class. This is a
1958
+ // relatively small edge-case that can be worked around by using
1959
+ // focusVia(parentEl, 'program') to focus the parent element.
1960
+ //
1961
+ // If we decide that we absolutely must handle this case correctly, we can do so by listening
1962
+ // for the first focus event after the touchstart, and then the first blur event after that
1963
+ // focus event. When that blur event fires we know that whatever follows is not a result of the
1964
+ // touchstart.
1847
1965
  /** @type {?} */
1848
1966
  let focusTarget = event.target;
1849
1967
  return this._lastTouchTarget instanceof Node && focusTarget instanceof Node &&
@@ -1851,16 +1969,33 @@ class FocusMonitor {
1851
1969
  }
1852
1970
  /**
1853
1971
  * Handles focus events on a registered element.
1972
+ * @private
1854
1973
  * @param {?} event The focus event.
1855
1974
  * @param {?} element The monitored element.
1856
1975
  * @return {?}
1857
1976
  */
1858
1977
  _onFocus(event, element) {
1978
+ // NOTE(mmalerba): We currently set the classes based on the focus origin of the most recent
1979
+ // focus event affecting the monitored element. If we want to use the origin of the first event
1980
+ // instead we should check for the cdk-focused class here and return if the element already has
1981
+ // it. (This only matters for elements that have includesChildren = true).
1982
+ // NOTE(mmalerba): We currently set the classes based on the focus origin of the most recent
1983
+ // focus event affecting the monitored element. If we want to use the origin of the first event
1984
+ // instead we should check for the cdk-focused class here and return if the element already has
1985
+ // it. (This only matters for elements that have includesChildren = true).
1986
+ // If we are not counting child-element-focus as focused, make sure that the event target is the
1987
+ // monitored element itself.
1859
1988
  /** @type {?} */
1860
1989
  const elementInfo = this._elementInfo.get(element);
1861
1990
  if (!elementInfo || (!elementInfo.checkChildren && element !== event.target)) {
1862
1991
  return;
1863
1992
  }
1993
+ // If we couldn't detect a cause for the focus event, it's due to one of three reasons:
1994
+ // 1) The window has just regained focus, in which case we want to restore the focused state of
1995
+ // the element from before the window blurred.
1996
+ // 2) It was caused by a touch event, in which case we mark the origin as 'touch'.
1997
+ // 3) The element was programmatically focused, in which case we should mark the origin as
1998
+ // 'program'.
1864
1999
  /** @type {?} */
1865
2000
  let origin = this._origin;
1866
2001
  if (!origin) {
@@ -1885,6 +2020,8 @@ class FocusMonitor {
1885
2020
  * @return {?}
1886
2021
  */
1887
2022
  _onBlur(event, element) {
2023
+ // If we are counting child-element-focus as focused, make sure that we aren't just blurring in
2024
+ // order to focus another child of the monitored element.
1888
2025
  /** @type {?} */
1889
2026
  const elementInfo = this._elementInfo.get(element);
1890
2027
  if (!elementInfo || (elementInfo.checkChildren && event.relatedTarget instanceof Node &&
@@ -1895,6 +2032,7 @@ class FocusMonitor {
1895
2032
  this._emitOrigin(elementInfo.subject, null);
1896
2033
  }
1897
2034
  /**
2035
+ * @private
1898
2036
  * @param {?} subject
1899
2037
  * @param {?} origin
1900
2038
  * @return {?}
@@ -1903,31 +2041,39 @@ class FocusMonitor {
1903
2041
  this._ngZone.run(() => subject.next(origin));
1904
2042
  }
1905
2043
  /**
2044
+ * @private
1906
2045
  * @return {?}
1907
2046
  */
1908
2047
  _incrementMonitoredElementCount() {
1909
2048
  // Register global listeners when first element is monitored.
1910
- if (++this._monitoredElementCount == 1) {
1911
- this._registerGlobalListeners();
2049
+ if (++this._monitoredElementCount == 1 && this._platform.isBrowser) {
2050
+ // Note: we listen to events in the capture phase so we
2051
+ // can detect them even if the user stops propagation.
2052
+ this._ngZone.runOutsideAngular(() => {
2053
+ document.addEventListener('keydown', this._documentKeydownListener, captureEventListenerOptions);
2054
+ document.addEventListener('mousedown', this._documentMousedownListener, captureEventListenerOptions);
2055
+ document.addEventListener('touchstart', this._documentTouchstartListener, captureEventListenerOptions);
2056
+ window.addEventListener('focus', this._windowFocusListener);
2057
+ });
1912
2058
  }
1913
2059
  }
1914
2060
  /**
2061
+ * @private
1915
2062
  * @return {?}
1916
2063
  */
1917
2064
  _decrementMonitoredElementCount() {
1918
2065
  // Unregister global listeners when last element is unmonitored.
1919
2066
  if (!--this._monitoredElementCount) {
1920
- this._unregisterGlobalListeners();
1921
- this._unregisterGlobalListeners = () => { };
2067
+ document.removeEventListener('keydown', this._documentKeydownListener, captureEventListenerOptions);
2068
+ document.removeEventListener('mousedown', this._documentMousedownListener, captureEventListenerOptions);
2069
+ document.removeEventListener('touchstart', this._documentTouchstartListener, captureEventListenerOptions);
2070
+ window.removeEventListener('focus', this._windowFocusListener);
2071
+ // Clear timeouts for all potentially pending timeouts to prevent the leaks.
2072
+ clearTimeout(this._windowFocusTimeoutId);
2073
+ clearTimeout(this._touchTimeoutId);
2074
+ clearTimeout(this._originTimeoutId);
1922
2075
  }
1923
2076
  }
1924
- /**
1925
- * @param {?} element
1926
- * @return {?}
1927
- */
1928
- _getNativeElement(element) {
1929
- return element instanceof ElementRef ? element.nativeElement : element;
1930
- }
1931
2077
  }
1932
2078
  FocusMonitor.decorators = [
1933
2079
  { type: Injectable, args: [{ providedIn: 'root' },] },
@@ -1990,9 +2136,10 @@ CdkMonitorFocus.propDecorators = {
1990
2136
  function FOCUS_MONITOR_PROVIDER_FACTORY(parentDispatcher, ngZone, platform) {
1991
2137
  return parentDispatcher || new FocusMonitor(ngZone, platform);
1992
2138
  }
1993
- /** *
2139
+ /**
1994
2140
  * \@docs-private \@deprecated \@breaking-change 8.0.0
1995
- @type {?} */
2141
+ * @type {?}
2142
+ */
1996
2143
  const FOCUS_MONITOR_PROVIDER = {
1997
2144
  // If there is already a FocusMonitor available, use that. Otherwise, provide a new one.
1998
2145
  provide: FocusMonitor,
@@ -2002,7 +2149,7 @@ const FOCUS_MONITOR_PROVIDER = {
2002
2149
 
2003
2150
  /**
2004
2151
  * @fileoverview added by tsickle
2005
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2152
+ * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2006
2153
  */
2007
2154
 
2008
2155
  /**
@@ -2020,7 +2167,7 @@ function isFakeMousedownFromScreenReader(event) {
2020
2167
 
2021
2168
  /**
2022
2169
  * @fileoverview added by tsickle
2023
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2170
+ * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2024
2171
  */
2025
2172
  class A11yModule {
2026
2173
  }
@@ -2034,12 +2181,12 @@ A11yModule.decorators = [
2034
2181
 
2035
2182
  /**
2036
2183
  * @fileoverview added by tsickle
2037
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2184
+ * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2038
2185
  */
2039
2186
 
2040
2187
  /**
2041
2188
  * @fileoverview added by tsickle
2042
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2189
+ * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2043
2190
  */
2044
2191
 
2045
2192
  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 };