@angular/cdk 9.2.0 → 9.2.4

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 (241) hide show
  1. package/_text-field.scss +19 -4
  2. package/a11y/focus-monitor/focus-monitor.d.ts +15 -2
  3. package/a11y/high-contrast-mode/high-contrast-mode-detector.d.ts +2 -2
  4. package/a11y/index.metadata.json +1 -1
  5. package/bundles/cdk-a11y.umd.js +133 -86
  6. package/bundles/cdk-a11y.umd.js.map +1 -1
  7. package/bundles/cdk-a11y.umd.min.js +13 -6
  8. package/bundles/cdk-a11y.umd.min.js.map +1 -1
  9. package/bundles/cdk-drag-drop.umd.js +292 -179
  10. package/bundles/cdk-drag-drop.umd.js.map +1 -1
  11. package/bundles/cdk-drag-drop.umd.min.js +23 -9
  12. package/bundles/cdk-drag-drop.umd.min.js.map +1 -1
  13. package/bundles/cdk-overlay.umd.js +2 -12
  14. package/bundles/cdk-overlay.umd.js.map +1 -1
  15. package/bundles/cdk-overlay.umd.min.js +2 -2
  16. package/bundles/cdk-overlay.umd.min.js.map +1 -1
  17. package/bundles/cdk-platform.umd.js +3 -1
  18. package/bundles/cdk-platform.umd.js.map +1 -1
  19. package/bundles/cdk-platform.umd.min.js +4 -4
  20. package/bundles/cdk-platform.umd.min.js.map +1 -1
  21. package/bundles/cdk-scrolling.umd.js +18 -3
  22. package/bundles/cdk-scrolling.umd.js.map +1 -1
  23. package/bundles/cdk-scrolling.umd.min.js +2 -2
  24. package/bundles/cdk-scrolling.umd.min.js.map +1 -1
  25. package/bundles/cdk-table.umd.js +8 -0
  26. package/bundles/cdk-table.umd.js.map +1 -1
  27. package/bundles/cdk-table.umd.min.js +1 -1
  28. package/bundles/cdk-table.umd.min.js.map +1 -1
  29. package/bundles/cdk-testing-protractor.umd.js +14 -10
  30. package/bundles/cdk-testing-protractor.umd.js.map +1 -1
  31. package/bundles/cdk-testing-protractor.umd.min.js +1 -1
  32. package/bundles/cdk-testing-protractor.umd.min.js.map +1 -1
  33. package/bundles/cdk-testing-testbed.umd.js +71 -16
  34. package/bundles/cdk-testing-testbed.umd.js.map +1 -1
  35. package/bundles/cdk-testing-testbed.umd.min.js +6 -6
  36. package/bundles/cdk-testing-testbed.umd.min.js.map +1 -1
  37. package/bundles/cdk-testing.umd.js.map +1 -1
  38. package/bundles/cdk-text-field.umd.js +7 -4
  39. package/bundles/cdk-text-field.umd.js.map +1 -1
  40. package/bundles/cdk-text-field.umd.min.js +2 -2
  41. package/bundles/cdk-text-field.umd.min.js.map +1 -1
  42. package/bundles/cdk-tree.umd.js +9 -4
  43. package/bundles/cdk-tree.umd.js.map +1 -1
  44. package/bundles/cdk-tree.umd.min.js +1 -1
  45. package/bundles/cdk-tree.umd.min.js.map +1 -1
  46. package/bundles/cdk.umd.js +1 -1
  47. package/bundles/cdk.umd.js.map +1 -1
  48. package/bundles/cdk.umd.min.js +1 -1
  49. package/bundles/cdk.umd.min.js.map +1 -1
  50. package/drag-drop/client-rect.d.ts +31 -0
  51. package/drag-drop/directives/config.d.ts +1 -0
  52. package/drag-drop/directives/drop-list.d.ts +4 -3
  53. package/drag-drop/drag-ref.d.ts +8 -2
  54. package/drag-drop/drop-list-ref.d.ts +9 -8
  55. package/drag-drop/index.metadata.json +1 -1
  56. package/drag-drop/parent-position-tracker.d.ts +31 -0
  57. package/drag-drop/public-api.d.ts +1 -1
  58. package/esm2015/a11y/aria-describer/aria-reference.js +6 -6
  59. package/esm2015/a11y/focus-monitor/focus-monitor.js +151 -82
  60. package/esm2015/a11y/high-contrast-mode/high-contrast-mode-detector.js +10 -6
  61. package/esm2015/drag-drop/client-rect.js +75 -0
  62. package/esm2015/drag-drop/directives/config.js +3 -1
  63. package/esm2015/drag-drop/directives/drag.js +3 -2
  64. package/esm2015/drag-drop/directives/drop-list.js +24 -18
  65. package/esm2015/drag-drop/drag-drop-module.js +3 -1
  66. package/esm2015/drag-drop/drag-ref.js +97 -43
  67. package/esm2015/drag-drop/drop-list-ref.js +119 -187
  68. package/esm2015/drag-drop/parent-position-tracker.js +141 -0
  69. package/esm2015/drag-drop/public-api.js +1 -1
  70. package/esm2015/overlay/keyboard/overlay-keyboard-dispatcher.js +2 -2
  71. package/esm2015/overlay/overlay-ref.js +3 -33
  72. package/esm2015/overlay/position/flexible-connected-position-strategy.js +1 -1
  73. package/esm2015/platform/features/shadow-dom.js +4 -2
  74. package/esm2015/scrolling/public-api.js +2 -2
  75. package/esm2015/scrolling/scrolling-module.js +15 -4
  76. package/esm2015/table/row.js +9 -1
  77. package/esm2015/testing/protractor/protractor-element.js +7 -3
  78. package/esm2015/testing/test-element.js +1 -1
  79. package/esm2015/testing/testbed/fake-events/dispatch-events.js +11 -4
  80. package/esm2015/testing/testbed/fake-events/event-objects.js +37 -3
  81. package/esm2015/testing/testbed/unit-test-element.js +17 -5
  82. package/esm2015/text-field/autosize.js +14 -5
  83. package/esm2015/tree/padding.js +9 -10
  84. package/esm2015/tree/tree.js +2 -1
  85. package/esm2015/version.js +1 -1
  86. package/esm5/a11y/aria-describer/aria-reference.js +6 -6
  87. package/esm5/a11y/focus-monitor/focus-monitor.js +105 -60
  88. package/esm5/a11y/high-contrast-mode/high-contrast-mode-detector.js +9 -6
  89. package/esm5/drag-drop/client-rect.js +60 -0
  90. package/esm5/drag-drop/directives/config.js +1 -1
  91. package/esm5/drag-drop/directives/drag.js +3 -2
  92. package/esm5/drag-drop/directives/drop-list.js +13 -10
  93. package/esm5/drag-drop/drag-drop-module.js +3 -1
  94. package/esm5/drag-drop/drag-ref.js +62 -33
  95. package/esm5/drag-drop/drop-list-ref.js +89 -139
  96. package/esm5/drag-drop/parent-position-tracker.js +74 -0
  97. package/esm5/drag-drop/public-api.js +1 -1
  98. package/esm5/overlay/keyboard/overlay-keyboard-dispatcher.js +2 -2
  99. package/esm5/overlay/overlay-ref.js +3 -13
  100. package/esm5/overlay/position/flexible-connected-position-strategy.js +1 -1
  101. package/esm5/platform/features/shadow-dom.js +4 -2
  102. package/esm5/scrolling/scrolling-module.js +19 -4
  103. package/esm5/table/row.js +9 -1
  104. package/esm5/testing/protractor/protractor-element.js +15 -11
  105. package/esm5/testing/test-element.js +1 -1
  106. package/esm5/testing/testbed/fake-events/dispatch-events.js +15 -7
  107. package/esm5/testing/testbed/fake-events/event-objects.js +43 -5
  108. package/esm5/testing/testbed/unit-test-element.js +19 -9
  109. package/esm5/text-field/autosize.js +8 -5
  110. package/esm5/tree/padding.js +9 -5
  111. package/esm5/tree/tree.js +2 -1
  112. package/esm5/version.js +1 -1
  113. package/fesm2015/a11y.js +188 -116
  114. package/fesm2015/a11y.js.map +1 -1
  115. package/fesm2015/cdk.js +1 -1
  116. package/fesm2015/cdk.js.map +1 -1
  117. package/fesm2015/drag-drop.js +448 -247
  118. package/fesm2015/drag-drop.js.map +1 -1
  119. package/fesm2015/overlay.js +3 -33
  120. package/fesm2015/overlay.js.map +1 -1
  121. package/fesm2015/platform.js +3 -1
  122. package/fesm2015/platform.js.map +1 -1
  123. package/fesm2015/scrolling.js +15 -4
  124. package/fesm2015/scrolling.js.map +1 -1
  125. package/fesm2015/table.js +8 -0
  126. package/fesm2015/table.js.map +1 -1
  127. package/fesm2015/testing/protractor.js +6 -2
  128. package/fesm2015/testing/protractor.js.map +1 -1
  129. package/fesm2015/testing/testbed.js +60 -7
  130. package/fesm2015/testing/testbed.js.map +1 -1
  131. package/fesm2015/testing.js.map +1 -1
  132. package/fesm2015/text-field.js +13 -4
  133. package/fesm2015/text-field.js.map +1 -1
  134. package/fesm2015/tree.js +9 -9
  135. package/fesm2015/tree.js.map +1 -1
  136. package/fesm5/a11y.js +134 -87
  137. package/fesm5/a11y.js.map +1 -1
  138. package/fesm5/cdk.js +1 -1
  139. package/fesm5/cdk.js.map +1 -1
  140. package/fesm5/drag-drop.js +294 -181
  141. package/fesm5/drag-drop.js.map +1 -1
  142. package/fesm5/overlay.js +3 -13
  143. package/fesm5/overlay.js.map +1 -1
  144. package/fesm5/platform.js +3 -1
  145. package/fesm5/platform.js.map +1 -1
  146. package/fesm5/scrolling.js +18 -4
  147. package/fesm5/scrolling.js.map +1 -1
  148. package/fesm5/table.js +8 -0
  149. package/fesm5/table.js.map +1 -1
  150. package/fesm5/testing/protractor.js +14 -10
  151. package/fesm5/testing/protractor.js.map +1 -1
  152. package/fesm5/testing/testbed.js +72 -17
  153. package/fesm5/testing/testbed.js.map +1 -1
  154. package/fesm5/testing.js.map +1 -1
  155. package/fesm5/text-field.js +7 -4
  156. package/fesm5/text-field.js.map +1 -1
  157. package/fesm5/tree.js +9 -4
  158. package/fesm5/tree.js.map +1 -1
  159. package/overlay/index.metadata.json +1 -1
  160. package/overlay/overlay-ref.d.ts +0 -3
  161. package/overlay/position/flexible-connected-position-strategy.d.ts +1 -1
  162. package/package.json +1 -1
  163. package/schematics/ng-add/index.js +1 -1
  164. package/schematics/ng-update/devkit-file-system.d.ts +29 -0
  165. package/schematics/ng-update/devkit-file-system.js +67 -0
  166. package/schematics/ng-update/devkit-migration-rule.d.ts +25 -0
  167. package/schematics/ng-update/devkit-migration-rule.js +152 -0
  168. package/schematics/ng-update/devkit-migration.d.ts +37 -0
  169. package/schematics/ng-update/devkit-migration.js +29 -0
  170. package/schematics/ng-update/index.js +7 -7
  171. package/schematics/ng-update/{upgrade-rules/attribute-selectors-rule.d.ts → migrations/attribute-selectors.d.ts} +6 -6
  172. package/schematics/ng-update/migrations/attribute-selectors.js +76 -0
  173. package/schematics/ng-update/{upgrade-rules/class-inheritance-rule.d.ts → migrations/class-inheritance.d.ts} +6 -6
  174. package/schematics/ng-update/migrations/class-inheritance.js +67 -0
  175. package/schematics/ng-update/{upgrade-rules/class-names-rule.d.ts → migrations/class-names.d.ts} +6 -6
  176. package/schematics/ng-update/migrations/class-names.js +98 -0
  177. package/schematics/ng-update/{upgrade-rules/constructor-signature-rule.d.ts → migrations/constructor-signature.d.ts} +6 -6
  178. package/schematics/ng-update/migrations/constructor-signature.js +144 -0
  179. package/schematics/ng-update/{upgrade-rules/css-selectors-rule.d.ts → migrations/css-selectors.d.ts} +6 -6
  180. package/schematics/ng-update/migrations/css-selectors.js +83 -0
  181. package/schematics/ng-update/{upgrade-rules/element-selectors-rule.d.ts → migrations/element-selectors.d.ts} +6 -6
  182. package/schematics/ng-update/migrations/element-selectors.js +74 -0
  183. package/schematics/ng-update/{upgrade-rules/input-names-rule.d.ts → migrations/input-names.d.ts} +6 -6
  184. package/schematics/ng-update/migrations/input-names.js +69 -0
  185. package/schematics/ng-update/{upgrade-rules/method-call-arguments-rule.d.ts → migrations/method-call-arguments.d.ts} +6 -6
  186. package/schematics/ng-update/migrations/method-call-arguments.js +70 -0
  187. package/schematics/ng-update/{upgrade-rules/misc-template-rule.d.ts → migrations/misc-template.d.ts} +6 -6
  188. package/schematics/ng-update/migrations/misc-template.js +47 -0
  189. package/schematics/ng-update/{upgrade-rules/output-names-rule.d.ts → migrations/output-names.d.ts} +6 -6
  190. package/schematics/ng-update/migrations/output-names.js +56 -0
  191. package/schematics/ng-update/{upgrade-rules/property-names-rule.d.ts → migrations/property-names.d.ts} +6 -6
  192. package/schematics/ng-update/migrations/property-names.js +56 -0
  193. package/schematics/ng-update/public-api.d.ts +3 -2
  194. package/schematics/ng-update/public-api.js +5 -4
  195. package/schematics/ng-update/upgrade-data.d.ts +7 -8
  196. package/schematics/ng-update/upgrade-data.js +6 -7
  197. package/schematics/update-tool/component-resource-collector.d.ts +3 -1
  198. package/schematics/update-tool/component-resource-collector.js +8 -8
  199. package/schematics/update-tool/file-system.d.ts +38 -0
  200. package/schematics/update-tool/file-system.js +20 -0
  201. package/schematics/update-tool/index.d.ts +41 -11
  202. package/schematics/update-tool/index.js +135 -106
  203. package/schematics/update-tool/logger.d.ts +16 -0
  204. package/schematics/update-tool/logger.js +27 -0
  205. package/schematics/update-tool/{migration-rule.d.ts → migration.d.ts} +23 -45
  206. package/schematics/update-tool/migration.js +76 -0
  207. package/schematics/update-tool/public-api.d.ts +5 -4
  208. package/schematics/update-tool/public-api.js +6 -6
  209. package/schematics/update-tool/update-recorder.d.ts +14 -0
  210. package/schematics/update-tool/update-recorder.js +20 -0
  211. package/schematics/update-tool/utils/parse-tsconfig.js +1 -1
  212. package/schematics/update-tool/version-changes.js +3 -4
  213. package/schematics/utils/build-component.js +15 -4
  214. package/scrolling/index.metadata.json +1 -1
  215. package/scrolling/scrolling-module.d.ts +2 -0
  216. package/table/index.metadata.json +1 -1
  217. package/testing/protractor/protractor-element.d.ts +1 -1
  218. package/testing/test-element.d.ts +4 -2
  219. package/testing/testbed/fake-events/dispatch-events.d.ts +8 -3
  220. package/testing/testbed/fake-events/event-objects.d.ts +12 -1
  221. package/testing/testbed/unit-test-element.d.ts +1 -1
  222. package/text-field/_text-field.scss +19 -4
  223. package/text-field/autosize.d.ts +2 -0
  224. package/text-field/index.metadata.json +1 -1
  225. package/text-field-prebuilt.css +1 -1
  226. package/tree/index.metadata.json +1 -1
  227. package/tree/padding.d.ts +6 -2
  228. package/schematics/ng-update/upgrade-rules/attribute-selectors-rule.js +0 -76
  229. package/schematics/ng-update/upgrade-rules/class-inheritance-rule.js +0 -67
  230. package/schematics/ng-update/upgrade-rules/class-names-rule.js +0 -98
  231. package/schematics/ng-update/upgrade-rules/constructor-signature-rule.js +0 -144
  232. package/schematics/ng-update/upgrade-rules/css-selectors-rule.js +0 -83
  233. package/schematics/ng-update/upgrade-rules/element-selectors-rule.js +0 -74
  234. package/schematics/ng-update/upgrade-rules/index.d.ts +0 -22
  235. package/schematics/ng-update/upgrade-rules/index.js +0 -116
  236. package/schematics/ng-update/upgrade-rules/input-names-rule.js +0 -69
  237. package/schematics/ng-update/upgrade-rules/method-call-arguments-rule.js +0 -70
  238. package/schematics/ng-update/upgrade-rules/misc-template-rule.js +0 -47
  239. package/schematics/ng-update/upgrade-rules/output-names-rule.js +0 -56
  240. package/schematics/ng-update/upgrade-rules/property-names-rule.js +0 -56
  241. package/schematics/update-tool/migration-rule.js +0 -101
@@ -11,8 +11,8 @@
11
11
  * Use of this source code is governed by an MIT-style license that can be
12
12
  * found in the LICENSE file at https://angular.io/license
13
13
  */
14
- /** IDs are deliminated by an empty space, as per the spec. */
15
- var ID_DELIMINATOR = ' ';
14
+ /** IDs are delimited by an empty space, as per the spec. */
15
+ var ID_DELIMITER = ' ';
16
16
  /**
17
17
  * Adds the given ID to the specified ARIA attribute on an element.
18
18
  * Used for attributes such as aria-labelledby, aria-owns, etc.
@@ -23,7 +23,7 @@
23
23
  return;
24
24
  }
25
25
  ids.push(id.trim());
26
- el.setAttribute(attr, ids.join(ID_DELIMINATOR));
26
+ el.setAttribute(attr, ids.join(ID_DELIMITER));
27
27
  }
28
28
  /**
29
29
  * Removes the given ID from the specified ARIA attribute on an element.
@@ -33,7 +33,7 @@
33
33
  var ids = getAriaReferenceIds(el, attr);
34
34
  var filteredIds = ids.filter(function (val) { return val != id.trim(); });
35
35
  if (filteredIds.length) {
36
- el.setAttribute(attr, filteredIds.join(ID_DELIMINATOR));
36
+ el.setAttribute(attr, filteredIds.join(ID_DELIMITER));
37
37
  }
38
38
  else {
39
39
  el.removeAttribute(attr);
@@ -44,7 +44,7 @@
44
44
  * Used for attributes such as aria-labelledby, aria-owns, etc.
45
45
  */
46
46
  function getAriaReferenceIds(el, attr) {
47
- // Get string array of all individual ids (whitespace deliminated) in the attribute value
47
+ // Get string array of all individual ids (whitespace delimited) in the attribute value
48
48
  return (el.getAttribute(attr) || '').match(/\S+/g) || [];
49
49
  }
50
50
 
@@ -1881,6 +1881,24 @@
1881
1881
  return CdkAriaLive;
1882
1882
  }());
1883
1883
 
1884
+ /**
1885
+ * @license
1886
+ * Copyright Google LLC All Rights Reserved.
1887
+ *
1888
+ * Use of this source code is governed by an MIT-style license that can be
1889
+ * found in the LICENSE file at https://angular.io/license
1890
+ */
1891
+ /**
1892
+ * Screenreaders will often fire fake mousedown events when a focusable element
1893
+ * is activated using the keyboard. We can typically distinguish between these faked
1894
+ * mousedown events and real mousedown events using the "buttons" property. While
1895
+ * real mousedowns will indicate the mouse button that was pressed (e.g. "1" for
1896
+ * the left mouse button), faked mousedowns will usually set the property value to 0.
1897
+ */
1898
+ function isFakeMousedownFromScreenReader(event) {
1899
+ return event.buttons === 0;
1900
+ }
1901
+
1884
1902
  /**
1885
1903
  * @license
1886
1904
  * Copyright Google LLC All Rights Reserved.
@@ -1917,6 +1935,13 @@
1917
1935
  this._elementInfo = new Map();
1918
1936
  /** The number of elements currently being monitored. */
1919
1937
  this._monitoredElementCount = 0;
1938
+ /**
1939
+ * Keeps track of the root nodes to which we've currently bound a focus/blur handler,
1940
+ * as well as the number of monitored elements that they contain. We have to treat focus/blur
1941
+ * handlers differently from the rest of the events, because the browser won't emit events
1942
+ * to the document when focus moves inside of a shadow root.
1943
+ */
1944
+ this._rootNodeFocusListenerCount = new Map();
1920
1945
  /**
1921
1946
  * Event listener for `keydown` events on the document.
1922
1947
  * Needs to be an arrow function in order to preserve the context when it gets bound.
@@ -1930,11 +1955,14 @@
1930
1955
  * Event listener for `mousedown` events on the document.
1931
1956
  * Needs to be an arrow function in order to preserve the context when it gets bound.
1932
1957
  */
1933
- this._documentMousedownListener = function () {
1958
+ this._documentMousedownListener = function (event) {
1934
1959
  // On mousedown record the origin only if there is not touch
1935
1960
  // target, since a mousedown can happen as a result of a touch event.
1936
1961
  if (!_this._lastTouchTarget) {
1937
- _this._setOriginForCurrentEventQueue('mouse');
1962
+ // In some cases screen readers fire fake `mousedown` events instead of `keydown`.
1963
+ // Resolve the focus source to `keyboard` if we detect one of them.
1964
+ var source = isFakeMousedownFromScreenReader(event) ? 'keyboard' : 'mouse';
1965
+ _this._setOriginForCurrentEventQueue(source);
1938
1966
  }
1939
1967
  };
1940
1968
  /**
@@ -1948,10 +1976,7 @@
1948
1976
  if (_this._touchTimeoutId != null) {
1949
1977
  clearTimeout(_this._touchTimeoutId);
1950
1978
  }
1951
- // Since this listener is bound on the `document` level, any events coming from the shadow DOM
1952
- // will have their `target` set to the shadow root. If available, use `composedPath` to
1953
- // figure out the event target.
1954
- _this._lastTouchTarget = event.composedPath ? event.composedPath()[0] : event.target;
1979
+ _this._lastTouchTarget = getTarget(event);
1955
1980
  _this._touchTimeoutId = setTimeout(function () { return _this._lastTouchTarget = null; }, TOUCH_BUFFER_MS);
1956
1981
  };
1957
1982
  /**
@@ -1964,54 +1989,61 @@
1964
1989
  _this._windowFocused = true;
1965
1990
  _this._windowFocusTimeoutId = setTimeout(function () { return _this._windowFocused = false; });
1966
1991
  };
1992
+ /**
1993
+ * Event listener for `focus` and 'blur' events on the document.
1994
+ * Needs to be an arrow function in order to preserve the context when it gets bound.
1995
+ */
1996
+ this._rootNodeFocusAndBlurListener = function (event) {
1997
+ var target = getTarget(event);
1998
+ var handler = event.type === 'focus' ? _this._onFocus : _this._onBlur;
1999
+ // We need to walk up the ancestor chain in order to support `checkChildren`.
2000
+ for (var element = target; element; element = element.parentElement) {
2001
+ handler.call(_this, event, element);
2002
+ }
2003
+ };
1967
2004
  this._document = document;
1968
2005
  this._detectionMode = (options === null || options === void 0 ? void 0 : options.detectionMode) || 0 /* IMMEDIATE */;
1969
2006
  }
1970
2007
  FocusMonitor.prototype.monitor = function (element, checkChildren) {
1971
- var _this = this;
1972
2008
  if (checkChildren === void 0) { checkChildren = false; }
1973
2009
  // Do nothing if we're not on the browser platform.
1974
2010
  if (!this._platform.isBrowser) {
1975
2011
  return rxjs.of(null);
1976
2012
  }
1977
2013
  var nativeElement = coercion.coerceElement(element);
2014
+ // If the element is inside the shadow DOM, we need to bind our focus/blur listeners to
2015
+ // the shadow root, rather than the `document`, because the browser won't emit focus events
2016
+ // to the `document`, if focus is moving within the same shadow root.
2017
+ var rootNode = i1._getShadowRoot(nativeElement) || this._getDocument();
2018
+ var cachedInfo = this._elementInfo.get(nativeElement);
1978
2019
  // Check if we're already monitoring this element.
1979
- if (this._elementInfo.has(nativeElement)) {
1980
- var cachedInfo = this._elementInfo.get(nativeElement);
1981
- cachedInfo.checkChildren = checkChildren;
2020
+ if (cachedInfo) {
2021
+ if (checkChildren) {
2022
+ // TODO(COMP-318): this can be problematic, because it'll turn all non-checkChildren
2023
+ // observers into ones that behave as if `checkChildren` was turned on. We need a more
2024
+ // robust solution.
2025
+ cachedInfo.checkChildren = true;
2026
+ }
1982
2027
  return cachedInfo.subject.asObservable();
1983
2028
  }
1984
2029
  // Create monitored element info.
1985
2030
  var info = {
1986
- unlisten: function () { },
1987
2031
  checkChildren: checkChildren,
1988
- subject: new rxjs.Subject()
2032
+ subject: new rxjs.Subject(),
2033
+ rootNode: rootNode
1989
2034
  };
1990
2035
  this._elementInfo.set(nativeElement, info);
1991
- this._incrementMonitoredElementCount();
1992
- // Start listening. We need to listen in capture phase since focus events don't bubble.
1993
- var focusListener = function (event) { return _this._onFocus(event, nativeElement); };
1994
- var blurListener = function (event) { return _this._onBlur(event, nativeElement); };
1995
- this._ngZone.runOutsideAngular(function () {
1996
- nativeElement.addEventListener('focus', focusListener, true);
1997
- nativeElement.addEventListener('blur', blurListener, true);
1998
- });
1999
- // Create an unlisten function for later.
2000
- info.unlisten = function () {
2001
- nativeElement.removeEventListener('focus', focusListener, true);
2002
- nativeElement.removeEventListener('blur', blurListener, true);
2003
- };
2036
+ this._registerGlobalListeners(info);
2004
2037
  return info.subject.asObservable();
2005
2038
  };
2006
2039
  FocusMonitor.prototype.stopMonitoring = function (element) {
2007
2040
  var nativeElement = coercion.coerceElement(element);
2008
2041
  var elementInfo = this._elementInfo.get(nativeElement);
2009
2042
  if (elementInfo) {
2010
- elementInfo.unlisten();
2011
2043
  elementInfo.subject.complete();
2012
2044
  this._setClasses(nativeElement);
2013
2045
  this._elementInfo.delete(nativeElement);
2014
- this._decrementMonitoredElementCount();
2046
+ this._removeGlobalListeners(elementInfo);
2015
2047
  }
2016
2048
  };
2017
2049
  FocusMonitor.prototype.focusVia = function (element, origin, options) {
@@ -2044,20 +2076,37 @@
2044
2076
  element.classList.remove(className);
2045
2077
  }
2046
2078
  };
2079
+ FocusMonitor.prototype._getFocusOrigin = function (event) {
2080
+ // If we couldn't detect a cause for the focus event, it's due to one of three reasons:
2081
+ // 1) The window has just regained focus, in which case we want to restore the focused state of
2082
+ // the element from before the window blurred.
2083
+ // 2) It was caused by a touch event, in which case we mark the origin as 'touch'.
2084
+ // 3) The element was programmatically focused, in which case we should mark the origin as
2085
+ // 'program'.
2086
+ if (this._origin) {
2087
+ return this._origin;
2088
+ }
2089
+ if (this._windowFocused && this._lastFocusOrigin) {
2090
+ return this._lastFocusOrigin;
2091
+ }
2092
+ else if (this._wasCausedByTouch(event)) {
2093
+ return 'touch';
2094
+ }
2095
+ else {
2096
+ return 'program';
2097
+ }
2098
+ };
2047
2099
  /**
2048
2100
  * Sets the focus classes on the element based on the given focus origin.
2049
2101
  * @param element The element to update the classes on.
2050
2102
  * @param origin The focus origin.
2051
2103
  */
2052
2104
  FocusMonitor.prototype._setClasses = function (element, origin) {
2053
- var elementInfo = this._elementInfo.get(element);
2054
- if (elementInfo) {
2055
- this._toggleClass(element, 'cdk-focused', !!origin);
2056
- this._toggleClass(element, 'cdk-touch-focused', origin === 'touch');
2057
- this._toggleClass(element, 'cdk-keyboard-focused', origin === 'keyboard');
2058
- this._toggleClass(element, 'cdk-mouse-focused', origin === 'mouse');
2059
- this._toggleClass(element, 'cdk-program-focused', origin === 'program');
2060
- }
2105
+ this._toggleClass(element, 'cdk-focused', !!origin);
2106
+ this._toggleClass(element, 'cdk-touch-focused', origin === 'touch');
2107
+ this._toggleClass(element, 'cdk-keyboard-focused', origin === 'keyboard');
2108
+ this._toggleClass(element, 'cdk-mouse-focused', origin === 'mouse');
2109
+ this._toggleClass(element, 'cdk-program-focused', origin === 'program');
2061
2110
  };
2062
2111
  /**
2063
2112
  * Sets the origin and schedules an async function to clear it at the end of the event queue.
@@ -2099,7 +2148,7 @@
2099
2148
  // for the first focus event after the touchstart, and then the first blur event after that
2100
2149
  // focus event. When that blur event fires we know that whatever follows is not a result of the
2101
2150
  // touchstart.
2102
- var focusTarget = event.target;
2151
+ var focusTarget = getTarget(event);
2103
2152
  return this._lastTouchTarget instanceof Node && focusTarget instanceof Node &&
2104
2153
  (focusTarget === this._lastTouchTarget || focusTarget.contains(this._lastTouchTarget));
2105
2154
  };
@@ -2116,27 +2165,10 @@
2116
2165
  // If we are not counting child-element-focus as focused, make sure that the event target is the
2117
2166
  // monitored element itself.
2118
2167
  var elementInfo = this._elementInfo.get(element);
2119
- if (!elementInfo || (!elementInfo.checkChildren && element !== event.target)) {
2168
+ if (!elementInfo || (!elementInfo.checkChildren && element !== getTarget(event))) {
2120
2169
  return;
2121
2170
  }
2122
- // If we couldn't detect a cause for the focus event, it's due to one of three reasons:
2123
- // 1) The window has just regained focus, in which case we want to restore the focused state of
2124
- // the element from before the window blurred.
2125
- // 2) It was caused by a touch event, in which case we mark the origin as 'touch'.
2126
- // 3) The element was programmatically focused, in which case we should mark the origin as
2127
- // 'program'.
2128
- var origin = this._origin;
2129
- if (!origin) {
2130
- if (this._windowFocused && this._lastFocusOrigin) {
2131
- origin = this._lastFocusOrigin;
2132
- }
2133
- else if (this._wasCausedByTouch(event)) {
2134
- origin = 'touch';
2135
- }
2136
- else {
2137
- origin = 'program';
2138
- }
2139
- }
2171
+ var origin = this._getFocusOrigin(event);
2140
2172
  this._setClasses(element, origin);
2141
2173
  this._emitOrigin(elementInfo.subject, origin);
2142
2174
  this._lastFocusOrigin = origin;
@@ -2160,10 +2192,22 @@
2160
2192
  FocusMonitor.prototype._emitOrigin = function (subject, origin) {
2161
2193
  this._ngZone.run(function () { return subject.next(origin); });
2162
2194
  };
2163
- FocusMonitor.prototype._incrementMonitoredElementCount = function () {
2195
+ FocusMonitor.prototype._registerGlobalListeners = function (elementInfo) {
2164
2196
  var _this = this;
2197
+ if (!this._platform.isBrowser) {
2198
+ return;
2199
+ }
2200
+ var rootNode = elementInfo.rootNode;
2201
+ var rootNodeFocusListeners = this._rootNodeFocusListenerCount.get(rootNode) || 0;
2202
+ if (!rootNodeFocusListeners) {
2203
+ this._ngZone.runOutsideAngular(function () {
2204
+ rootNode.addEventListener('focus', _this._rootNodeFocusAndBlurListener, captureEventListenerOptions);
2205
+ rootNode.addEventListener('blur', _this._rootNodeFocusAndBlurListener, captureEventListenerOptions);
2206
+ });
2207
+ }
2208
+ this._rootNodeFocusListenerCount.set(rootNode, rootNodeFocusListeners + 1);
2165
2209
  // Register global listeners when first element is monitored.
2166
- if (++this._monitoredElementCount == 1 && this._platform.isBrowser) {
2210
+ if (++this._monitoredElementCount === 1) {
2167
2211
  // Note: we listen to events in the capture phase so we
2168
2212
  // can detect them even if the user stops propagation.
2169
2213
  this._ngZone.runOutsideAngular(function () {
@@ -2176,7 +2220,19 @@
2176
2220
  });
2177
2221
  }
2178
2222
  };
2179
- FocusMonitor.prototype._decrementMonitoredElementCount = function () {
2223
+ FocusMonitor.prototype._removeGlobalListeners = function (elementInfo) {
2224
+ var rootNode = elementInfo.rootNode;
2225
+ if (this._rootNodeFocusListenerCount.has(rootNode)) {
2226
+ var rootNodeFocusListeners = this._rootNodeFocusListenerCount.get(rootNode);
2227
+ if (rootNodeFocusListeners > 1) {
2228
+ this._rootNodeFocusListenerCount.set(rootNode, rootNodeFocusListeners - 1);
2229
+ }
2230
+ else {
2231
+ rootNode.removeEventListener('focus', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);
2232
+ rootNode.removeEventListener('blur', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);
2233
+ this._rootNodeFocusListenerCount.delete(rootNode);
2234
+ }
2235
+ }
2180
2236
  // Unregister global listeners when last element is unmonitored.
2181
2237
  if (!--this._monitoredElementCount) {
2182
2238
  var document_1 = this._getDocument();
@@ -2204,6 +2260,12 @@
2204
2260
  FocusMonitor.ɵprov = i0.ɵɵdefineInjectable({ factory: function FocusMonitor_Factory() { return new FocusMonitor(i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(i1.Platform), i0.ɵɵinject(i2.DOCUMENT, 8), i0.ɵɵinject(FOCUS_MONITOR_DEFAULT_OPTIONS, 8)); }, token: FocusMonitor, providedIn: "root" });
2205
2261
  return FocusMonitor;
2206
2262
  }());
2263
+ /** Gets the target of an event, accounting for Shadow DOM. */
2264
+ function getTarget(event) {
2265
+ // If an event is bound outside the Shadow DOM, the `event.target` will
2266
+ // point to the shadow root so we have to use `composedPath` instead.
2267
+ return (event.composedPath ? event.composedPath()[0] : event.target);
2268
+ }
2207
2269
  /**
2208
2270
  * Directive that determines how a particular element was focused (via keyboard, mouse, touch, or
2209
2271
  * programmatically) and adds corresponding classes to the element.
@@ -2242,24 +2304,6 @@
2242
2304
  return CdkMonitorFocus;
2243
2305
  }());
2244
2306
 
2245
- /**
2246
- * @license
2247
- * Copyright Google LLC All Rights Reserved.
2248
- *
2249
- * Use of this source code is governed by an MIT-style license that can be
2250
- * found in the LICENSE file at https://angular.io/license
2251
- */
2252
- /**
2253
- * Screenreaders will often fire fake mousedown events when a focusable element
2254
- * is activated using the keyboard. We can typically distinguish between these faked
2255
- * mousedown events and real mousedown events using the "buttons" property. While
2256
- * real mousedowns will indicate the mouse button that was pressed (e.g. "1" for
2257
- * the left mouse button), faked mousedowns will usually set the property value to 0.
2258
- */
2259
- function isFakeMousedownFromScreenReader(event) {
2260
- return event.buttons === 0;
2261
- }
2262
-
2263
2307
  /**
2264
2308
  * @license
2265
2309
  * Copyright Google LLC All Rights Reserved.
@@ -2274,7 +2318,7 @@
2274
2318
  /** CSS class applied to the document body when in high-contrast mode. */
2275
2319
  var HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS = 'cdk-high-contrast-active';
2276
2320
  /**
2277
- * Service to determine whether the browser is currently in a high-constrast-mode environment.
2321
+ * Service to determine whether the browser is currently in a high-contrast-mode environment.
2278
2322
  *
2279
2323
  * Microsoft Windows supports an accessibility feature called "High Contrast Mode". This mode
2280
2324
  * changes the appearance of all applications, including web applications, to dramatically increase
@@ -2289,7 +2333,7 @@
2289
2333
  this._platform = _platform;
2290
2334
  this._document = document;
2291
2335
  }
2292
- /** Gets the current high-constrast-mode for the page. */
2336
+ /** Gets the current high-contrast-mode for the page. */
2293
2337
  HighContrastModeDetector.prototype.getHighContrastMode = function () {
2294
2338
  if (!this._platform.isBrowser) {
2295
2339
  return 0 /* NONE */;
@@ -2303,9 +2347,12 @@
2303
2347
  this._document.body.appendChild(testElement);
2304
2348
  // Get the computed style for the background color, collapsing spaces to normalize between
2305
2349
  // browsers. Once we get this color, we no longer need the test element. Access the `window`
2306
- // via the document so we can fake it in tests.
2307
- var documentWindow = this._document.defaultView;
2308
- var computedColor = (documentWindow.getComputedStyle(testElement).backgroundColor || '').replace(/ /g, '');
2350
+ // via the document so we can fake it in tests. Note that we have extra null checks, because
2351
+ // this logic will likely run during app bootstrap and throwing can break the entire app.
2352
+ var documentWindow = this._document.defaultView || window;
2353
+ var computedStyle = (documentWindow && documentWindow.getComputedStyle) ?
2354
+ documentWindow.getComputedStyle(testElement) : null;
2355
+ var computedColor = (computedStyle && computedStyle.backgroundColor || '').replace(/ /g, '');
2309
2356
  this._document.body.removeChild(testElement);
2310
2357
  switch (computedColor) {
2311
2358
  case 'rgb(0,0,0)': return 2 /* WHITE_ON_BLACK */;