@angular/cdk 16.0.0-next.4 → 16.0.0-rc.0

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 (454) hide show
  1. package/a11y/index.d.ts +2 -2
  2. package/accordion/index.d.ts +2 -2
  3. package/bidi/index.d.ts +1 -1
  4. package/clipboard/index.d.ts +1 -1
  5. package/drag-drop/index.d.ts +6 -6
  6. package/{esm2020 → esm2022}/a11y/a11y-module.mjs +5 -5
  7. package/{esm2020 → esm2022}/a11y/aria-describer/aria-describer.mjs +4 -4
  8. package/{esm2020 → esm2022}/a11y/focus-monitor/focus-monitor.mjs +7 -7
  9. package/{esm2020 → esm2022}/a11y/focus-trap/configurable-focus-trap-factory.mjs +4 -4
  10. package/{esm2020 → esm2022}/a11y/focus-trap/focus-trap-manager.mjs +4 -4
  11. package/{esm2020 → esm2022}/a11y/focus-trap/focus-trap.mjs +7 -7
  12. package/{esm2020 → esm2022}/a11y/high-contrast-mode/high-contrast-mode-detector.mjs +4 -4
  13. package/{esm2020 → esm2022}/a11y/input-modality/input-modality-detector.mjs +4 -4
  14. package/{esm2020 → esm2022}/a11y/interactivity-checker/interactivity-checker.mjs +4 -4
  15. package/{esm2020 → esm2022}/a11y/live-announcer/live-announcer.mjs +7 -7
  16. package/{esm2020 → esm2022}/accordion/accordion-item.mjs +8 -8
  17. package/{esm2020 → esm2022}/accordion/accordion-module.mjs +5 -5
  18. package/{esm2020 → esm2022}/accordion/accordion.mjs +4 -4
  19. package/{esm2020 → esm2022}/bidi/bidi-module.mjs +5 -5
  20. package/{esm2020 → esm2022}/bidi/dir.mjs +4 -4
  21. package/{esm2020 → esm2022}/bidi/directionality.mjs +4 -4
  22. package/{esm2020 → esm2022}/clipboard/clipboard-module.mjs +5 -5
  23. package/{esm2020 → esm2022}/clipboard/clipboard.mjs +4 -4
  24. package/{esm2020 → esm2022}/clipboard/copy-to-clipboard.mjs +4 -4
  25. package/{esm2020 → esm2022}/collections/unique-selection-dispatcher.mjs +4 -4
  26. package/{esm2020 → esm2022}/dialog/dialog-container.mjs +4 -4
  27. package/{esm2020 → esm2022}/dialog/dialog-module.mjs +12 -12
  28. package/{esm2020 → esm2022}/dialog/dialog.mjs +4 -4
  29. package/{esm2020 → esm2022}/drag-drop/directives/drag-handle.mjs +4 -4
  30. package/{esm2020 → esm2022}/drag-drop/directives/drag-placeholder.mjs +4 -4
  31. package/{esm2020 → esm2022}/drag-drop/directives/drag-preview.mjs +4 -4
  32. package/esm2022/drag-drop/directives/drag.mjs +489 -0
  33. package/{esm2020 → esm2022}/drag-drop/directives/drop-list-group.mjs +4 -4
  34. package/esm2022/drag-drop/directives/drop-list.mjs +348 -0
  35. package/{esm2020 → esm2022}/drag-drop/drag-drop-module.mjs +15 -15
  36. package/{esm2020 → esm2022}/drag-drop/drag-drop-registry.mjs +4 -4
  37. package/{esm2020 → esm2022}/drag-drop/drag-drop.mjs +4 -4
  38. package/{esm2020 → esm2022}/layout/breakpoints-observer.mjs +4 -4
  39. package/{esm2020 → esm2022}/layout/layout-module.mjs +5 -5
  40. package/{esm2020 → esm2022}/layout/media-matcher.mjs +4 -4
  41. package/{esm2020 → esm2022}/listbox/listbox-module.mjs +5 -5
  42. package/{esm2020 → esm2022}/listbox/listbox.mjs +13 -13
  43. package/{esm2020 → esm2022}/menu/context-menu-trigger.mjs +10 -10
  44. package/{esm2020 → esm2022}/menu/menu-aim.mjs +7 -7
  45. package/{esm2020 → esm2022}/menu/menu-bar.mjs +8 -8
  46. package/{esm2020 → esm2022}/menu/menu-base.mjs +4 -4
  47. package/{esm2020 → esm2022}/menu/menu-group.mjs +4 -4
  48. package/{esm2020 → esm2022}/menu/menu-item-checkbox.mjs +7 -7
  49. package/{esm2020 → esm2022}/menu/menu-item-radio.mjs +7 -7
  50. package/{esm2020 → esm2022}/menu/menu-item-selectable.mjs +4 -4
  51. package/{esm2020 → esm2022}/menu/menu-item.mjs +4 -4
  52. package/{esm2020 → esm2022}/menu/menu-module.mjs +21 -21
  53. package/{esm2020 → esm2022}/menu/menu-stack.mjs +4 -4
  54. package/{esm2020 → esm2022}/menu/menu-trigger-base.mjs +4 -4
  55. package/esm2022/menu/menu-trigger.mjs +307 -0
  56. package/{esm2020 → esm2022}/menu/menu.mjs +8 -8
  57. package/{esm2020 → esm2022}/observers/observe-content.mjs +14 -14
  58. package/{esm2020 → esm2022}/overlay/dispatchers/base-overlay-dispatcher.mjs +4 -4
  59. package/{esm2020 → esm2022}/overlay/dispatchers/overlay-keyboard-dispatcher.mjs +4 -4
  60. package/{esm2020 → esm2022}/overlay/dispatchers/overlay-outside-click-dispatcher.mjs +4 -4
  61. package/{esm2020 → esm2022}/overlay/fullscreen-overlay-container.mjs +4 -4
  62. package/{esm2020 → esm2022}/overlay/overlay-container.mjs +4 -4
  63. package/{esm2020 → esm2022}/overlay/overlay-directives.mjs +7 -7
  64. package/{esm2020 → esm2022}/overlay/overlay-module.mjs +5 -5
  65. package/{esm2020 → esm2022}/overlay/overlay.mjs +4 -4
  66. package/{esm2020 → esm2022}/overlay/position/overlay-position-builder.mjs +4 -4
  67. package/{esm2020 → esm2022}/overlay/scroll/scroll-strategy-options.mjs +4 -4
  68. package/{esm2020 → esm2022}/platform/platform-module.mjs +5 -5
  69. package/{esm2020 → esm2022}/platform/platform.mjs +4 -4
  70. package/esm2022/portal/portal-directives.mjs +250 -0
  71. package/{esm2020 → esm2022}/scrolling/fixed-size-virtual-scroll.mjs +10 -10
  72. package/{esm2020 → esm2022}/scrolling/scroll-dispatcher.mjs +4 -4
  73. package/{esm2020 → esm2022}/scrolling/scrollable.mjs +4 -4
  74. package/{esm2020 → esm2022}/scrolling/scrolling-module.mjs +19 -19
  75. package/{esm2020 → esm2022}/scrolling/viewport-ruler.mjs +4 -4
  76. package/{esm2020 → esm2022}/scrolling/virtual-for-of.mjs +4 -4
  77. package/{esm2020 → esm2022}/scrolling/virtual-scroll-viewport.mjs +10 -10
  78. package/{esm2020 → esm2022}/scrolling/virtual-scrollable-element.mjs +4 -4
  79. package/{esm2020 → esm2022}/scrolling/virtual-scrollable-window.mjs +4 -4
  80. package/{esm2020 → esm2022}/scrolling/virtual-scrollable.mjs +4 -4
  81. package/{esm2020 → esm2022}/stepper/step-header.mjs +4 -4
  82. package/{esm2020 → esm2022}/stepper/step-label.mjs +4 -4
  83. package/{esm2020 → esm2022}/stepper/stepper-button.mjs +7 -7
  84. package/{esm2020 → esm2022}/stepper/stepper-module.mjs +10 -10
  85. package/{esm2020 → esm2022}/stepper/stepper.mjs +7 -7
  86. package/{esm2020 → esm2022}/table/cell.mjs +22 -22
  87. package/{esm2020 → esm2022}/table/coalesced-style-scheduler.mjs +4 -4
  88. package/esm2022/table/row.mjs +271 -0
  89. package/{esm2020 → esm2022}/table/table-module.mjs +47 -47
  90. package/{esm2020 → esm2022}/table/table.mjs +25 -25
  91. package/{esm2020 → esm2022}/table/text-column.mjs +6 -6
  92. package/{esm2020 → esm2022}/text-field/autofill.mjs +7 -7
  93. package/{esm2020 → esm2022}/text-field/autosize.mjs +4 -4
  94. package/{esm2020 → esm2022}/text-field/text-field-module.mjs +5 -5
  95. package/{esm2020 → esm2022}/tree/nested-node.mjs +7 -7
  96. package/{esm2020 → esm2022}/tree/node.mjs +4 -4
  97. package/{esm2020 → esm2022}/tree/outlet.mjs +4 -4
  98. package/{esm2020 → esm2022}/tree/padding.mjs +4 -4
  99. package/{esm2020 → esm2022}/tree/toggle.mjs +4 -4
  100. package/{esm2020 → esm2022}/tree/tree-module.mjs +17 -17
  101. package/esm2022/tree/tree.mjs +349 -0
  102. package/{esm2020 → esm2022}/version.mjs +1 -1
  103. package/{fesm2020 → fesm2022}/a11y.mjs +40 -197
  104. package/fesm2022/a11y.mjs.map +1 -0
  105. package/{fesm2020 → fesm2022}/accordion.mjs +14 -51
  106. package/fesm2022/accordion.mjs.map +1 -0
  107. package/{fesm2020 → fesm2022}/bidi.mjs +10 -54
  108. package/fesm2022/bidi.mjs.map +1 -0
  109. package/fesm2022/cdk.mjs +7 -0
  110. package/fesm2022/cdk.mjs.map +1 -0
  111. package/{fesm2020 → fesm2022}/clipboard.mjs +10 -54
  112. package/fesm2022/clipboard.mjs.map +1 -0
  113. package/{fesm2015 → fesm2022}/coercion.mjs +0 -58
  114. package/fesm2022/coercion.mjs.map +1 -0
  115. package/{fesm2015 → fesm2022}/collections.mjs +5 -70
  116. package/fesm2022/collections.mjs.map +1 -0
  117. package/{fesm2020 → fesm2022}/dialog.mjs +17 -75
  118. package/fesm2022/dialog.mjs.map +1 -0
  119. package/{fesm2020 → fesm2022}/drag-drop.mjs +45 -216
  120. package/fesm2022/drag-drop.mjs.map +1 -0
  121. package/{fesm2020 → fesm2022}/keycodes.mjs +0 -30
  122. package/fesm2022/keycodes.mjs.map +1 -0
  123. package/{fesm2015 → fesm2022}/layout.mjs +10 -54
  124. package/fesm2022/layout.mjs.map +1 -0
  125. package/{fesm2020 → fesm2022}/listbox.mjs +16 -46
  126. package/fesm2022/listbox.mjs.map +1 -0
  127. package/{fesm2020 → fesm2022}/menu.mjs +86 -220
  128. package/fesm2022/menu.mjs.map +1 -0
  129. package/{fesm2020 → fesm2022}/observers.mjs +13 -36
  130. package/fesm2022/observers.mjs.map +1 -0
  131. package/{fesm2020 → fesm2022}/overlay.mjs +34 -206
  132. package/fesm2022/overlay.mjs.map +1 -0
  133. package/{fesm2020 → fesm2022}/platform.mjs +7 -72
  134. package/fesm2022/platform.mjs.map +1 -0
  135. package/{fesm2020 → fesm2022}/portal.mjs +26 -77
  136. package/fesm2022/portal.mjs.map +1 -0
  137. package/{fesm2020 → fesm2022}/scrolling.mjs +57 -158
  138. package/fesm2022/scrolling.mjs.map +1 -0
  139. package/{fesm2020 → fesm2022}/stepper.mjs +27 -78
  140. package/fesm2022/stepper.mjs.map +1 -0
  141. package/{fesm2020 → fesm2022}/table.mjs +134 -227
  142. package/fesm2022/table.mjs.map +1 -0
  143. package/{fesm2020 → fesm2022}/testing/selenium-webdriver.mjs +0 -37
  144. package/fesm2022/testing/selenium-webdriver.mjs.map +1 -0
  145. package/{fesm2020 → fesm2022}/testing/testbed.mjs +1 -72
  146. package/fesm2022/testing/testbed.mjs.map +1 -0
  147. package/{fesm2020 → fesm2022}/testing.mjs +0 -66
  148. package/fesm2022/testing.mjs.map +1 -0
  149. package/{fesm2020 → fesm2022}/text-field.mjs +13 -50
  150. package/fesm2022/text-field.mjs.map +1 -0
  151. package/{fesm2020 → fesm2022}/tree.mjs +45 -131
  152. package/fesm2022/tree.mjs.map +1 -0
  153. package/listbox/index.d.ts +2 -2
  154. package/menu/index.d.ts +5 -5
  155. package/observers/index.d.ts +1 -1
  156. package/overlay/index.d.ts +1 -1
  157. package/package.json +77 -131
  158. package/portal/index.d.ts +2 -2
  159. package/schematics/ng-add/index.js +1 -1
  160. package/schematics/ng-add/index.mjs +1 -1
  161. package/schematics/ng-update/devkit-file-system.js +3 -2
  162. package/schematics/ng-update/devkit-file-system.mjs +3 -2
  163. package/schematics/ng-update/migrations/attribute-selectors.js +5 -8
  164. package/schematics/ng-update/migrations/attribute-selectors.mjs +5 -8
  165. package/schematics/ng-update/migrations/class-inheritance.js +8 -11
  166. package/schematics/ng-update/migrations/class-inheritance.mjs +8 -11
  167. package/schematics/ng-update/migrations/class-names.js +12 -15
  168. package/schematics/ng-update/migrations/class-names.mjs +12 -15
  169. package/schematics/ng-update/migrations/constructor-signature.js +7 -10
  170. package/schematics/ng-update/migrations/constructor-signature.mjs +7 -10
  171. package/schematics/ng-update/migrations/css-selectors.js +5 -8
  172. package/schematics/ng-update/migrations/css-selectors.mjs +5 -8
  173. package/schematics/ng-update/migrations/element-selectors.js +5 -8
  174. package/schematics/ng-update/migrations/element-selectors.mjs +5 -8
  175. package/schematics/ng-update/migrations/input-names.js +5 -8
  176. package/schematics/ng-update/migrations/input-names.mjs +5 -8
  177. package/schematics/ng-update/migrations/method-call-arguments.js +5 -8
  178. package/schematics/ng-update/migrations/method-call-arguments.mjs +5 -8
  179. package/schematics/ng-update/migrations/misc-template.js +3 -6
  180. package/schematics/ng-update/migrations/misc-template.mjs +3 -6
  181. package/schematics/ng-update/migrations/output-names.js +5 -8
  182. package/schematics/ng-update/migrations/output-names.mjs +5 -8
  183. package/schematics/ng-update/migrations/property-names.js +5 -8
  184. package/schematics/ng-update/migrations/property-names.mjs +5 -8
  185. package/schematics/ng-update/migrations/symbol-removal.js +5 -8
  186. package/schematics/ng-update/migrations/symbol-removal.mjs +5 -8
  187. package/schematics/update-tool/component-resource-collector.js +5 -3
  188. package/schematics/update-tool/component-resource-collector.mjs +5 -3
  189. package/schematics/update-tool/index.js +8 -2
  190. package/schematics/update-tool/index.mjs +8 -2
  191. package/schematics/update-tool/migration.js +10 -3
  192. package/schematics/update-tool/migration.mjs +10 -3
  193. package/schematics/update-tool/utils/virtual-host.js +3 -2
  194. package/schematics/update-tool/utils/virtual-host.mjs +3 -2
  195. package/scrolling/index.d.ts +3 -3
  196. package/stepper/index.d.ts +4 -4
  197. package/table/index.d.ts +6 -6
  198. package/text-field/index.d.ts +1 -1
  199. package/tree/index.d.ts +6 -6
  200. package/esm2020/drag-drop/directives/drag.mjs +0 -489
  201. package/esm2020/drag-drop/directives/drop-list.mjs +0 -348
  202. package/esm2020/menu/menu-trigger.mjs +0 -306
  203. package/esm2020/portal/portal-directives.mjs +0 -250
  204. package/esm2020/table/row.mjs +0 -271
  205. package/esm2020/tree/tree.mjs +0 -349
  206. package/fesm2015/a11y.mjs +0 -2544
  207. package/fesm2015/a11y.mjs.map +0 -1
  208. package/fesm2015/accordion.mjs +0 -275
  209. package/fesm2015/accordion.mjs.map +0 -1
  210. package/fesm2015/bidi.mjs +0 -194
  211. package/fesm2015/bidi.mjs.map +0 -1
  212. package/fesm2015/cdk.mjs +0 -30
  213. package/fesm2015/cdk.mjs.map +0 -1
  214. package/fesm2015/clipboard.mjs +0 -263
  215. package/fesm2015/clipboard.mjs.map +0 -1
  216. package/fesm2015/coercion.mjs.map +0 -1
  217. package/fesm2015/collections.mjs.map +0 -1
  218. package/fesm2015/dialog.mjs +0 -800
  219. package/fesm2015/dialog.mjs.map +0 -1
  220. package/fesm2015/drag-drop.mjs +0 -3823
  221. package/fesm2015/drag-drop.mjs.map +0 -1
  222. package/fesm2015/keycodes.mjs +0 -167
  223. package/fesm2015/keycodes.mjs.map +0 -1
  224. package/fesm2015/layout.mjs.map +0 -1
  225. package/fesm2015/listbox.mjs +0 -918
  226. package/fesm2015/listbox.mjs.map +0 -1
  227. package/fesm2015/menu.mjs +0 -2009
  228. package/fesm2015/menu.mjs.map +0 -1
  229. package/fesm2015/observers.mjs +0 -211
  230. package/fesm2015/observers.mjs.map +0 -1
  231. package/fesm2015/overlay.mjs +0 -3142
  232. package/fesm2015/overlay.mjs.map +0 -1
  233. package/fesm2015/platform.mjs +0 -385
  234. package/fesm2015/platform.mjs.map +0 -1
  235. package/fesm2015/portal.mjs +0 -691
  236. package/fesm2015/portal.mjs.map +0 -1
  237. package/fesm2015/scrolling.mjs +0 -1566
  238. package/fesm2015/scrolling.mjs.map +0 -1
  239. package/fesm2015/stepper.mjs +0 -621
  240. package/fesm2015/stepper.mjs.map +0 -1
  241. package/fesm2015/table.mjs +0 -2357
  242. package/fesm2015/table.mjs.map +0 -1
  243. package/fesm2015/testing/selenium-webdriver.mjs +0 -419
  244. package/fesm2015/testing/selenium-webdriver.mjs.map +0 -1
  245. package/fesm2015/testing/testbed.mjs +0 -868
  246. package/fesm2015/testing/testbed.mjs.map +0 -1
  247. package/fesm2015/testing.mjs +0 -785
  248. package/fesm2015/testing.mjs.map +0 -1
  249. package/fesm2015/text-field.mjs +0 -461
  250. package/fesm2015/text-field.mjs.map +0 -1
  251. package/fesm2015/tree.mjs +0 -950
  252. package/fesm2015/tree.mjs.map +0 -1
  253. package/fesm2020/a11y.mjs.map +0 -1
  254. package/fesm2020/accordion.mjs.map +0 -1
  255. package/fesm2020/bidi.mjs.map +0 -1
  256. package/fesm2020/cdk.mjs +0 -30
  257. package/fesm2020/cdk.mjs.map +0 -1
  258. package/fesm2020/clipboard.mjs.map +0 -1
  259. package/fesm2020/coercion.mjs +0 -132
  260. package/fesm2020/coercion.mjs.map +0 -1
  261. package/fesm2020/collections.mjs +0 -543
  262. package/fesm2020/collections.mjs.map +0 -1
  263. package/fesm2020/dialog.mjs.map +0 -1
  264. package/fesm2020/drag-drop.mjs.map +0 -1
  265. package/fesm2020/keycodes.mjs.map +0 -1
  266. package/fesm2020/layout.mjs +0 -254
  267. package/fesm2020/layout.mjs.map +0 -1
  268. package/fesm2020/listbox.mjs.map +0 -1
  269. package/fesm2020/menu.mjs.map +0 -1
  270. package/fesm2020/observers.mjs.map +0 -1
  271. package/fesm2020/overlay.mjs.map +0 -1
  272. package/fesm2020/platform.mjs.map +0 -1
  273. package/fesm2020/portal.mjs.map +0 -1
  274. package/fesm2020/scrolling.mjs.map +0 -1
  275. package/fesm2020/stepper.mjs.map +0 -1
  276. package/fesm2020/table.mjs.map +0 -1
  277. package/fesm2020/testing/selenium-webdriver.mjs.map +0 -1
  278. package/fesm2020/testing/testbed.mjs.map +0 -1
  279. package/fesm2020/testing.mjs.map +0 -1
  280. package/fesm2020/text-field.mjs.map +0 -1
  281. package/fesm2020/tree.mjs.map +0 -1
  282. /package/{esm2020 → esm2022}/a11y/a11y_public_index.mjs +0 -0
  283. /package/{esm2020 → esm2022}/a11y/aria-describer/aria-reference.mjs +0 -0
  284. /package/{esm2020 → esm2022}/a11y/fake-event-detection.mjs +0 -0
  285. /package/{esm2020 → esm2022}/a11y/focus-trap/configurable-focus-trap-config.mjs +0 -0
  286. /package/{esm2020 → esm2022}/a11y/focus-trap/configurable-focus-trap.mjs +0 -0
  287. /package/{esm2020 → esm2022}/a11y/focus-trap/event-listener-inert-strategy.mjs +0 -0
  288. /package/{esm2020 → esm2022}/a11y/focus-trap/focus-trap-inert-strategy.mjs +0 -0
  289. /package/{esm2020 → esm2022}/a11y/index.mjs +0 -0
  290. /package/{esm2020 → esm2022}/a11y/key-manager/activedescendant-key-manager.mjs +0 -0
  291. /package/{esm2020 → esm2022}/a11y/key-manager/focus-key-manager.mjs +0 -0
  292. /package/{esm2020 → esm2022}/a11y/key-manager/list-key-manager.mjs +0 -0
  293. /package/{esm2020 → esm2022}/a11y/live-announcer/live-announcer-tokens.mjs +0 -0
  294. /package/{esm2020 → esm2022}/a11y/public-api.mjs +0 -0
  295. /package/{esm2020 → esm2022}/accordion/accordion_public_index.mjs +0 -0
  296. /package/{esm2020 → esm2022}/accordion/index.mjs +0 -0
  297. /package/{esm2020 → esm2022}/accordion/public-api.mjs +0 -0
  298. /package/{esm2020 → esm2022}/bidi/bidi_public_index.mjs +0 -0
  299. /package/{esm2020 → esm2022}/bidi/dir-document-token.mjs +0 -0
  300. /package/{esm2020 → esm2022}/bidi/index.mjs +0 -0
  301. /package/{esm2020 → esm2022}/bidi/public-api.mjs +0 -0
  302. /package/{esm2020 → esm2022}/clipboard/clipboard_public_index.mjs +0 -0
  303. /package/{esm2020 → esm2022}/clipboard/index.mjs +0 -0
  304. /package/{esm2020 → esm2022}/clipboard/pending-copy.mjs +0 -0
  305. /package/{esm2020 → esm2022}/clipboard/public-api.mjs +0 -0
  306. /package/{esm2020 → esm2022}/coercion/array.mjs +0 -0
  307. /package/{esm2020 → esm2022}/coercion/boolean-property.mjs +0 -0
  308. /package/{esm2020 → esm2022}/coercion/css-pixel-value.mjs +0 -0
  309. /package/{esm2020 → esm2022}/coercion/element.mjs +0 -0
  310. /package/{esm2020 → esm2022}/coercion/index.mjs +0 -0
  311. /package/{esm2020 → esm2022}/coercion/number-property.mjs +0 -0
  312. /package/{esm2020 → esm2022}/coercion/public-api.mjs +0 -0
  313. /package/{esm2020 → esm2022}/coercion/string-array.mjs +0 -0
  314. /package/{esm2020 → esm2022}/collections/array-data-source.mjs +0 -0
  315. /package/{esm2020 → esm2022}/collections/collection-viewer.mjs +0 -0
  316. /package/{esm2020 → esm2022}/collections/collections_public_index.mjs +0 -0
  317. /package/{esm2020 → esm2022}/collections/data-source.mjs +0 -0
  318. /package/{esm2020 → esm2022}/collections/dispose-view-repeater-strategy.mjs +0 -0
  319. /package/{esm2020 → esm2022}/collections/index.mjs +0 -0
  320. /package/{esm2020 → esm2022}/collections/public-api.mjs +0 -0
  321. /package/{esm2020 → esm2022}/collections/recycle-view-repeater-strategy.mjs +0 -0
  322. /package/{esm2020 → esm2022}/collections/selection-model.mjs +0 -0
  323. /package/{esm2020 → esm2022}/collections/tree-adapter.mjs +0 -0
  324. /package/{esm2020 → esm2022}/collections/view-repeater.mjs +0 -0
  325. /package/{esm2020 → esm2022}/dialog/dialog-config.mjs +0 -0
  326. /package/{esm2020 → esm2022}/dialog/dialog-injectors.mjs +0 -0
  327. /package/{esm2020 → esm2022}/dialog/dialog-ref.mjs +0 -0
  328. /package/{esm2020 → esm2022}/dialog/dialog_public_index.mjs +0 -0
  329. /package/{esm2020 → esm2022}/dialog/index.mjs +0 -0
  330. /package/{esm2020 → esm2022}/dialog/public-api.mjs +0 -0
  331. /package/{esm2020 → esm2022}/drag-drop/directives/assertions.mjs +0 -0
  332. /package/{esm2020 → esm2022}/drag-drop/directives/config.mjs +0 -0
  333. /package/{esm2020 → esm2022}/drag-drop/dom/client-rect.mjs +0 -0
  334. /package/{esm2020 → esm2022}/drag-drop/dom/clone-node.mjs +0 -0
  335. /package/{esm2020 → esm2022}/drag-drop/dom/parent-position-tracker.mjs +0 -0
  336. /package/{esm2020 → esm2022}/drag-drop/dom/styling.mjs +0 -0
  337. /package/{esm2020 → esm2022}/drag-drop/dom/transition-duration.mjs +0 -0
  338. /package/{esm2020 → esm2022}/drag-drop/drag-drop_public_index.mjs +0 -0
  339. /package/{esm2020 → esm2022}/drag-drop/drag-events.mjs +0 -0
  340. /package/{esm2020 → esm2022}/drag-drop/drag-parent.mjs +0 -0
  341. /package/{esm2020 → esm2022}/drag-drop/drag-ref.mjs +0 -0
  342. /package/{esm2020 → esm2022}/drag-drop/drag-utils.mjs +0 -0
  343. /package/{esm2020 → esm2022}/drag-drop/drop-list-ref.mjs +0 -0
  344. /package/{esm2020 → esm2022}/drag-drop/index.mjs +0 -0
  345. /package/{esm2020 → esm2022}/drag-drop/public-api.mjs +0 -0
  346. /package/{esm2020 → esm2022}/drag-drop/sorting/drop-list-sort-strategy.mjs +0 -0
  347. /package/{esm2020 → esm2022}/drag-drop/sorting/single-axis-sort-strategy.mjs +0 -0
  348. /package/{esm2020 → esm2022}/index.mjs +0 -0
  349. /package/{esm2020 → esm2022}/keycodes/index.mjs +0 -0
  350. /package/{esm2020 → esm2022}/keycodes/keycodes.mjs +0 -0
  351. /package/{esm2020 → esm2022}/keycodes/keycodes_public_index.mjs +0 -0
  352. /package/{esm2020 → esm2022}/keycodes/modifiers.mjs +0 -0
  353. /package/{esm2020 → esm2022}/keycodes/public-api.mjs +0 -0
  354. /package/{esm2020 → esm2022}/layout/breakpoints.mjs +0 -0
  355. /package/{esm2020 → esm2022}/layout/index.mjs +0 -0
  356. /package/{esm2020 → esm2022}/layout/layout_public_index.mjs +0 -0
  357. /package/{esm2020 → esm2022}/layout/public-api.mjs +0 -0
  358. /package/{esm2020 → esm2022}/listbox/index.mjs +0 -0
  359. /package/{esm2020 → esm2022}/listbox/listbox_public_index.mjs +0 -0
  360. /package/{esm2020 → esm2022}/listbox/public-api.mjs +0 -0
  361. /package/{esm2020 → esm2022}/menu/index.mjs +0 -0
  362. /package/{esm2020 → esm2022}/menu/menu-errors.mjs +0 -0
  363. /package/{esm2020 → esm2022}/menu/menu-interface.mjs +0 -0
  364. /package/{esm2020 → esm2022}/menu/menu_public_index.mjs +0 -0
  365. /package/{esm2020 → esm2022}/menu/pointer-focus-tracker.mjs +0 -0
  366. /package/{esm2020 → esm2022}/menu/public-api.mjs +0 -0
  367. /package/{esm2020 → esm2022}/observers/index.mjs +0 -0
  368. /package/{esm2020 → esm2022}/observers/observers_public_index.mjs +0 -0
  369. /package/{esm2020 → esm2022}/observers/public-api.mjs +0 -0
  370. /package/{esm2020 → esm2022}/overlay/dispatchers/index.mjs +0 -0
  371. /package/{esm2020 → esm2022}/overlay/index.mjs +0 -0
  372. /package/{esm2020 → esm2022}/overlay/overlay-config.mjs +0 -0
  373. /package/{esm2020 → esm2022}/overlay/overlay-ref.mjs +0 -0
  374. /package/{esm2020 → esm2022}/overlay/overlay-reference.mjs +0 -0
  375. /package/{esm2020 → esm2022}/overlay/overlay_public_index.mjs +0 -0
  376. /package/{esm2020 → esm2022}/overlay/position/connected-position.mjs +0 -0
  377. /package/{esm2020 → esm2022}/overlay/position/flexible-connected-position-strategy.mjs +0 -0
  378. /package/{esm2020 → esm2022}/overlay/position/global-position-strategy.mjs +0 -0
  379. /package/{esm2020 → esm2022}/overlay/position/position-strategy.mjs +0 -0
  380. /package/{esm2020 → esm2022}/overlay/position/scroll-clip.mjs +0 -0
  381. /package/{esm2020 → esm2022}/overlay/public-api.mjs +0 -0
  382. /package/{esm2020 → esm2022}/overlay/scroll/block-scroll-strategy.mjs +0 -0
  383. /package/{esm2020 → esm2022}/overlay/scroll/close-scroll-strategy.mjs +0 -0
  384. /package/{esm2020 → esm2022}/overlay/scroll/index.mjs +0 -0
  385. /package/{esm2020 → esm2022}/overlay/scroll/noop-scroll-strategy.mjs +0 -0
  386. /package/{esm2020 → esm2022}/overlay/scroll/reposition-scroll-strategy.mjs +0 -0
  387. /package/{esm2020 → esm2022}/overlay/scroll/scroll-strategy.mjs +0 -0
  388. /package/{esm2020 → esm2022}/platform/features/input-types.mjs +0 -0
  389. /package/{esm2020 → esm2022}/platform/features/passive-listeners.mjs +0 -0
  390. /package/{esm2020 → esm2022}/platform/features/scrolling.mjs +0 -0
  391. /package/{esm2020 → esm2022}/platform/features/shadow-dom.mjs +0 -0
  392. /package/{esm2020 → esm2022}/platform/features/test-environment.mjs +0 -0
  393. /package/{esm2020 → esm2022}/platform/index.mjs +0 -0
  394. /package/{esm2020 → esm2022}/platform/platform_public_index.mjs +0 -0
  395. /package/{esm2020 → esm2022}/platform/public-api.mjs +0 -0
  396. /package/{esm2020 → esm2022}/portal/dom-portal-outlet.mjs +0 -0
  397. /package/{esm2020 → esm2022}/portal/index.mjs +0 -0
  398. /package/{esm2020 → esm2022}/portal/portal-errors.mjs +0 -0
  399. /package/{esm2020 → esm2022}/portal/portal-injector.mjs +0 -0
  400. /package/{esm2020 → esm2022}/portal/portal.mjs +0 -0
  401. /package/{esm2020 → esm2022}/portal/portal_public_index.mjs +0 -0
  402. /package/{esm2020 → esm2022}/portal/public-api.mjs +0 -0
  403. /package/{esm2020 → esm2022}/public-api.mjs +0 -0
  404. /package/{esm2020 → esm2022}/scrolling/index.mjs +0 -0
  405. /package/{esm2020 → esm2022}/scrolling/public-api.mjs +0 -0
  406. /package/{esm2020 → esm2022}/scrolling/scrolling_public_index.mjs +0 -0
  407. /package/{esm2020 → esm2022}/scrolling/virtual-scroll-repeater.mjs +0 -0
  408. /package/{esm2020 → esm2022}/scrolling/virtual-scroll-strategy.mjs +0 -0
  409. /package/{esm2020 → esm2022}/stepper/index.mjs +0 -0
  410. /package/{esm2020 → esm2022}/stepper/public-api.mjs +0 -0
  411. /package/{esm2020 → esm2022}/stepper/stepper_public_index.mjs +0 -0
  412. /package/{esm2020 → esm2022}/table/can-stick.mjs +0 -0
  413. /package/{esm2020 → esm2022}/table/index.mjs +0 -0
  414. /package/{esm2020 → esm2022}/table/public-api.mjs +0 -0
  415. /package/{esm2020 → esm2022}/table/sticky-position-listener.mjs +0 -0
  416. /package/{esm2020 → esm2022}/table/sticky-styler.mjs +0 -0
  417. /package/{esm2020 → esm2022}/table/table-errors.mjs +0 -0
  418. /package/{esm2020 → esm2022}/table/table_public_index.mjs +0 -0
  419. /package/{esm2020 → esm2022}/table/tokens.mjs +0 -0
  420. /package/{esm2020 → esm2022}/testing/change-detection.mjs +0 -0
  421. /package/{esm2020 → esm2022}/testing/component-harness.mjs +0 -0
  422. /package/{esm2020 → esm2022}/testing/element-dimensions.mjs +0 -0
  423. /package/{esm2020 → esm2022}/testing/harness-environment.mjs +0 -0
  424. /package/{esm2020 → esm2022}/testing/index.mjs +0 -0
  425. /package/{esm2020 → esm2022}/testing/public-api.mjs +0 -0
  426. /package/{esm2020 → esm2022}/testing/selenium-webdriver/index.mjs +0 -0
  427. /package/{esm2020 → esm2022}/testing/selenium-webdriver/public-api.mjs +0 -0
  428. /package/{esm2020 → esm2022}/testing/selenium-webdriver/selenium-web-driver-element.mjs +0 -0
  429. /package/{esm2020 → esm2022}/testing/selenium-webdriver/selenium-web-driver-harness-environment.mjs +0 -0
  430. /package/{esm2020 → esm2022}/testing/selenium-webdriver/selenium-webdriver-keys.mjs +0 -0
  431. /package/{esm2020 → esm2022}/testing/test-element-errors.mjs +0 -0
  432. /package/{esm2020 → esm2022}/testing/test-element.mjs +0 -0
  433. /package/{esm2020 → esm2022}/testing/testbed/fake-events/dispatch-events.mjs +0 -0
  434. /package/{esm2020 → esm2022}/testing/testbed/fake-events/element-focus.mjs +0 -0
  435. /package/{esm2020 → esm2022}/testing/testbed/fake-events/event-objects.mjs +0 -0
  436. /package/{esm2020 → esm2022}/testing/testbed/fake-events/index.mjs +0 -0
  437. /package/{esm2020 → esm2022}/testing/testbed/fake-events/type-in-element.mjs +0 -0
  438. /package/{esm2020 → esm2022}/testing/testbed/index.mjs +0 -0
  439. /package/{esm2020 → esm2022}/testing/testbed/public-api.mjs +0 -0
  440. /package/{esm2020 → esm2022}/testing/testbed/task-state-zone-interceptor.mjs +0 -0
  441. /package/{esm2020 → esm2022}/testing/testbed/testbed-harness-environment.mjs +0 -0
  442. /package/{esm2020 → esm2022}/testing/testbed/unit-test-element.mjs +0 -0
  443. /package/{esm2020 → esm2022}/testing/text-filtering.mjs +0 -0
  444. /package/{esm2020 → esm2022}/text-field/index.mjs +0 -0
  445. /package/{esm2020 → esm2022}/text-field/public-api.mjs +0 -0
  446. /package/{esm2020 → esm2022}/text-field/text-field_public_index.mjs +0 -0
  447. /package/{esm2020 → esm2022}/tree/control/base-tree-control.mjs +0 -0
  448. /package/{esm2020 → esm2022}/tree/control/flat-tree-control.mjs +0 -0
  449. /package/{esm2020 → esm2022}/tree/control/nested-tree-control.mjs +0 -0
  450. /package/{esm2020 → esm2022}/tree/control/tree-control.mjs +0 -0
  451. /package/{esm2020 → esm2022}/tree/index.mjs +0 -0
  452. /package/{esm2020 → esm2022}/tree/public-api.mjs +0 -0
  453. /package/{esm2020 → esm2022}/tree/tree-errors.mjs +0 -0
  454. /package/{esm2020 → esm2022}/tree/tree_public_index.mjs +0 -0
package/fesm2015/a11y.mjs DELETED
@@ -1,2544 +0,0 @@
1
- import { DOCUMENT } from '@angular/common';
2
- import * as i0 from '@angular/core';
3
- import { inject, APP_ID, Injectable, Inject, QueryList, Directive, Input, InjectionToken, Optional, EventEmitter, Output, NgModule } from '@angular/core';
4
- import * as i1 from '@angular/cdk/platform';
5
- import { _getFocusedElementPierceShadowDom, normalizePassiveListenerOptions, _getEventTarget, _getShadowRoot } from '@angular/cdk/platform';
6
- import { Subject, Subscription, BehaviorSubject, of } from 'rxjs';
7
- import { hasModifierKey, A, Z, ZERO, NINE, PAGE_DOWN, PAGE_UP, END, HOME, LEFT_ARROW, RIGHT_ARROW, UP_ARROW, DOWN_ARROW, TAB, ALT, CONTROL, MAC_META, META, SHIFT } from '@angular/cdk/keycodes';
8
- import { tap, debounceTime, filter, map, take, skip, distinctUntilChanged, takeUntil } from 'rxjs/operators';
9
- import { coerceBooleanProperty, coerceElement } from '@angular/cdk/coercion';
10
- import * as i1$1 from '@angular/cdk/observers';
11
- import { ObserversModule } from '@angular/cdk/observers';
12
- import { BreakpointObserver } from '@angular/cdk/layout';
13
-
14
- /**
15
- * @license
16
- * Copyright Google LLC All Rights Reserved.
17
- *
18
- * Use of this source code is governed by an MIT-style license that can be
19
- * found in the LICENSE file at https://angular.io/license
20
- */
21
- /** IDs are delimited by an empty space, as per the spec. */
22
- const ID_DELIMITER = ' ';
23
- /**
24
- * Adds the given ID to the specified ARIA attribute on an element.
25
- * Used for attributes such as aria-labelledby, aria-owns, etc.
26
- */
27
- function addAriaReferencedId(el, attr, id) {
28
- const ids = getAriaReferenceIds(el, attr);
29
- if (ids.some(existingId => existingId.trim() == id.trim())) {
30
- return;
31
- }
32
- ids.push(id.trim());
33
- el.setAttribute(attr, ids.join(ID_DELIMITER));
34
- }
35
- /**
36
- * Removes the given ID from the specified ARIA attribute on an element.
37
- * Used for attributes such as aria-labelledby, aria-owns, etc.
38
- */
39
- function removeAriaReferencedId(el, attr, id) {
40
- const ids = getAriaReferenceIds(el, attr);
41
- const filteredIds = ids.filter(val => val != id.trim());
42
- if (filteredIds.length) {
43
- el.setAttribute(attr, filteredIds.join(ID_DELIMITER));
44
- }
45
- else {
46
- el.removeAttribute(attr);
47
- }
48
- }
49
- /**
50
- * Gets the list of IDs referenced by the given ARIA attribute on an element.
51
- * Used for attributes such as aria-labelledby, aria-owns, etc.
52
- */
53
- function getAriaReferenceIds(el, attr) {
54
- // Get string array of all individual ids (whitespace delimited) in the attribute value
55
- return (el.getAttribute(attr) || '').match(/\S+/g) || [];
56
- }
57
-
58
- /**
59
- * @license
60
- * Copyright Google LLC All Rights Reserved.
61
- *
62
- * Use of this source code is governed by an MIT-style license that can be
63
- * found in the LICENSE file at https://angular.io/license
64
- */
65
- /**
66
- * ID used for the body container where all messages are appended.
67
- * @deprecated No longer being used. To be removed.
68
- * @breaking-change 14.0.0
69
- */
70
- const MESSAGES_CONTAINER_ID = 'cdk-describedby-message-container';
71
- /**
72
- * ID prefix used for each created message element.
73
- * @deprecated To be turned into a private variable.
74
- * @breaking-change 14.0.0
75
- */
76
- const CDK_DESCRIBEDBY_ID_PREFIX = 'cdk-describedby-message';
77
- /**
78
- * Attribute given to each host element that is described by a message element.
79
- * @deprecated To be turned into a private variable.
80
- * @breaking-change 14.0.0
81
- */
82
- const CDK_DESCRIBEDBY_HOST_ATTRIBUTE = 'cdk-describedby-host';
83
- /** Global incremental identifier for each registered message element. */
84
- let nextId = 0;
85
- /**
86
- * Utility that creates visually hidden elements with a message content. Useful for elements that
87
- * want to use aria-describedby to further describe themselves without adding additional visual
88
- * content.
89
- */
90
- class AriaDescriber {
91
- constructor(_document,
92
- /**
93
- * @deprecated To be turned into a required parameter.
94
- * @breaking-change 14.0.0
95
- */
96
- _platform) {
97
- this._platform = _platform;
98
- /** Map of all registered message elements that have been placed into the document. */
99
- this._messageRegistry = new Map();
100
- /** Container for all registered messages. */
101
- this._messagesContainer = null;
102
- /** Unique ID for the service. */
103
- this._id = `${nextId++}`;
104
- this._document = _document;
105
- this._id = inject(APP_ID) + '-' + nextId++;
106
- }
107
- describe(hostElement, message, role) {
108
- if (!this._canBeDescribed(hostElement, message)) {
109
- return;
110
- }
111
- const key = getKey(message, role);
112
- if (typeof message !== 'string') {
113
- // We need to ensure that the element has an ID.
114
- setMessageId(message, this._id);
115
- this._messageRegistry.set(key, { messageElement: message, referenceCount: 0 });
116
- }
117
- else if (!this._messageRegistry.has(key)) {
118
- this._createMessageElement(message, role);
119
- }
120
- if (!this._isElementDescribedByMessage(hostElement, key)) {
121
- this._addMessageReference(hostElement, key);
122
- }
123
- }
124
- removeDescription(hostElement, message, role) {
125
- var _a;
126
- if (!message || !this._isElementNode(hostElement)) {
127
- return;
128
- }
129
- const key = getKey(message, role);
130
- if (this._isElementDescribedByMessage(hostElement, key)) {
131
- this._removeMessageReference(hostElement, key);
132
- }
133
- // If the message is a string, it means that it's one that we created for the
134
- // consumer so we can remove it safely, otherwise we should leave it in place.
135
- if (typeof message === 'string') {
136
- const registeredMessage = this._messageRegistry.get(key);
137
- if (registeredMessage && registeredMessage.referenceCount === 0) {
138
- this._deleteMessageElement(key);
139
- }
140
- }
141
- if (((_a = this._messagesContainer) === null || _a === void 0 ? void 0 : _a.childNodes.length) === 0) {
142
- this._messagesContainer.remove();
143
- this._messagesContainer = null;
144
- }
145
- }
146
- /** Unregisters all created message elements and removes the message container. */
147
- ngOnDestroy() {
148
- var _a;
149
- const describedElements = this._document.querySelectorAll(`[${CDK_DESCRIBEDBY_HOST_ATTRIBUTE}="${this._id}"]`);
150
- for (let i = 0; i < describedElements.length; i++) {
151
- this._removeCdkDescribedByReferenceIds(describedElements[i]);
152
- describedElements[i].removeAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE);
153
- }
154
- (_a = this._messagesContainer) === null || _a === void 0 ? void 0 : _a.remove();
155
- this._messagesContainer = null;
156
- this._messageRegistry.clear();
157
- }
158
- /**
159
- * Creates a new element in the visually hidden message container element with the message
160
- * as its content and adds it to the message registry.
161
- */
162
- _createMessageElement(message, role) {
163
- const messageElement = this._document.createElement('div');
164
- setMessageId(messageElement, this._id);
165
- messageElement.textContent = message;
166
- if (role) {
167
- messageElement.setAttribute('role', role);
168
- }
169
- this._createMessagesContainer();
170
- this._messagesContainer.appendChild(messageElement);
171
- this._messageRegistry.set(getKey(message, role), { messageElement, referenceCount: 0 });
172
- }
173
- /** Deletes the message element from the global messages container. */
174
- _deleteMessageElement(key) {
175
- var _a, _b;
176
- (_b = (_a = this._messageRegistry.get(key)) === null || _a === void 0 ? void 0 : _a.messageElement) === null || _b === void 0 ? void 0 : _b.remove();
177
- this._messageRegistry.delete(key);
178
- }
179
- /** Creates the global container for all aria-describedby messages. */
180
- _createMessagesContainer() {
181
- if (this._messagesContainer) {
182
- return;
183
- }
184
- const containerClassName = 'cdk-describedby-message-container';
185
- const serverContainers = this._document.querySelectorAll(`.${containerClassName}[platform="server"]`);
186
- for (let i = 0; i < serverContainers.length; i++) {
187
- // When going from the server to the client, we may end up in a situation where there's
188
- // already a container on the page, but we don't have a reference to it. Clear the
189
- // old container so we don't get duplicates. Doing this, instead of emptying the previous
190
- // container, should be slightly faster.
191
- serverContainers[i].remove();
192
- }
193
- const messagesContainer = this._document.createElement('div');
194
- // We add `visibility: hidden` in order to prevent text in this container from
195
- // being searchable by the browser's Ctrl + F functionality.
196
- // Screen-readers will still read the description for elements with aria-describedby even
197
- // when the description element is not visible.
198
- messagesContainer.style.visibility = 'hidden';
199
- // Even though we use `visibility: hidden`, we still apply `cdk-visually-hidden` so that
200
- // the description element doesn't impact page layout.
201
- messagesContainer.classList.add(containerClassName);
202
- messagesContainer.classList.add('cdk-visually-hidden');
203
- // @breaking-change 14.0.0 Remove null check for `_platform`.
204
- if (this._platform && !this._platform.isBrowser) {
205
- messagesContainer.setAttribute('platform', 'server');
206
- }
207
- this._document.body.appendChild(messagesContainer);
208
- this._messagesContainer = messagesContainer;
209
- }
210
- /** Removes all cdk-describedby messages that are hosted through the element. */
211
- _removeCdkDescribedByReferenceIds(element) {
212
- // Remove all aria-describedby reference IDs that are prefixed by CDK_DESCRIBEDBY_ID_PREFIX
213
- const originalReferenceIds = getAriaReferenceIds(element, 'aria-describedby').filter(id => id.indexOf(CDK_DESCRIBEDBY_ID_PREFIX) != 0);
214
- element.setAttribute('aria-describedby', originalReferenceIds.join(' '));
215
- }
216
- /**
217
- * Adds a message reference to the element using aria-describedby and increments the registered
218
- * message's reference count.
219
- */
220
- _addMessageReference(element, key) {
221
- const registeredMessage = this._messageRegistry.get(key);
222
- // Add the aria-describedby reference and set the
223
- // describedby_host attribute to mark the element.
224
- addAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id);
225
- element.setAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE, this._id);
226
- registeredMessage.referenceCount++;
227
- }
228
- /**
229
- * Removes a message reference from the element using aria-describedby
230
- * and decrements the registered message's reference count.
231
- */
232
- _removeMessageReference(element, key) {
233
- const registeredMessage = this._messageRegistry.get(key);
234
- registeredMessage.referenceCount--;
235
- removeAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id);
236
- element.removeAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE);
237
- }
238
- /** Returns true if the element has been described by the provided message ID. */
239
- _isElementDescribedByMessage(element, key) {
240
- const referenceIds = getAriaReferenceIds(element, 'aria-describedby');
241
- const registeredMessage = this._messageRegistry.get(key);
242
- const messageId = registeredMessage && registeredMessage.messageElement.id;
243
- return !!messageId && referenceIds.indexOf(messageId) != -1;
244
- }
245
- /** Determines whether a message can be described on a particular element. */
246
- _canBeDescribed(element, message) {
247
- if (!this._isElementNode(element)) {
248
- return false;
249
- }
250
- if (message && typeof message === 'object') {
251
- // We'd have to make some assumptions about the description element's text, if the consumer
252
- // passed in an element. Assume that if an element is passed in, the consumer has verified
253
- // that it can be used as a description.
254
- return true;
255
- }
256
- const trimmedMessage = message == null ? '' : `${message}`.trim();
257
- const ariaLabel = element.getAttribute('aria-label');
258
- // We shouldn't set descriptions if they're exactly the same as the `aria-label` of the
259
- // element, because screen readers will end up reading out the same text twice in a row.
260
- return trimmedMessage ? !ariaLabel || ariaLabel.trim() !== trimmedMessage : false;
261
- }
262
- /** Checks whether a node is an Element node. */
263
- _isElementNode(element) {
264
- return element.nodeType === this._document.ELEMENT_NODE;
265
- }
266
- }
267
- AriaDescriber.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: AriaDescriber, deps: [{ token: DOCUMENT }, { token: i1.Platform }], target: i0.ɵɵFactoryTarget.Injectable });
268
- AriaDescriber.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: AriaDescriber, providedIn: 'root' });
269
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: AriaDescriber, decorators: [{
270
- type: Injectable,
271
- args: [{ providedIn: 'root' }]
272
- }], ctorParameters: function () {
273
- return [{ type: undefined, decorators: [{
274
- type: Inject,
275
- args: [DOCUMENT]
276
- }] }, { type: i1.Platform }];
277
- } });
278
- /** Gets a key that can be used to look messages up in the registry. */
279
- function getKey(message, role) {
280
- return typeof message === 'string' ? `${role || ''}/${message}` : message;
281
- }
282
- /** Assigns a unique ID to an element, if it doesn't have one already. */
283
- function setMessageId(element, serviceId) {
284
- if (!element.id) {
285
- element.id = `${CDK_DESCRIBEDBY_ID_PREFIX}-${serviceId}-${nextId++}`;
286
- }
287
- }
288
-
289
- /**
290
- * @license
291
- * Copyright Google LLC All Rights Reserved.
292
- *
293
- * Use of this source code is governed by an MIT-style license that can be
294
- * found in the LICENSE file at https://angular.io/license
295
- */
296
- /**
297
- * This class manages keyboard events for selectable lists. If you pass it a query list
298
- * of items, it will set the active item correctly when arrow events occur.
299
- */
300
- class ListKeyManager {
301
- constructor(_items) {
302
- this._items = _items;
303
- this._activeItemIndex = -1;
304
- this._activeItem = null;
305
- this._wrap = false;
306
- this._letterKeyStream = new Subject();
307
- this._typeaheadSubscription = Subscription.EMPTY;
308
- this._vertical = true;
309
- this._allowedModifierKeys = [];
310
- this._homeAndEnd = false;
311
- this._pageUpAndDown = { enabled: false, delta: 10 };
312
- /**
313
- * Predicate function that can be used to check whether an item should be skipped
314
- * by the key manager. By default, disabled items are skipped.
315
- */
316
- this._skipPredicateFn = (item) => item.disabled;
317
- // Buffer for the letters that the user has pressed when the typeahead option is turned on.
318
- this._pressedLetters = [];
319
- /**
320
- * Stream that emits any time the TAB key is pressed, so components can react
321
- * when focus is shifted off of the list.
322
- */
323
- this.tabOut = new Subject();
324
- /** Stream that emits whenever the active item of the list manager changes. */
325
- this.change = new Subject();
326
- // We allow for the items to be an array because, in some cases, the consumer may
327
- // not have access to a QueryList of the items they want to manage (e.g. when the
328
- // items aren't being collected via `ViewChildren` or `ContentChildren`).
329
- if (_items instanceof QueryList) {
330
- this._itemChangesSubscription = _items.changes.subscribe((newItems) => {
331
- if (this._activeItem) {
332
- const itemArray = newItems.toArray();
333
- const newIndex = itemArray.indexOf(this._activeItem);
334
- if (newIndex > -1 && newIndex !== this._activeItemIndex) {
335
- this._activeItemIndex = newIndex;
336
- }
337
- }
338
- });
339
- }
340
- }
341
- /**
342
- * Sets the predicate function that determines which items should be skipped by the
343
- * list key manager.
344
- * @param predicate Function that determines whether the given item should be skipped.
345
- */
346
- skipPredicate(predicate) {
347
- this._skipPredicateFn = predicate;
348
- return this;
349
- }
350
- /**
351
- * Configures wrapping mode, which determines whether the active item will wrap to
352
- * the other end of list when there are no more items in the given direction.
353
- * @param shouldWrap Whether the list should wrap when reaching the end.
354
- */
355
- withWrap(shouldWrap = true) {
356
- this._wrap = shouldWrap;
357
- return this;
358
- }
359
- /**
360
- * Configures whether the key manager should be able to move the selection vertically.
361
- * @param enabled Whether vertical selection should be enabled.
362
- */
363
- withVerticalOrientation(enabled = true) {
364
- this._vertical = enabled;
365
- return this;
366
- }
367
- /**
368
- * Configures the key manager to move the selection horizontally.
369
- * Passing in `null` will disable horizontal movement.
370
- * @param direction Direction in which the selection can be moved.
371
- */
372
- withHorizontalOrientation(direction) {
373
- this._horizontal = direction;
374
- return this;
375
- }
376
- /**
377
- * Modifier keys which are allowed to be held down and whose default actions will be prevented
378
- * as the user is pressing the arrow keys. Defaults to not allowing any modifier keys.
379
- */
380
- withAllowedModifierKeys(keys) {
381
- this._allowedModifierKeys = keys;
382
- return this;
383
- }
384
- /**
385
- * Turns on typeahead mode which allows users to set the active item by typing.
386
- * @param debounceInterval Time to wait after the last keystroke before setting the active item.
387
- */
388
- withTypeAhead(debounceInterval = 200) {
389
- if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
390
- this._items.length &&
391
- this._items.some(item => typeof item.getLabel !== 'function')) {
392
- throw Error('ListKeyManager items in typeahead mode must implement the `getLabel` method.');
393
- }
394
- this._typeaheadSubscription.unsubscribe();
395
- // Debounce the presses of non-navigational keys, collect the ones that correspond to letters
396
- // and convert those letters back into a string. Afterwards find the first item that starts
397
- // with that string and select it.
398
- this._typeaheadSubscription = this._letterKeyStream
399
- .pipe(tap(letter => this._pressedLetters.push(letter)), debounceTime(debounceInterval), filter(() => this._pressedLetters.length > 0), map(() => this._pressedLetters.join('')))
400
- .subscribe(inputString => {
401
- const items = this._getItemsArray();
402
- // Start at 1 because we want to start searching at the item immediately
403
- // following the current active item.
404
- for (let i = 1; i < items.length + 1; i++) {
405
- const index = (this._activeItemIndex + i) % items.length;
406
- const item = items[index];
407
- if (!this._skipPredicateFn(item) &&
408
- item.getLabel().toUpperCase().trim().indexOf(inputString) === 0) {
409
- this.setActiveItem(index);
410
- break;
411
- }
412
- }
413
- this._pressedLetters = [];
414
- });
415
- return this;
416
- }
417
- /** Cancels the current typeahead sequence. */
418
- cancelTypeahead() {
419
- this._pressedLetters = [];
420
- return this;
421
- }
422
- /**
423
- * Configures the key manager to activate the first and last items
424
- * respectively when the Home or End key is pressed.
425
- * @param enabled Whether pressing the Home or End key activates the first/last item.
426
- */
427
- withHomeAndEnd(enabled = true) {
428
- this._homeAndEnd = enabled;
429
- return this;
430
- }
431
- /**
432
- * Configures the key manager to activate every 10th, configured or first/last element in up/down direction
433
- * respectively when the Page-Up or Page-Down key is pressed.
434
- * @param enabled Whether pressing the Page-Up or Page-Down key activates the first/last item.
435
- * @param delta Whether pressing the Home or End key activates the first/last item.
436
- */
437
- withPageUpDown(enabled = true, delta = 10) {
438
- this._pageUpAndDown = { enabled, delta };
439
- return this;
440
- }
441
- setActiveItem(item) {
442
- const previousActiveItem = this._activeItem;
443
- this.updateActiveItem(item);
444
- if (this._activeItem !== previousActiveItem) {
445
- this.change.next(this._activeItemIndex);
446
- }
447
- }
448
- /**
449
- * Sets the active item depending on the key event passed in.
450
- * @param event Keyboard event to be used for determining which element should be active.
451
- */
452
- onKeydown(event) {
453
- const keyCode = event.keyCode;
454
- const modifiers = ['altKey', 'ctrlKey', 'metaKey', 'shiftKey'];
455
- const isModifierAllowed = modifiers.every(modifier => {
456
- return !event[modifier] || this._allowedModifierKeys.indexOf(modifier) > -1;
457
- });
458
- switch (keyCode) {
459
- case TAB:
460
- this.tabOut.next();
461
- return;
462
- case DOWN_ARROW:
463
- if (this._vertical && isModifierAllowed) {
464
- this.setNextItemActive();
465
- break;
466
- }
467
- else {
468
- return;
469
- }
470
- case UP_ARROW:
471
- if (this._vertical && isModifierAllowed) {
472
- this.setPreviousItemActive();
473
- break;
474
- }
475
- else {
476
- return;
477
- }
478
- case RIGHT_ARROW:
479
- if (this._horizontal && isModifierAllowed) {
480
- this._horizontal === 'rtl' ? this.setPreviousItemActive() : this.setNextItemActive();
481
- break;
482
- }
483
- else {
484
- return;
485
- }
486
- case LEFT_ARROW:
487
- if (this._horizontal && isModifierAllowed) {
488
- this._horizontal === 'rtl' ? this.setNextItemActive() : this.setPreviousItemActive();
489
- break;
490
- }
491
- else {
492
- return;
493
- }
494
- case HOME:
495
- if (this._homeAndEnd && isModifierAllowed) {
496
- this.setFirstItemActive();
497
- break;
498
- }
499
- else {
500
- return;
501
- }
502
- case END:
503
- if (this._homeAndEnd && isModifierAllowed) {
504
- this.setLastItemActive();
505
- break;
506
- }
507
- else {
508
- return;
509
- }
510
- case PAGE_UP:
511
- if (this._pageUpAndDown.enabled && isModifierAllowed) {
512
- const targetIndex = this._activeItemIndex - this._pageUpAndDown.delta;
513
- this._setActiveItemByIndex(targetIndex > 0 ? targetIndex : 0, 1);
514
- break;
515
- }
516
- else {
517
- return;
518
- }
519
- case PAGE_DOWN:
520
- if (this._pageUpAndDown.enabled && isModifierAllowed) {
521
- const targetIndex = this._activeItemIndex + this._pageUpAndDown.delta;
522
- const itemsLength = this._getItemsArray().length;
523
- this._setActiveItemByIndex(targetIndex < itemsLength ? targetIndex : itemsLength - 1, -1);
524
- break;
525
- }
526
- else {
527
- return;
528
- }
529
- default:
530
- if (isModifierAllowed || hasModifierKey(event, 'shiftKey')) {
531
- // Attempt to use the `event.key` which also maps it to the user's keyboard language,
532
- // otherwise fall back to resolving alphanumeric characters via the keyCode.
533
- if (event.key && event.key.length === 1) {
534
- this._letterKeyStream.next(event.key.toLocaleUpperCase());
535
- }
536
- else if ((keyCode >= A && keyCode <= Z) || (keyCode >= ZERO && keyCode <= NINE)) {
537
- this._letterKeyStream.next(String.fromCharCode(keyCode));
538
- }
539
- }
540
- // Note that we return here, in order to avoid preventing
541
- // the default action of non-navigational keys.
542
- return;
543
- }
544
- this._pressedLetters = [];
545
- event.preventDefault();
546
- }
547
- /** Index of the currently active item. */
548
- get activeItemIndex() {
549
- return this._activeItemIndex;
550
- }
551
- /** The active item. */
552
- get activeItem() {
553
- return this._activeItem;
554
- }
555
- /** Gets whether the user is currently typing into the manager using the typeahead feature. */
556
- isTyping() {
557
- return this._pressedLetters.length > 0;
558
- }
559
- /** Sets the active item to the first enabled item in the list. */
560
- setFirstItemActive() {
561
- this._setActiveItemByIndex(0, 1);
562
- }
563
- /** Sets the active item to the last enabled item in the list. */
564
- setLastItemActive() {
565
- this._setActiveItemByIndex(this._items.length - 1, -1);
566
- }
567
- /** Sets the active item to the next enabled item in the list. */
568
- setNextItemActive() {
569
- this._activeItemIndex < 0 ? this.setFirstItemActive() : this._setActiveItemByDelta(1);
570
- }
571
- /** Sets the active item to a previous enabled item in the list. */
572
- setPreviousItemActive() {
573
- this._activeItemIndex < 0 && this._wrap
574
- ? this.setLastItemActive()
575
- : this._setActiveItemByDelta(-1);
576
- }
577
- updateActiveItem(item) {
578
- const itemArray = this._getItemsArray();
579
- const index = typeof item === 'number' ? item : itemArray.indexOf(item);
580
- const activeItem = itemArray[index];
581
- // Explicitly check for `null` and `undefined` because other falsy values are valid.
582
- this._activeItem = activeItem == null ? null : activeItem;
583
- this._activeItemIndex = index;
584
- }
585
- /** Cleans up the key manager. */
586
- destroy() {
587
- var _a;
588
- this._typeaheadSubscription.unsubscribe();
589
- (_a = this._itemChangesSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
590
- this._letterKeyStream.complete();
591
- this.tabOut.complete();
592
- this.change.complete();
593
- this._pressedLetters = [];
594
- }
595
- /**
596
- * This method sets the active item, given a list of items and the delta between the
597
- * currently active item and the new active item. It will calculate differently
598
- * depending on whether wrap mode is turned on.
599
- */
600
- _setActiveItemByDelta(delta) {
601
- this._wrap ? this._setActiveInWrapMode(delta) : this._setActiveInDefaultMode(delta);
602
- }
603
- /**
604
- * Sets the active item properly given "wrap" mode. In other words, it will continue to move
605
- * down the list until it finds an item that is not disabled, and it will wrap if it
606
- * encounters either end of the list.
607
- */
608
- _setActiveInWrapMode(delta) {
609
- const items = this._getItemsArray();
610
- for (let i = 1; i <= items.length; i++) {
611
- const index = (this._activeItemIndex + delta * i + items.length) % items.length;
612
- const item = items[index];
613
- if (!this._skipPredicateFn(item)) {
614
- this.setActiveItem(index);
615
- return;
616
- }
617
- }
618
- }
619
- /**
620
- * Sets the active item properly given the default mode. In other words, it will
621
- * continue to move down the list until it finds an item that is not disabled. If
622
- * it encounters either end of the list, it will stop and not wrap.
623
- */
624
- _setActiveInDefaultMode(delta) {
625
- this._setActiveItemByIndex(this._activeItemIndex + delta, delta);
626
- }
627
- /**
628
- * Sets the active item to the first enabled item starting at the index specified. If the
629
- * item is disabled, it will move in the fallbackDelta direction until it either
630
- * finds an enabled item or encounters the end of the list.
631
- */
632
- _setActiveItemByIndex(index, fallbackDelta) {
633
- const items = this._getItemsArray();
634
- if (!items[index]) {
635
- return;
636
- }
637
- while (this._skipPredicateFn(items[index])) {
638
- index += fallbackDelta;
639
- if (!items[index]) {
640
- return;
641
- }
642
- }
643
- this.setActiveItem(index);
644
- }
645
- /** Returns the items as an array. */
646
- _getItemsArray() {
647
- return this._items instanceof QueryList ? this._items.toArray() : this._items;
648
- }
649
- }
650
-
651
- /**
652
- * @license
653
- * Copyright Google LLC All Rights Reserved.
654
- *
655
- * Use of this source code is governed by an MIT-style license that can be
656
- * found in the LICENSE file at https://angular.io/license
657
- */
658
- class ActiveDescendantKeyManager extends ListKeyManager {
659
- setActiveItem(index) {
660
- if (this.activeItem) {
661
- this.activeItem.setInactiveStyles();
662
- }
663
- super.setActiveItem(index);
664
- if (this.activeItem) {
665
- this.activeItem.setActiveStyles();
666
- }
667
- }
668
- }
669
-
670
- /**
671
- * @license
672
- * Copyright Google LLC All Rights Reserved.
673
- *
674
- * Use of this source code is governed by an MIT-style license that can be
675
- * found in the LICENSE file at https://angular.io/license
676
- */
677
- class FocusKeyManager extends ListKeyManager {
678
- constructor() {
679
- super(...arguments);
680
- this._origin = 'program';
681
- }
682
- /**
683
- * Sets the focus origin that will be passed in to the items for any subsequent `focus` calls.
684
- * @param origin Focus origin to be used when focusing items.
685
- */
686
- setFocusOrigin(origin) {
687
- this._origin = origin;
688
- return this;
689
- }
690
- setActiveItem(item) {
691
- super.setActiveItem(item);
692
- if (this.activeItem) {
693
- this.activeItem.focus(this._origin);
694
- }
695
- }
696
- }
697
-
698
- /**
699
- * Configuration for the isFocusable method.
700
- */
701
- class IsFocusableConfig {
702
- constructor() {
703
- /**
704
- * Whether to count an element as focusable even if it is not currently visible.
705
- */
706
- this.ignoreVisibility = false;
707
- }
708
- }
709
- // The InteractivityChecker leans heavily on the ally.js accessibility utilities.
710
- // Methods like `isTabbable` are only covering specific edge-cases for the browsers which are
711
- // supported.
712
- /**
713
- * Utility for checking the interactivity of an element, such as whether is is focusable or
714
- * tabbable.
715
- */
716
- class InteractivityChecker {
717
- constructor(_platform) {
718
- this._platform = _platform;
719
- }
720
- /**
721
- * Gets whether an element is disabled.
722
- *
723
- * @param element Element to be checked.
724
- * @returns Whether the element is disabled.
725
- */
726
- isDisabled(element) {
727
- // This does not capture some cases, such as a non-form control with a disabled attribute or
728
- // a form control inside of a disabled form, but should capture the most common cases.
729
- return element.hasAttribute('disabled');
730
- }
731
- /**
732
- * Gets whether an element is visible for the purposes of interactivity.
733
- *
734
- * This will capture states like `display: none` and `visibility: hidden`, but not things like
735
- * being clipped by an `overflow: hidden` parent or being outside the viewport.
736
- *
737
- * @returns Whether the element is visible.
738
- */
739
- isVisible(element) {
740
- return hasGeometry(element) && getComputedStyle(element).visibility === 'visible';
741
- }
742
- /**
743
- * Gets whether an element can be reached via Tab key.
744
- * Assumes that the element has already been checked with isFocusable.
745
- *
746
- * @param element Element to be checked.
747
- * @returns Whether the element is tabbable.
748
- */
749
- isTabbable(element) {
750
- // Nothing is tabbable on the server 😎
751
- if (!this._platform.isBrowser) {
752
- return false;
753
- }
754
- const frameElement = getFrameElement(getWindow(element));
755
- if (frameElement) {
756
- // Frame elements inherit their tabindex onto all child elements.
757
- if (getTabIndexValue(frameElement) === -1) {
758
- return false;
759
- }
760
- // Browsers disable tabbing to an element inside of an invisible frame.
761
- if (!this.isVisible(frameElement)) {
762
- return false;
763
- }
764
- }
765
- let nodeName = element.nodeName.toLowerCase();
766
- let tabIndexValue = getTabIndexValue(element);
767
- if (element.hasAttribute('contenteditable')) {
768
- return tabIndexValue !== -1;
769
- }
770
- if (nodeName === 'iframe' || nodeName === 'object') {
771
- // The frame or object's content may be tabbable depending on the content, but it's
772
- // not possibly to reliably detect the content of the frames. We always consider such
773
- // elements as non-tabbable.
774
- return false;
775
- }
776
- // In iOS, the browser only considers some specific elements as tabbable.
777
- if (this._platform.WEBKIT && this._platform.IOS && !isPotentiallyTabbableIOS(element)) {
778
- return false;
779
- }
780
- if (nodeName === 'audio') {
781
- // Audio elements without controls enabled are never tabbable, regardless
782
- // of the tabindex attribute explicitly being set.
783
- if (!element.hasAttribute('controls')) {
784
- return false;
785
- }
786
- // Audio elements with controls are by default tabbable unless the
787
- // tabindex attribute is set to `-1` explicitly.
788
- return tabIndexValue !== -1;
789
- }
790
- if (nodeName === 'video') {
791
- // For all video elements, if the tabindex attribute is set to `-1`, the video
792
- // is not tabbable. Note: We cannot rely on the default `HTMLElement.tabIndex`
793
- // property as that one is set to `-1` in Chrome, Edge and Safari v13.1. The
794
- // tabindex attribute is the source of truth here.
795
- if (tabIndexValue === -1) {
796
- return false;
797
- }
798
- // If the tabindex is explicitly set, and not `-1` (as per check before), the
799
- // video element is always tabbable (regardless of whether it has controls or not).
800
- if (tabIndexValue !== null) {
801
- return true;
802
- }
803
- // Otherwise (when no explicit tabindex is set), a video is only tabbable if it
804
- // has controls enabled. Firefox is special as videos are always tabbable regardless
805
- // of whether there are controls or not.
806
- return this._platform.FIREFOX || element.hasAttribute('controls');
807
- }
808
- return element.tabIndex >= 0;
809
- }
810
- /**
811
- * Gets whether an element can be focused by the user.
812
- *
813
- * @param element Element to be checked.
814
- * @param config The config object with options to customize this method's behavior
815
- * @returns Whether the element is focusable.
816
- */
817
- isFocusable(element, config) {
818
- // Perform checks in order of left to most expensive.
819
- // Again, naive approach that does not capture many edge cases and browser quirks.
820
- return (isPotentiallyFocusable(element) &&
821
- !this.isDisabled(element) &&
822
- ((config === null || config === void 0 ? void 0 : config.ignoreVisibility) || this.isVisible(element)));
823
- }
824
- }
825
- InteractivityChecker.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: InteractivityChecker, deps: [{ token: i1.Platform }], target: i0.ɵɵFactoryTarget.Injectable });
826
- InteractivityChecker.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: InteractivityChecker, providedIn: 'root' });
827
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: InteractivityChecker, decorators: [{
828
- type: Injectable,
829
- args: [{ providedIn: 'root' }]
830
- }], ctorParameters: function () { return [{ type: i1.Platform }]; } });
831
- /**
832
- * Returns the frame element from a window object. Since browsers like MS Edge throw errors if
833
- * the frameElement property is being accessed from a different host address, this property
834
- * should be accessed carefully.
835
- */
836
- function getFrameElement(window) {
837
- try {
838
- return window.frameElement;
839
- }
840
- catch (_a) {
841
- return null;
842
- }
843
- }
844
- /** Checks whether the specified element has any geometry / rectangles. */
845
- function hasGeometry(element) {
846
- // Use logic from jQuery to check for an invisible element.
847
- // See https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js#L12
848
- return !!(element.offsetWidth ||
849
- element.offsetHeight ||
850
- (typeof element.getClientRects === 'function' && element.getClientRects().length));
851
- }
852
- /** Gets whether an element's */
853
- function isNativeFormElement(element) {
854
- let nodeName = element.nodeName.toLowerCase();
855
- return (nodeName === 'input' ||
856
- nodeName === 'select' ||
857
- nodeName === 'button' ||
858
- nodeName === 'textarea');
859
- }
860
- /** Gets whether an element is an `<input type="hidden">`. */
861
- function isHiddenInput(element) {
862
- return isInputElement(element) && element.type == 'hidden';
863
- }
864
- /** Gets whether an element is an anchor that has an href attribute. */
865
- function isAnchorWithHref(element) {
866
- return isAnchorElement(element) && element.hasAttribute('href');
867
- }
868
- /** Gets whether an element is an input element. */
869
- function isInputElement(element) {
870
- return element.nodeName.toLowerCase() == 'input';
871
- }
872
- /** Gets whether an element is an anchor element. */
873
- function isAnchorElement(element) {
874
- return element.nodeName.toLowerCase() == 'a';
875
- }
876
- /** Gets whether an element has a valid tabindex. */
877
- function hasValidTabIndex(element) {
878
- if (!element.hasAttribute('tabindex') || element.tabIndex === undefined) {
879
- return false;
880
- }
881
- let tabIndex = element.getAttribute('tabindex');
882
- return !!(tabIndex && !isNaN(parseInt(tabIndex, 10)));
883
- }
884
- /**
885
- * Returns the parsed tabindex from the element attributes instead of returning the
886
- * evaluated tabindex from the browsers defaults.
887
- */
888
- function getTabIndexValue(element) {
889
- if (!hasValidTabIndex(element)) {
890
- return null;
891
- }
892
- // See browser issue in Gecko https://bugzilla.mozilla.org/show_bug.cgi?id=1128054
893
- const tabIndex = parseInt(element.getAttribute('tabindex') || '', 10);
894
- return isNaN(tabIndex) ? -1 : tabIndex;
895
- }
896
- /** Checks whether the specified element is potentially tabbable on iOS */
897
- function isPotentiallyTabbableIOS(element) {
898
- let nodeName = element.nodeName.toLowerCase();
899
- let inputType = nodeName === 'input' && element.type;
900
- return (inputType === 'text' ||
901
- inputType === 'password' ||
902
- nodeName === 'select' ||
903
- nodeName === 'textarea');
904
- }
905
- /**
906
- * Gets whether an element is potentially focusable without taking current visible/disabled state
907
- * into account.
908
- */
909
- function isPotentiallyFocusable(element) {
910
- // Inputs are potentially focusable *unless* they're type="hidden".
911
- if (isHiddenInput(element)) {
912
- return false;
913
- }
914
- return (isNativeFormElement(element) ||
915
- isAnchorWithHref(element) ||
916
- element.hasAttribute('contenteditable') ||
917
- hasValidTabIndex(element));
918
- }
919
- /** Gets the parent window of a DOM node with regards of being inside of an iframe. */
920
- function getWindow(node) {
921
- // ownerDocument is null if `node` itself *is* a document.
922
- return (node.ownerDocument && node.ownerDocument.defaultView) || window;
923
- }
924
-
925
- /**
926
- * @license
927
- * Copyright Google LLC All Rights Reserved.
928
- *
929
- * Use of this source code is governed by an MIT-style license that can be
930
- * found in the LICENSE file at https://angular.io/license
931
- */
932
- /**
933
- * Class that allows for trapping focus within a DOM element.
934
- *
935
- * This class currently uses a relatively simple approach to focus trapping.
936
- * It assumes that the tab order is the same as DOM order, which is not necessarily true.
937
- * Things like `tabIndex > 0`, flex `order`, and shadow roots can cause the two to be misaligned.
938
- *
939
- * @deprecated Use `ConfigurableFocusTrap` instead.
940
- * @breaking-change 11.0.0
941
- */
942
- class FocusTrap {
943
- /** Whether the focus trap is active. */
944
- get enabled() {
945
- return this._enabled;
946
- }
947
- set enabled(value) {
948
- this._enabled = value;
949
- if (this._startAnchor && this._endAnchor) {
950
- this._toggleAnchorTabIndex(value, this._startAnchor);
951
- this._toggleAnchorTabIndex(value, this._endAnchor);
952
- }
953
- }
954
- constructor(_element, _checker, _ngZone, _document, deferAnchors = false) {
955
- this._element = _element;
956
- this._checker = _checker;
957
- this._ngZone = _ngZone;
958
- this._document = _document;
959
- this._hasAttached = false;
960
- // Event listeners for the anchors. Need to be regular functions so that we can unbind them later.
961
- this.startAnchorListener = () => this.focusLastTabbableElement();
962
- this.endAnchorListener = () => this.focusFirstTabbableElement();
963
- this._enabled = true;
964
- if (!deferAnchors) {
965
- this.attachAnchors();
966
- }
967
- }
968
- /** Destroys the focus trap by cleaning up the anchors. */
969
- destroy() {
970
- const startAnchor = this._startAnchor;
971
- const endAnchor = this._endAnchor;
972
- if (startAnchor) {
973
- startAnchor.removeEventListener('focus', this.startAnchorListener);
974
- startAnchor.remove();
975
- }
976
- if (endAnchor) {
977
- endAnchor.removeEventListener('focus', this.endAnchorListener);
978
- endAnchor.remove();
979
- }
980
- this._startAnchor = this._endAnchor = null;
981
- this._hasAttached = false;
982
- }
983
- /**
984
- * Inserts the anchors into the DOM. This is usually done automatically
985
- * in the constructor, but can be deferred for cases like directives with `*ngIf`.
986
- * @returns Whether the focus trap managed to attach successfully. This may not be the case
987
- * if the target element isn't currently in the DOM.
988
- */
989
- attachAnchors() {
990
- // If we're not on the browser, there can be no focus to trap.
991
- if (this._hasAttached) {
992
- return true;
993
- }
994
- this._ngZone.runOutsideAngular(() => {
995
- if (!this._startAnchor) {
996
- this._startAnchor = this._createAnchor();
997
- this._startAnchor.addEventListener('focus', this.startAnchorListener);
998
- }
999
- if (!this._endAnchor) {
1000
- this._endAnchor = this._createAnchor();
1001
- this._endAnchor.addEventListener('focus', this.endAnchorListener);
1002
- }
1003
- });
1004
- if (this._element.parentNode) {
1005
- this._element.parentNode.insertBefore(this._startAnchor, this._element);
1006
- this._element.parentNode.insertBefore(this._endAnchor, this._element.nextSibling);
1007
- this._hasAttached = true;
1008
- }
1009
- return this._hasAttached;
1010
- }
1011
- /**
1012
- * Waits for the zone to stabilize, then focuses the first tabbable element.
1013
- * @returns Returns a promise that resolves with a boolean, depending
1014
- * on whether focus was moved successfully.
1015
- */
1016
- focusInitialElementWhenReady(options) {
1017
- return new Promise(resolve => {
1018
- this._executeOnStable(() => resolve(this.focusInitialElement(options)));
1019
- });
1020
- }
1021
- /**
1022
- * Waits for the zone to stabilize, then focuses
1023
- * the first tabbable element within the focus trap region.
1024
- * @returns Returns a promise that resolves with a boolean, depending
1025
- * on whether focus was moved successfully.
1026
- */
1027
- focusFirstTabbableElementWhenReady(options) {
1028
- return new Promise(resolve => {
1029
- this._executeOnStable(() => resolve(this.focusFirstTabbableElement(options)));
1030
- });
1031
- }
1032
- /**
1033
- * Waits for the zone to stabilize, then focuses
1034
- * the last tabbable element within the focus trap region.
1035
- * @returns Returns a promise that resolves with a boolean, depending
1036
- * on whether focus was moved successfully.
1037
- */
1038
- focusLastTabbableElementWhenReady(options) {
1039
- return new Promise(resolve => {
1040
- this._executeOnStable(() => resolve(this.focusLastTabbableElement(options)));
1041
- });
1042
- }
1043
- /**
1044
- * Get the specified boundary element of the trapped region.
1045
- * @param bound The boundary to get (start or end of trapped region).
1046
- * @returns The boundary element.
1047
- */
1048
- _getRegionBoundary(bound) {
1049
- // Contains the deprecated version of selector, for temporary backwards comparability.
1050
- const markers = this._element.querySelectorAll(`[cdk-focus-region-${bound}], ` + `[cdkFocusRegion${bound}], ` + `[cdk-focus-${bound}]`);
1051
- if (typeof ngDevMode === 'undefined' || ngDevMode) {
1052
- for (let i = 0; i < markers.length; i++) {
1053
- // @breaking-change 8.0.0
1054
- if (markers[i].hasAttribute(`cdk-focus-${bound}`)) {
1055
- console.warn(`Found use of deprecated attribute 'cdk-focus-${bound}', ` +
1056
- `use 'cdkFocusRegion${bound}' instead. The deprecated ` +
1057
- `attribute will be removed in 8.0.0.`, markers[i]);
1058
- }
1059
- else if (markers[i].hasAttribute(`cdk-focus-region-${bound}`)) {
1060
- console.warn(`Found use of deprecated attribute 'cdk-focus-region-${bound}', ` +
1061
- `use 'cdkFocusRegion${bound}' instead. The deprecated attribute ` +
1062
- `will be removed in 8.0.0.`, markers[i]);
1063
- }
1064
- }
1065
- }
1066
- if (bound == 'start') {
1067
- return markers.length ? markers[0] : this._getFirstTabbableElement(this._element);
1068
- }
1069
- return markers.length
1070
- ? markers[markers.length - 1]
1071
- : this._getLastTabbableElement(this._element);
1072
- }
1073
- /**
1074
- * Focuses the element that should be focused when the focus trap is initialized.
1075
- * @returns Whether focus was moved successfully.
1076
- */
1077
- focusInitialElement(options) {
1078
- // Contains the deprecated version of selector, for temporary backwards comparability.
1079
- const redirectToElement = this._element.querySelector(`[cdk-focus-initial], ` + `[cdkFocusInitial]`);
1080
- if (redirectToElement) {
1081
- // @breaking-change 8.0.0
1082
- if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
1083
- redirectToElement.hasAttribute(`cdk-focus-initial`)) {
1084
- console.warn(`Found use of deprecated attribute 'cdk-focus-initial', ` +
1085
- `use 'cdkFocusInitial' instead. The deprecated attribute ` +
1086
- `will be removed in 8.0.0`, redirectToElement);
1087
- }
1088
- // Warn the consumer if the element they've pointed to
1089
- // isn't focusable, when not in production mode.
1090
- if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
1091
- !this._checker.isFocusable(redirectToElement)) {
1092
- console.warn(`Element matching '[cdkFocusInitial]' is not focusable.`, redirectToElement);
1093
- }
1094
- if (!this._checker.isFocusable(redirectToElement)) {
1095
- const focusableChild = this._getFirstTabbableElement(redirectToElement);
1096
- focusableChild === null || focusableChild === void 0 ? void 0 : focusableChild.focus(options);
1097
- return !!focusableChild;
1098
- }
1099
- redirectToElement.focus(options);
1100
- return true;
1101
- }
1102
- return this.focusFirstTabbableElement(options);
1103
- }
1104
- /**
1105
- * Focuses the first tabbable element within the focus trap region.
1106
- * @returns Whether focus was moved successfully.
1107
- */
1108
- focusFirstTabbableElement(options) {
1109
- const redirectToElement = this._getRegionBoundary('start');
1110
- if (redirectToElement) {
1111
- redirectToElement.focus(options);
1112
- }
1113
- return !!redirectToElement;
1114
- }
1115
- /**
1116
- * Focuses the last tabbable element within the focus trap region.
1117
- * @returns Whether focus was moved successfully.
1118
- */
1119
- focusLastTabbableElement(options) {
1120
- const redirectToElement = this._getRegionBoundary('end');
1121
- if (redirectToElement) {
1122
- redirectToElement.focus(options);
1123
- }
1124
- return !!redirectToElement;
1125
- }
1126
- /**
1127
- * Checks whether the focus trap has successfully been attached.
1128
- */
1129
- hasAttached() {
1130
- return this._hasAttached;
1131
- }
1132
- /** Get the first tabbable element from a DOM subtree (inclusive). */
1133
- _getFirstTabbableElement(root) {
1134
- if (this._checker.isFocusable(root) && this._checker.isTabbable(root)) {
1135
- return root;
1136
- }
1137
- const children = root.children;
1138
- for (let i = 0; i < children.length; i++) {
1139
- const tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE
1140
- ? this._getFirstTabbableElement(children[i])
1141
- : null;
1142
- if (tabbableChild) {
1143
- return tabbableChild;
1144
- }
1145
- }
1146
- return null;
1147
- }
1148
- /** Get the last tabbable element from a DOM subtree (inclusive). */
1149
- _getLastTabbableElement(root) {
1150
- if (this._checker.isFocusable(root) && this._checker.isTabbable(root)) {
1151
- return root;
1152
- }
1153
- // Iterate in reverse DOM order.
1154
- const children = root.children;
1155
- for (let i = children.length - 1; i >= 0; i--) {
1156
- const tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE
1157
- ? this._getLastTabbableElement(children[i])
1158
- : null;
1159
- if (tabbableChild) {
1160
- return tabbableChild;
1161
- }
1162
- }
1163
- return null;
1164
- }
1165
- /** Creates an anchor element. */
1166
- _createAnchor() {
1167
- const anchor = this._document.createElement('div');
1168
- this._toggleAnchorTabIndex(this._enabled, anchor);
1169
- anchor.classList.add('cdk-visually-hidden');
1170
- anchor.classList.add('cdk-focus-trap-anchor');
1171
- anchor.setAttribute('aria-hidden', 'true');
1172
- return anchor;
1173
- }
1174
- /**
1175
- * Toggles the `tabindex` of an anchor, based on the enabled state of the focus trap.
1176
- * @param isEnabled Whether the focus trap is enabled.
1177
- * @param anchor Anchor on which to toggle the tabindex.
1178
- */
1179
- _toggleAnchorTabIndex(isEnabled, anchor) {
1180
- // Remove the tabindex completely, rather than setting it to -1, because if the
1181
- // element has a tabindex, the user might still hit it when navigating with the arrow keys.
1182
- isEnabled ? anchor.setAttribute('tabindex', '0') : anchor.removeAttribute('tabindex');
1183
- }
1184
- /**
1185
- * Toggles the`tabindex` of both anchors to either trap Tab focus or allow it to escape.
1186
- * @param enabled: Whether the anchors should trap Tab.
1187
- */
1188
- toggleAnchors(enabled) {
1189
- if (this._startAnchor && this._endAnchor) {
1190
- this._toggleAnchorTabIndex(enabled, this._startAnchor);
1191
- this._toggleAnchorTabIndex(enabled, this._endAnchor);
1192
- }
1193
- }
1194
- /** Executes a function when the zone is stable. */
1195
- _executeOnStable(fn) {
1196
- if (this._ngZone.isStable) {
1197
- fn();
1198
- }
1199
- else {
1200
- this._ngZone.onStable.pipe(take(1)).subscribe(fn);
1201
- }
1202
- }
1203
- }
1204
- /**
1205
- * Factory that allows easy instantiation of focus traps.
1206
- * @deprecated Use `ConfigurableFocusTrapFactory` instead.
1207
- * @breaking-change 11.0.0
1208
- */
1209
- class FocusTrapFactory {
1210
- constructor(_checker, _ngZone, _document) {
1211
- this._checker = _checker;
1212
- this._ngZone = _ngZone;
1213
- this._document = _document;
1214
- }
1215
- /**
1216
- * Creates a focus-trapped region around the given element.
1217
- * @param element The element around which focus will be trapped.
1218
- * @param deferCaptureElements Defers the creation of focus-capturing elements to be done
1219
- * manually by the user.
1220
- * @returns The created focus trap instance.
1221
- */
1222
- create(element, deferCaptureElements = false) {
1223
- return new FocusTrap(element, this._checker, this._ngZone, this._document, deferCaptureElements);
1224
- }
1225
- }
1226
- FocusTrapFactory.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: FocusTrapFactory, deps: [{ token: InteractivityChecker }, { token: i0.NgZone }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
1227
- FocusTrapFactory.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: FocusTrapFactory, providedIn: 'root' });
1228
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: FocusTrapFactory, decorators: [{
1229
- type: Injectable,
1230
- args: [{ providedIn: 'root' }]
1231
- }], ctorParameters: function () {
1232
- return [{ type: InteractivityChecker }, { type: i0.NgZone }, { type: undefined, decorators: [{
1233
- type: Inject,
1234
- args: [DOCUMENT]
1235
- }] }];
1236
- } });
1237
- /** Directive for trapping focus within a region. */
1238
- class CdkTrapFocus {
1239
- /** Whether the focus trap is active. */
1240
- get enabled() {
1241
- return this.focusTrap.enabled;
1242
- }
1243
- set enabled(value) {
1244
- this.focusTrap.enabled = coerceBooleanProperty(value);
1245
- }
1246
- /**
1247
- * Whether the directive should automatically move focus into the trapped region upon
1248
- * initialization and return focus to the previous activeElement upon destruction.
1249
- */
1250
- get autoCapture() {
1251
- return this._autoCapture;
1252
- }
1253
- set autoCapture(value) {
1254
- this._autoCapture = coerceBooleanProperty(value);
1255
- }
1256
- constructor(_elementRef, _focusTrapFactory,
1257
- /**
1258
- * @deprecated No longer being used. To be removed.
1259
- * @breaking-change 13.0.0
1260
- */
1261
- _document) {
1262
- this._elementRef = _elementRef;
1263
- this._focusTrapFactory = _focusTrapFactory;
1264
- /** Previously focused element to restore focus to upon destroy when using autoCapture. */
1265
- this._previouslyFocusedElement = null;
1266
- this.focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement, true);
1267
- }
1268
- ngOnDestroy() {
1269
- this.focusTrap.destroy();
1270
- // If we stored a previously focused element when using autoCapture, return focus to that
1271
- // element now that the trapped region is being destroyed.
1272
- if (this._previouslyFocusedElement) {
1273
- this._previouslyFocusedElement.focus();
1274
- this._previouslyFocusedElement = null;
1275
- }
1276
- }
1277
- ngAfterContentInit() {
1278
- this.focusTrap.attachAnchors();
1279
- if (this.autoCapture) {
1280
- this._captureFocus();
1281
- }
1282
- }
1283
- ngDoCheck() {
1284
- if (!this.focusTrap.hasAttached()) {
1285
- this.focusTrap.attachAnchors();
1286
- }
1287
- }
1288
- ngOnChanges(changes) {
1289
- const autoCaptureChange = changes['autoCapture'];
1290
- if (autoCaptureChange &&
1291
- !autoCaptureChange.firstChange &&
1292
- this.autoCapture &&
1293
- this.focusTrap.hasAttached()) {
1294
- this._captureFocus();
1295
- }
1296
- }
1297
- _captureFocus() {
1298
- this._previouslyFocusedElement = _getFocusedElementPierceShadowDom();
1299
- this.focusTrap.focusInitialElementWhenReady();
1300
- }
1301
- }
1302
- CdkTrapFocus.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: CdkTrapFocus, deps: [{ token: i0.ElementRef }, { token: FocusTrapFactory }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive });
1303
- CdkTrapFocus.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0-next.2", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: { enabled: ["cdkTrapFocus", "enabled"], autoCapture: ["cdkTrapFocusAutoCapture", "autoCapture"] }, exportAs: ["cdkTrapFocus"], usesOnChanges: true, ngImport: i0 });
1304
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: CdkTrapFocus, decorators: [{
1305
- type: Directive,
1306
- args: [{
1307
- selector: '[cdkTrapFocus]',
1308
- exportAs: 'cdkTrapFocus',
1309
- }]
1310
- }], ctorParameters: function () {
1311
- return [{ type: i0.ElementRef }, { type: FocusTrapFactory }, { type: undefined, decorators: [{
1312
- type: Inject,
1313
- args: [DOCUMENT]
1314
- }] }];
1315
- }, propDecorators: { enabled: [{
1316
- type: Input,
1317
- args: ['cdkTrapFocus']
1318
- }], autoCapture: [{
1319
- type: Input,
1320
- args: ['cdkTrapFocusAutoCapture']
1321
- }] } });
1322
-
1323
- /**
1324
- * @license
1325
- * Copyright Google LLC All Rights Reserved.
1326
- *
1327
- * Use of this source code is governed by an MIT-style license that can be
1328
- * found in the LICENSE file at https://angular.io/license
1329
- */
1330
- /**
1331
- * Class that allows for trapping focus within a DOM element.
1332
- *
1333
- * This class uses a strategy pattern that determines how it traps focus.
1334
- * See FocusTrapInertStrategy.
1335
- */
1336
- class ConfigurableFocusTrap extends FocusTrap {
1337
- /** Whether the FocusTrap is enabled. */
1338
- get enabled() {
1339
- return this._enabled;
1340
- }
1341
- set enabled(value) {
1342
- this._enabled = value;
1343
- if (this._enabled) {
1344
- this._focusTrapManager.register(this);
1345
- }
1346
- else {
1347
- this._focusTrapManager.deregister(this);
1348
- }
1349
- }
1350
- constructor(_element, _checker, _ngZone, _document, _focusTrapManager, _inertStrategy, config) {
1351
- super(_element, _checker, _ngZone, _document, config.defer);
1352
- this._focusTrapManager = _focusTrapManager;
1353
- this._inertStrategy = _inertStrategy;
1354
- this._focusTrapManager.register(this);
1355
- }
1356
- /** Notifies the FocusTrapManager that this FocusTrap will be destroyed. */
1357
- destroy() {
1358
- this._focusTrapManager.deregister(this);
1359
- super.destroy();
1360
- }
1361
- /** @docs-private Implemented as part of ManagedFocusTrap. */
1362
- _enable() {
1363
- this._inertStrategy.preventFocus(this);
1364
- this.toggleAnchors(true);
1365
- }
1366
- /** @docs-private Implemented as part of ManagedFocusTrap. */
1367
- _disable() {
1368
- this._inertStrategy.allowFocus(this);
1369
- this.toggleAnchors(false);
1370
- }
1371
- }
1372
-
1373
- /**
1374
- * @license
1375
- * Copyright Google LLC All Rights Reserved.
1376
- *
1377
- * Use of this source code is governed by an MIT-style license that can be
1378
- * found in the LICENSE file at https://angular.io/license
1379
- */
1380
- /** The injection token used to specify the inert strategy. */
1381
- const FOCUS_TRAP_INERT_STRATEGY = new InjectionToken('FOCUS_TRAP_INERT_STRATEGY');
1382
-
1383
- /**
1384
- * @license
1385
- * Copyright Google LLC All Rights Reserved.
1386
- *
1387
- * Use of this source code is governed by an MIT-style license that can be
1388
- * found in the LICENSE file at https://angular.io/license
1389
- */
1390
- /**
1391
- * Lightweight FocusTrapInertStrategy that adds a document focus event
1392
- * listener to redirect focus back inside the FocusTrap.
1393
- */
1394
- class EventListenerFocusTrapInertStrategy {
1395
- constructor() {
1396
- /** Focus event handler. */
1397
- this._listener = null;
1398
- }
1399
- /** Adds a document event listener that keeps focus inside the FocusTrap. */
1400
- preventFocus(focusTrap) {
1401
- // Ensure there's only one listener per document
1402
- if (this._listener) {
1403
- focusTrap._document.removeEventListener('focus', this._listener, true);
1404
- }
1405
- this._listener = (e) => this._trapFocus(focusTrap, e);
1406
- focusTrap._ngZone.runOutsideAngular(() => {
1407
- focusTrap._document.addEventListener('focus', this._listener, true);
1408
- });
1409
- }
1410
- /** Removes the event listener added in preventFocus. */
1411
- allowFocus(focusTrap) {
1412
- if (!this._listener) {
1413
- return;
1414
- }
1415
- focusTrap._document.removeEventListener('focus', this._listener, true);
1416
- this._listener = null;
1417
- }
1418
- /**
1419
- * Refocuses the first element in the FocusTrap if the focus event target was outside
1420
- * the FocusTrap.
1421
- *
1422
- * This is an event listener callback. The event listener is added in runOutsideAngular,
1423
- * so all this code runs outside Angular as well.
1424
- */
1425
- _trapFocus(focusTrap, event) {
1426
- var _a;
1427
- const target = event.target;
1428
- const focusTrapRoot = focusTrap._element;
1429
- // Don't refocus if target was in an overlay, because the overlay might be associated
1430
- // with an element inside the FocusTrap, ex. mat-select.
1431
- if (target && !focusTrapRoot.contains(target) && !((_a = target.closest) === null || _a === void 0 ? void 0 : _a.call(target, 'div.cdk-overlay-pane'))) {
1432
- // Some legacy FocusTrap usages have logic that focuses some element on the page
1433
- // just before FocusTrap is destroyed. For backwards compatibility, wait
1434
- // to be sure FocusTrap is still enabled before refocusing.
1435
- setTimeout(() => {
1436
- // Check whether focus wasn't put back into the focus trap while the timeout was pending.
1437
- if (focusTrap.enabled && !focusTrapRoot.contains(focusTrap._document.activeElement)) {
1438
- focusTrap.focusFirstTabbableElement();
1439
- }
1440
- });
1441
- }
1442
- }
1443
- }
1444
-
1445
- /**
1446
- * @license
1447
- * Copyright Google LLC All Rights Reserved.
1448
- *
1449
- * Use of this source code is governed by an MIT-style license that can be
1450
- * found in the LICENSE file at https://angular.io/license
1451
- */
1452
- /** Injectable that ensures only the most recently enabled FocusTrap is active. */
1453
- class FocusTrapManager {
1454
- constructor() {
1455
- // A stack of the FocusTraps on the page. Only the FocusTrap at the
1456
- // top of the stack is active.
1457
- this._focusTrapStack = [];
1458
- }
1459
- /**
1460
- * Disables the FocusTrap at the top of the stack, and then pushes
1461
- * the new FocusTrap onto the stack.
1462
- */
1463
- register(focusTrap) {
1464
- // Dedupe focusTraps that register multiple times.
1465
- this._focusTrapStack = this._focusTrapStack.filter(ft => ft !== focusTrap);
1466
- let stack = this._focusTrapStack;
1467
- if (stack.length) {
1468
- stack[stack.length - 1]._disable();
1469
- }
1470
- stack.push(focusTrap);
1471
- focusTrap._enable();
1472
- }
1473
- /**
1474
- * Removes the FocusTrap from the stack, and activates the
1475
- * FocusTrap that is the new top of the stack.
1476
- */
1477
- deregister(focusTrap) {
1478
- focusTrap._disable();
1479
- const stack = this._focusTrapStack;
1480
- const i = stack.indexOf(focusTrap);
1481
- if (i !== -1) {
1482
- stack.splice(i, 1);
1483
- if (stack.length) {
1484
- stack[stack.length - 1]._enable();
1485
- }
1486
- }
1487
- }
1488
- }
1489
- FocusTrapManager.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: FocusTrapManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1490
- FocusTrapManager.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: FocusTrapManager, providedIn: 'root' });
1491
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: FocusTrapManager, decorators: [{
1492
- type: Injectable,
1493
- args: [{ providedIn: 'root' }]
1494
- }] });
1495
-
1496
- /**
1497
- * @license
1498
- * Copyright Google LLC All Rights Reserved.
1499
- *
1500
- * Use of this source code is governed by an MIT-style license that can be
1501
- * found in the LICENSE file at https://angular.io/license
1502
- */
1503
- /** Factory that allows easy instantiation of configurable focus traps. */
1504
- class ConfigurableFocusTrapFactory {
1505
- constructor(_checker, _ngZone, _focusTrapManager, _document, _inertStrategy) {
1506
- this._checker = _checker;
1507
- this._ngZone = _ngZone;
1508
- this._focusTrapManager = _focusTrapManager;
1509
- this._document = _document;
1510
- // TODO split up the strategies into different modules, similar to DateAdapter.
1511
- this._inertStrategy = _inertStrategy || new EventListenerFocusTrapInertStrategy();
1512
- }
1513
- create(element, config = { defer: false }) {
1514
- let configObject;
1515
- if (typeof config === 'boolean') {
1516
- configObject = { defer: config };
1517
- }
1518
- else {
1519
- configObject = config;
1520
- }
1521
- return new ConfigurableFocusTrap(element, this._checker, this._ngZone, this._document, this._focusTrapManager, this._inertStrategy, configObject);
1522
- }
1523
- }
1524
- ConfigurableFocusTrapFactory.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: ConfigurableFocusTrapFactory, deps: [{ token: InteractivityChecker }, { token: i0.NgZone }, { token: FocusTrapManager }, { token: DOCUMENT }, { token: FOCUS_TRAP_INERT_STRATEGY, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
1525
- ConfigurableFocusTrapFactory.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: ConfigurableFocusTrapFactory, providedIn: 'root' });
1526
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: ConfigurableFocusTrapFactory, decorators: [{
1527
- type: Injectable,
1528
- args: [{ providedIn: 'root' }]
1529
- }], ctorParameters: function () {
1530
- return [{ type: InteractivityChecker }, { type: i0.NgZone }, { type: FocusTrapManager }, { type: undefined, decorators: [{
1531
- type: Inject,
1532
- args: [DOCUMENT]
1533
- }] }, { type: undefined, decorators: [{
1534
- type: Optional
1535
- }, {
1536
- type: Inject,
1537
- args: [FOCUS_TRAP_INERT_STRATEGY]
1538
- }] }];
1539
- } });
1540
-
1541
- /**
1542
- * @license
1543
- * Copyright Google LLC All Rights Reserved.
1544
- *
1545
- * Use of this source code is governed by an MIT-style license that can be
1546
- * found in the LICENSE file at https://angular.io/license
1547
- */
1548
- /** Gets whether an event could be a faked `mousedown` event dispatched by a screen reader. */
1549
- function isFakeMousedownFromScreenReader(event) {
1550
- // Some screen readers will dispatch a fake `mousedown` event when pressing enter or space on
1551
- // a clickable element. We can distinguish these events when both `offsetX` and `offsetY` are
1552
- // zero or `event.buttons` is zero, depending on the browser:
1553
- // - `event.buttons` works on Firefox, but fails on Chrome.
1554
- // - `offsetX` and `offsetY` work on Chrome, but fail on Firefox.
1555
- // Note that there's an edge case where the user could click the 0x0 spot of the
1556
- // screen themselves, but that is unlikely to contain interactive elements.
1557
- return event.buttons === 0 || (event.offsetX === 0 && event.offsetY === 0);
1558
- }
1559
- /** Gets whether an event could be a faked `touchstart` event dispatched by a screen reader. */
1560
- function isFakeTouchstartFromScreenReader(event) {
1561
- const touch = (event.touches && event.touches[0]) || (event.changedTouches && event.changedTouches[0]);
1562
- // A fake `touchstart` can be distinguished from a real one by looking at the `identifier`
1563
- // which is typically >= 0 on a real device versus -1 from a screen reader. Just to be safe,
1564
- // we can also look at `radiusX` and `radiusY`. This behavior was observed against a Windows 10
1565
- // device with a touch screen running NVDA v2020.4 and Firefox 85 or Chrome 88.
1566
- return (!!touch &&
1567
- touch.identifier === -1 &&
1568
- (touch.radiusX == null || touch.radiusX === 1) &&
1569
- (touch.radiusY == null || touch.radiusY === 1));
1570
- }
1571
-
1572
- /**
1573
- * @license
1574
- * Copyright Google LLC All Rights Reserved.
1575
- *
1576
- * Use of this source code is governed by an MIT-style license that can be
1577
- * found in the LICENSE file at https://angular.io/license
1578
- */
1579
- /**
1580
- * Injectable options for the InputModalityDetector. These are shallowly merged with the default
1581
- * options.
1582
- */
1583
- const INPUT_MODALITY_DETECTOR_OPTIONS = new InjectionToken('cdk-input-modality-detector-options');
1584
- /**
1585
- * Default options for the InputModalityDetector.
1586
- *
1587
- * Modifier keys are ignored by default (i.e. when pressed won't cause the service to detect
1588
- * keyboard input modality) for two reasons:
1589
- *
1590
- * 1. Modifier keys are commonly used with mouse to perform actions such as 'right click' or 'open
1591
- * in new tab', and are thus less representative of actual keyboard interaction.
1592
- * 2. VoiceOver triggers some keyboard events when linearly navigating with Control + Option (but
1593
- * confusingly not with Caps Lock). Thus, to have parity with other screen readers, we ignore
1594
- * these keys so as to not update the input modality.
1595
- *
1596
- * Note that we do not by default ignore the right Meta key on Safari because it has the same key
1597
- * code as the ContextMenu key on other browsers. When we switch to using event.key, we can
1598
- * distinguish between the two.
1599
- */
1600
- const INPUT_MODALITY_DETECTOR_DEFAULT_OPTIONS = {
1601
- ignoreKeys: [ALT, CONTROL, MAC_META, META, SHIFT],
1602
- };
1603
- /**
1604
- * The amount of time needed to pass after a touchstart event in order for a subsequent mousedown
1605
- * event to be attributed as mouse and not touch.
1606
- *
1607
- * This is the value used by AngularJS Material. Through trial and error (on iPhone 6S) they found
1608
- * that a value of around 650ms seems appropriate.
1609
- */
1610
- const TOUCH_BUFFER_MS = 650;
1611
- /**
1612
- * Event listener options that enable capturing and also mark the listener as passive if the browser
1613
- * supports it.
1614
- */
1615
- const modalityEventListenerOptions = normalizePassiveListenerOptions({
1616
- passive: true,
1617
- capture: true,
1618
- });
1619
- /**
1620
- * Service that detects the user's input modality.
1621
- *
1622
- * This service does not update the input modality when a user navigates with a screen reader
1623
- * (e.g. linear navigation with VoiceOver, object navigation / browse mode with NVDA, virtual PC
1624
- * cursor mode with JAWS). This is in part due to technical limitations (i.e. keyboard events do not
1625
- * fire as expected in these modes) but is also arguably the correct behavior. Navigating with a
1626
- * screen reader is akin to visually scanning a page, and should not be interpreted as actual user
1627
- * input interaction.
1628
- *
1629
- * When a user is not navigating but *interacting* with a screen reader, this service attempts to
1630
- * update the input modality to keyboard, but in general this service's behavior is largely
1631
- * undefined.
1632
- */
1633
- class InputModalityDetector {
1634
- /** The most recently detected input modality. */
1635
- get mostRecentModality() {
1636
- return this._modality.value;
1637
- }
1638
- constructor(_platform, ngZone, document, options) {
1639
- this._platform = _platform;
1640
- /**
1641
- * The most recently detected input modality event target. Is null if no input modality has been
1642
- * detected or if the associated event target is null for some unknown reason.
1643
- */
1644
- this._mostRecentTarget = null;
1645
- /** The underlying BehaviorSubject that emits whenever an input modality is detected. */
1646
- this._modality = new BehaviorSubject(null);
1647
- /**
1648
- * The timestamp of the last touch input modality. Used to determine whether mousedown events
1649
- * should be attributed to mouse or touch.
1650
- */
1651
- this._lastTouchMs = 0;
1652
- /**
1653
- * Handles keydown events. Must be an arrow function in order to preserve the context when it gets
1654
- * bound.
1655
- */
1656
- this._onKeydown = (event) => {
1657
- var _a, _b;
1658
- // If this is one of the keys we should ignore, then ignore it and don't update the input
1659
- // modality to keyboard.
1660
- if ((_b = (_a = this._options) === null || _a === void 0 ? void 0 : _a.ignoreKeys) === null || _b === void 0 ? void 0 : _b.some(keyCode => keyCode === event.keyCode)) {
1661
- return;
1662
- }
1663
- this._modality.next('keyboard');
1664
- this._mostRecentTarget = _getEventTarget(event);
1665
- };
1666
- /**
1667
- * Handles mousedown events. Must be an arrow function in order to preserve the context when it
1668
- * gets bound.
1669
- */
1670
- this._onMousedown = (event) => {
1671
- // Touches trigger both touch and mouse events, so we need to distinguish between mouse events
1672
- // that were triggered via mouse vs touch. To do so, check if the mouse event occurs closely
1673
- // after the previous touch event.
1674
- if (Date.now() - this._lastTouchMs < TOUCH_BUFFER_MS) {
1675
- return;
1676
- }
1677
- // Fake mousedown events are fired by some screen readers when controls are activated by the
1678
- // screen reader. Attribute them to keyboard input modality.
1679
- this._modality.next(isFakeMousedownFromScreenReader(event) ? 'keyboard' : 'mouse');
1680
- this._mostRecentTarget = _getEventTarget(event);
1681
- };
1682
- /**
1683
- * Handles touchstart events. Must be an arrow function in order to preserve the context when it
1684
- * gets bound.
1685
- */
1686
- this._onTouchstart = (event) => {
1687
- // Same scenario as mentioned in _onMousedown, but on touch screen devices, fake touchstart
1688
- // events are fired. Again, attribute to keyboard input modality.
1689
- if (isFakeTouchstartFromScreenReader(event)) {
1690
- this._modality.next('keyboard');
1691
- return;
1692
- }
1693
- // Store the timestamp of this touch event, as it's used to distinguish between mouse events
1694
- // triggered via mouse vs touch.
1695
- this._lastTouchMs = Date.now();
1696
- this._modality.next('touch');
1697
- this._mostRecentTarget = _getEventTarget(event);
1698
- };
1699
- this._options = Object.assign(Object.assign({}, INPUT_MODALITY_DETECTOR_DEFAULT_OPTIONS), options);
1700
- // Skip the first emission as it's null.
1701
- this.modalityDetected = this._modality.pipe(skip(1));
1702
- this.modalityChanged = this.modalityDetected.pipe(distinctUntilChanged());
1703
- // If we're not in a browser, this service should do nothing, as there's no relevant input
1704
- // modality to detect.
1705
- if (_platform.isBrowser) {
1706
- ngZone.runOutsideAngular(() => {
1707
- document.addEventListener('keydown', this._onKeydown, modalityEventListenerOptions);
1708
- document.addEventListener('mousedown', this._onMousedown, modalityEventListenerOptions);
1709
- document.addEventListener('touchstart', this._onTouchstart, modalityEventListenerOptions);
1710
- });
1711
- }
1712
- }
1713
- ngOnDestroy() {
1714
- this._modality.complete();
1715
- if (this._platform.isBrowser) {
1716
- document.removeEventListener('keydown', this._onKeydown, modalityEventListenerOptions);
1717
- document.removeEventListener('mousedown', this._onMousedown, modalityEventListenerOptions);
1718
- document.removeEventListener('touchstart', this._onTouchstart, modalityEventListenerOptions);
1719
- }
1720
- }
1721
- }
1722
- InputModalityDetector.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: InputModalityDetector, deps: [{ token: i1.Platform }, { token: i0.NgZone }, { token: DOCUMENT }, { token: INPUT_MODALITY_DETECTOR_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
1723
- InputModalityDetector.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: InputModalityDetector, providedIn: 'root' });
1724
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: InputModalityDetector, decorators: [{
1725
- type: Injectable,
1726
- args: [{ providedIn: 'root' }]
1727
- }], ctorParameters: function () {
1728
- return [{ type: i1.Platform }, { type: i0.NgZone }, { type: Document, decorators: [{
1729
- type: Inject,
1730
- args: [DOCUMENT]
1731
- }] }, { type: undefined, decorators: [{
1732
- type: Optional
1733
- }, {
1734
- type: Inject,
1735
- args: [INPUT_MODALITY_DETECTOR_OPTIONS]
1736
- }] }];
1737
- } });
1738
-
1739
- /**
1740
- * @license
1741
- * Copyright Google LLC All Rights Reserved.
1742
- *
1743
- * Use of this source code is governed by an MIT-style license that can be
1744
- * found in the LICENSE file at https://angular.io/license
1745
- */
1746
- const LIVE_ANNOUNCER_ELEMENT_TOKEN = new InjectionToken('liveAnnouncerElement', {
1747
- providedIn: 'root',
1748
- factory: LIVE_ANNOUNCER_ELEMENT_TOKEN_FACTORY,
1749
- });
1750
- /** @docs-private */
1751
- function LIVE_ANNOUNCER_ELEMENT_TOKEN_FACTORY() {
1752
- return null;
1753
- }
1754
- /** Injection token that can be used to configure the default options for the LiveAnnouncer. */
1755
- const LIVE_ANNOUNCER_DEFAULT_OPTIONS = new InjectionToken('LIVE_ANNOUNCER_DEFAULT_OPTIONS');
1756
-
1757
- let uniqueIds = 0;
1758
- class LiveAnnouncer {
1759
- constructor(elementToken, _ngZone, _document, _defaultOptions) {
1760
- this._ngZone = _ngZone;
1761
- this._defaultOptions = _defaultOptions;
1762
- // We inject the live element and document as `any` because the constructor signature cannot
1763
- // reference browser globals (HTMLElement, Document) on non-browser environments, since having
1764
- // a class decorator causes TypeScript to preserve the constructor signature types.
1765
- this._document = _document;
1766
- this._liveElement = elementToken || this._createLiveElement();
1767
- }
1768
- announce(message, ...args) {
1769
- const defaultOptions = this._defaultOptions;
1770
- let politeness;
1771
- let duration;
1772
- if (args.length === 1 && typeof args[0] === 'number') {
1773
- duration = args[0];
1774
- }
1775
- else {
1776
- [politeness, duration] = args;
1777
- }
1778
- this.clear();
1779
- clearTimeout(this._previousTimeout);
1780
- if (!politeness) {
1781
- politeness =
1782
- defaultOptions && defaultOptions.politeness ? defaultOptions.politeness : 'polite';
1783
- }
1784
- if (duration == null && defaultOptions) {
1785
- duration = defaultOptions.duration;
1786
- }
1787
- // TODO: ensure changing the politeness works on all environments we support.
1788
- this._liveElement.setAttribute('aria-live', politeness);
1789
- if (this._liveElement.id) {
1790
- this._exposeAnnouncerToModals(this._liveElement.id);
1791
- }
1792
- // This 100ms timeout is necessary for some browser + screen-reader combinations:
1793
- // - Both JAWS and NVDA over IE11 will not announce anything without a non-zero timeout.
1794
- // - With Chrome and IE11 with NVDA or JAWS, a repeated (identical) message won't be read a
1795
- // second time without clearing and then using a non-zero delay.
1796
- // (using JAWS 17 at time of this writing).
1797
- return this._ngZone.runOutsideAngular(() => {
1798
- if (!this._currentPromise) {
1799
- this._currentPromise = new Promise(resolve => (this._currentResolve = resolve));
1800
- }
1801
- clearTimeout(this._previousTimeout);
1802
- this._previousTimeout = setTimeout(() => {
1803
- this._liveElement.textContent = message;
1804
- if (typeof duration === 'number') {
1805
- this._previousTimeout = setTimeout(() => this.clear(), duration);
1806
- }
1807
- this._currentResolve();
1808
- this._currentPromise = this._currentResolve = undefined;
1809
- }, 100);
1810
- return this._currentPromise;
1811
- });
1812
- }
1813
- /**
1814
- * Clears the current text from the announcer element. Can be used to prevent
1815
- * screen readers from reading the text out again while the user is going
1816
- * through the page landmarks.
1817
- */
1818
- clear() {
1819
- if (this._liveElement) {
1820
- this._liveElement.textContent = '';
1821
- }
1822
- }
1823
- ngOnDestroy() {
1824
- var _a, _b;
1825
- clearTimeout(this._previousTimeout);
1826
- (_a = this._liveElement) === null || _a === void 0 ? void 0 : _a.remove();
1827
- this._liveElement = null;
1828
- (_b = this._currentResolve) === null || _b === void 0 ? void 0 : _b.call(this);
1829
- this._currentPromise = this._currentResolve = undefined;
1830
- }
1831
- _createLiveElement() {
1832
- const elementClass = 'cdk-live-announcer-element';
1833
- const previousElements = this._document.getElementsByClassName(elementClass);
1834
- const liveEl = this._document.createElement('div');
1835
- // Remove any old containers. This can happen when coming in from a server-side-rendered page.
1836
- for (let i = 0; i < previousElements.length; i++) {
1837
- previousElements[i].remove();
1838
- }
1839
- liveEl.classList.add(elementClass);
1840
- liveEl.classList.add('cdk-visually-hidden');
1841
- liveEl.setAttribute('aria-atomic', 'true');
1842
- liveEl.setAttribute('aria-live', 'polite');
1843
- liveEl.id = `cdk-live-announcer-${uniqueIds++}`;
1844
- this._document.body.appendChild(liveEl);
1845
- return liveEl;
1846
- }
1847
- /**
1848
- * Some browsers won't expose the accessibility node of the live announcer element if there is an
1849
- * `aria-modal` and the live announcer is outside of it. This method works around the issue by
1850
- * pointing the `aria-owns` of all modals to the live announcer element.
1851
- */
1852
- _exposeAnnouncerToModals(id) {
1853
- // Note that the selector here is limited to CDK overlays at the moment in order to reduce the
1854
- // section of the DOM we need to look through. This should cover all the cases we support, but
1855
- // the selector can be expanded if it turns out to be too narrow.
1856
- const modals = this._document.querySelectorAll('body > .cdk-overlay-container [aria-modal="true"]');
1857
- for (let i = 0; i < modals.length; i++) {
1858
- const modal = modals[i];
1859
- const ariaOwns = modal.getAttribute('aria-owns');
1860
- if (!ariaOwns) {
1861
- modal.setAttribute('aria-owns', id);
1862
- }
1863
- else if (ariaOwns.indexOf(id) === -1) {
1864
- modal.setAttribute('aria-owns', ariaOwns + ' ' + id);
1865
- }
1866
- }
1867
- }
1868
- }
1869
- LiveAnnouncer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: LiveAnnouncer, deps: [{ token: LIVE_ANNOUNCER_ELEMENT_TOKEN, optional: true }, { token: i0.NgZone }, { token: DOCUMENT }, { token: LIVE_ANNOUNCER_DEFAULT_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
1870
- LiveAnnouncer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: LiveAnnouncer, providedIn: 'root' });
1871
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: LiveAnnouncer, decorators: [{
1872
- type: Injectable,
1873
- args: [{ providedIn: 'root' }]
1874
- }], ctorParameters: function () {
1875
- return [{ type: undefined, decorators: [{
1876
- type: Optional
1877
- }, {
1878
- type: Inject,
1879
- args: [LIVE_ANNOUNCER_ELEMENT_TOKEN]
1880
- }] }, { type: i0.NgZone }, { type: undefined, decorators: [{
1881
- type: Inject,
1882
- args: [DOCUMENT]
1883
- }] }, { type: undefined, decorators: [{
1884
- type: Optional
1885
- }, {
1886
- type: Inject,
1887
- args: [LIVE_ANNOUNCER_DEFAULT_OPTIONS]
1888
- }] }];
1889
- } });
1890
- /**
1891
- * A directive that works similarly to aria-live, but uses the LiveAnnouncer to ensure compatibility
1892
- * with a wider range of browsers and screen readers.
1893
- */
1894
- class CdkAriaLive {
1895
- /** The aria-live politeness level to use when announcing messages. */
1896
- get politeness() {
1897
- return this._politeness;
1898
- }
1899
- set politeness(value) {
1900
- this._politeness = value === 'off' || value === 'assertive' ? value : 'polite';
1901
- if (this._politeness === 'off') {
1902
- if (this._subscription) {
1903
- this._subscription.unsubscribe();
1904
- this._subscription = null;
1905
- }
1906
- }
1907
- else if (!this._subscription) {
1908
- this._subscription = this._ngZone.runOutsideAngular(() => {
1909
- return this._contentObserver.observe(this._elementRef).subscribe(() => {
1910
- // Note that we use textContent here, rather than innerText, in order to avoid a reflow.
1911
- const elementText = this._elementRef.nativeElement.textContent;
1912
- // The `MutationObserver` fires also for attribute
1913
- // changes which we don't want to announce.
1914
- if (elementText !== this._previousAnnouncedText) {
1915
- this._liveAnnouncer.announce(elementText, this._politeness, this.duration);
1916
- this._previousAnnouncedText = elementText;
1917
- }
1918
- });
1919
- });
1920
- }
1921
- }
1922
- constructor(_elementRef, _liveAnnouncer, _contentObserver, _ngZone) {
1923
- this._elementRef = _elementRef;
1924
- this._liveAnnouncer = _liveAnnouncer;
1925
- this._contentObserver = _contentObserver;
1926
- this._ngZone = _ngZone;
1927
- this._politeness = 'polite';
1928
- }
1929
- ngOnDestroy() {
1930
- if (this._subscription) {
1931
- this._subscription.unsubscribe();
1932
- }
1933
- }
1934
- }
1935
- CdkAriaLive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: CdkAriaLive, deps: [{ token: i0.ElementRef }, { token: LiveAnnouncer }, { token: i1$1.ContentObserver }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
1936
- CdkAriaLive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0-next.2", type: CdkAriaLive, selector: "[cdkAriaLive]", inputs: { politeness: ["cdkAriaLive", "politeness"], duration: ["cdkAriaLiveDuration", "duration"] }, exportAs: ["cdkAriaLive"], ngImport: i0 });
1937
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: CdkAriaLive, decorators: [{
1938
- type: Directive,
1939
- args: [{
1940
- selector: '[cdkAriaLive]',
1941
- exportAs: 'cdkAriaLive',
1942
- }]
1943
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: LiveAnnouncer }, { type: i1$1.ContentObserver }, { type: i0.NgZone }]; }, propDecorators: { politeness: [{
1944
- type: Input,
1945
- args: ['cdkAriaLive']
1946
- }], duration: [{
1947
- type: Input,
1948
- args: ['cdkAriaLiveDuration']
1949
- }] } });
1950
-
1951
- /**
1952
- * @license
1953
- * Copyright Google LLC All Rights Reserved.
1954
- *
1955
- * Use of this source code is governed by an MIT-style license that can be
1956
- * found in the LICENSE file at https://angular.io/license
1957
- */
1958
- /** InjectionToken for FocusMonitorOptions. */
1959
- const FOCUS_MONITOR_DEFAULT_OPTIONS = new InjectionToken('cdk-focus-monitor-default-options');
1960
- /**
1961
- * Event listener options that enable capturing and also
1962
- * mark the listener as passive if the browser supports it.
1963
- */
1964
- const captureEventListenerOptions = normalizePassiveListenerOptions({
1965
- passive: true,
1966
- capture: true,
1967
- });
1968
- /** Monitors mouse and keyboard events to determine the cause of focus events. */
1969
- class FocusMonitor {
1970
- constructor(_ngZone, _platform, _inputModalityDetector,
1971
- /** @breaking-change 11.0.0 make document required */
1972
- document, options) {
1973
- this._ngZone = _ngZone;
1974
- this._platform = _platform;
1975
- this._inputModalityDetector = _inputModalityDetector;
1976
- /** The focus origin that the next focus event is a result of. */
1977
- this._origin = null;
1978
- /** Whether the window has just been focused. */
1979
- this._windowFocused = false;
1980
- /**
1981
- * Whether the origin was determined via a touch interaction. Necessary as properly attributing
1982
- * focus events to touch interactions requires special logic.
1983
- */
1984
- this._originFromTouchInteraction = false;
1985
- /** Map of elements being monitored to their info. */
1986
- this._elementInfo = new Map();
1987
- /** The number of elements currently being monitored. */
1988
- this._monitoredElementCount = 0;
1989
- /**
1990
- * Keeps track of the root nodes to which we've currently bound a focus/blur handler,
1991
- * as well as the number of monitored elements that they contain. We have to treat focus/blur
1992
- * handlers differently from the rest of the events, because the browser won't emit events
1993
- * to the document when focus moves inside of a shadow root.
1994
- */
1995
- this._rootNodeFocusListenerCount = new Map();
1996
- /**
1997
- * Event listener for `focus` events on the window.
1998
- * Needs to be an arrow function in order to preserve the context when it gets bound.
1999
- */
2000
- this._windowFocusListener = () => {
2001
- // Make a note of when the window regains focus, so we can
2002
- // restore the origin info for the focused element.
2003
- this._windowFocused = true;
2004
- this._windowFocusTimeoutId = window.setTimeout(() => (this._windowFocused = false));
2005
- };
2006
- /** Subject for stopping our InputModalityDetector subscription. */
2007
- this._stopInputModalityDetector = new Subject();
2008
- /**
2009
- * Event listener for `focus` and 'blur' events on the document.
2010
- * Needs to be an arrow function in order to preserve the context when it gets bound.
2011
- */
2012
- this._rootNodeFocusAndBlurListener = (event) => {
2013
- const target = _getEventTarget(event);
2014
- // We need to walk up the ancestor chain in order to support `checkChildren`.
2015
- for (let element = target; element; element = element.parentElement) {
2016
- if (event.type === 'focus') {
2017
- this._onFocus(event, element);
2018
- }
2019
- else {
2020
- this._onBlur(event, element);
2021
- }
2022
- }
2023
- };
2024
- this._document = document;
2025
- this._detectionMode = (options === null || options === void 0 ? void 0 : options.detectionMode) || 0 /* FocusMonitorDetectionMode.IMMEDIATE */;
2026
- }
2027
- monitor(element, checkChildren = false) {
2028
- const nativeElement = coerceElement(element);
2029
- // Do nothing if we're not on the browser platform or the passed in node isn't an element.
2030
- if (!this._platform.isBrowser || nativeElement.nodeType !== 1) {
2031
- return of(null);
2032
- }
2033
- // If the element is inside the shadow DOM, we need to bind our focus/blur listeners to
2034
- // the shadow root, rather than the `document`, because the browser won't emit focus events
2035
- // to the `document`, if focus is moving within the same shadow root.
2036
- const rootNode = _getShadowRoot(nativeElement) || this._getDocument();
2037
- const cachedInfo = this._elementInfo.get(nativeElement);
2038
- // Check if we're already monitoring this element.
2039
- if (cachedInfo) {
2040
- if (checkChildren) {
2041
- // TODO(COMP-318): this can be problematic, because it'll turn all non-checkChildren
2042
- // observers into ones that behave as if `checkChildren` was turned on. We need a more
2043
- // robust solution.
2044
- cachedInfo.checkChildren = true;
2045
- }
2046
- return cachedInfo.subject;
2047
- }
2048
- // Create monitored element info.
2049
- const info = {
2050
- checkChildren: checkChildren,
2051
- subject: new Subject(),
2052
- rootNode,
2053
- };
2054
- this._elementInfo.set(nativeElement, info);
2055
- this._registerGlobalListeners(info);
2056
- return info.subject;
2057
- }
2058
- stopMonitoring(element) {
2059
- const nativeElement = coerceElement(element);
2060
- const elementInfo = this._elementInfo.get(nativeElement);
2061
- if (elementInfo) {
2062
- elementInfo.subject.complete();
2063
- this._setClasses(nativeElement);
2064
- this._elementInfo.delete(nativeElement);
2065
- this._removeGlobalListeners(elementInfo);
2066
- }
2067
- }
2068
- focusVia(element, origin, options) {
2069
- const nativeElement = coerceElement(element);
2070
- const focusedElement = this._getDocument().activeElement;
2071
- // If the element is focused already, calling `focus` again won't trigger the event listener
2072
- // which means that the focus classes won't be updated. If that's the case, update the classes
2073
- // directly without waiting for an event.
2074
- if (nativeElement === focusedElement) {
2075
- this._getClosestElementsInfo(nativeElement).forEach(([currentElement, info]) => this._originChanged(currentElement, origin, info));
2076
- }
2077
- else {
2078
- this._setOrigin(origin);
2079
- // `focus` isn't available on the server
2080
- if (typeof nativeElement.focus === 'function') {
2081
- nativeElement.focus(options);
2082
- }
2083
- }
2084
- }
2085
- ngOnDestroy() {
2086
- this._elementInfo.forEach((_info, element) => this.stopMonitoring(element));
2087
- }
2088
- /** Access injected document if available or fallback to global document reference */
2089
- _getDocument() {
2090
- return this._document || document;
2091
- }
2092
- /** Use defaultView of injected document if available or fallback to global window reference */
2093
- _getWindow() {
2094
- const doc = this._getDocument();
2095
- return doc.defaultView || window;
2096
- }
2097
- _getFocusOrigin(focusEventTarget) {
2098
- if (this._origin) {
2099
- // If the origin was realized via a touch interaction, we need to perform additional checks
2100
- // to determine whether the focus origin should be attributed to touch or program.
2101
- if (this._originFromTouchInteraction) {
2102
- return this._shouldBeAttributedToTouch(focusEventTarget) ? 'touch' : 'program';
2103
- }
2104
- else {
2105
- return this._origin;
2106
- }
2107
- }
2108
- // If the window has just regained focus, we can restore the most recent origin from before the
2109
- // window blurred. Otherwise, we've reached the point where we can't identify the source of the
2110
- // focus. This typically means one of two things happened:
2111
- //
2112
- // 1) The element was programmatically focused, or
2113
- // 2) The element was focused via screen reader navigation (which generally doesn't fire
2114
- // events).
2115
- //
2116
- // Because we can't distinguish between these two cases, we default to setting `program`.
2117
- if (this._windowFocused && this._lastFocusOrigin) {
2118
- return this._lastFocusOrigin;
2119
- }
2120
- // If the interaction is coming from an input label, we consider it a mouse interactions.
2121
- // This is a special case where focus moves on `click`, rather than `mousedown` which breaks
2122
- // our detection, because all our assumptions are for `mousedown`. We need to handle this
2123
- // special case, because it's very common for checkboxes and radio buttons.
2124
- if (focusEventTarget && this._isLastInteractionFromInputLabel(focusEventTarget)) {
2125
- return 'mouse';
2126
- }
2127
- return 'program';
2128
- }
2129
- /**
2130
- * Returns whether the focus event should be attributed to touch. Recall that in IMMEDIATE mode, a
2131
- * touch origin isn't immediately reset at the next tick (see _setOrigin). This means that when we
2132
- * handle a focus event following a touch interaction, we need to determine whether (1) the focus
2133
- * event was directly caused by the touch interaction or (2) the focus event was caused by a
2134
- * subsequent programmatic focus call triggered by the touch interaction.
2135
- * @param focusEventTarget The target of the focus event under examination.
2136
- */
2137
- _shouldBeAttributedToTouch(focusEventTarget) {
2138
- // Please note that this check is not perfect. Consider the following edge case:
2139
- //
2140
- // <div #parent tabindex="0">
2141
- // <div #child tabindex="0" (click)="#parent.focus()"></div>
2142
- // </div>
2143
- //
2144
- // Suppose there is a FocusMonitor in IMMEDIATE mode attached to #parent. When the user touches
2145
- // #child, #parent is programmatically focused. This code will attribute the focus to touch
2146
- // instead of program. This is a relatively minor edge-case that can be worked around by using
2147
- // focusVia(parent, 'program') to focus #parent.
2148
- return (this._detectionMode === 1 /* FocusMonitorDetectionMode.EVENTUAL */ ||
2149
- !!(focusEventTarget === null || focusEventTarget === void 0 ? void 0 : focusEventTarget.contains(this._inputModalityDetector._mostRecentTarget)));
2150
- }
2151
- /**
2152
- * Sets the focus classes on the element based on the given focus origin.
2153
- * @param element The element to update the classes on.
2154
- * @param origin The focus origin.
2155
- */
2156
- _setClasses(element, origin) {
2157
- element.classList.toggle('cdk-focused', !!origin);
2158
- element.classList.toggle('cdk-touch-focused', origin === 'touch');
2159
- element.classList.toggle('cdk-keyboard-focused', origin === 'keyboard');
2160
- element.classList.toggle('cdk-mouse-focused', origin === 'mouse');
2161
- element.classList.toggle('cdk-program-focused', origin === 'program');
2162
- }
2163
- /**
2164
- * Updates the focus origin. If we're using immediate detection mode, we schedule an async
2165
- * function to clear the origin at the end of a timeout. The duration of the timeout depends on
2166
- * the origin being set.
2167
- * @param origin The origin to set.
2168
- * @param isFromInteraction Whether we are setting the origin from an interaction event.
2169
- */
2170
- _setOrigin(origin, isFromInteraction = false) {
2171
- this._ngZone.runOutsideAngular(() => {
2172
- this._origin = origin;
2173
- this._originFromTouchInteraction = origin === 'touch' && isFromInteraction;
2174
- // If we're in IMMEDIATE mode, reset the origin at the next tick (or in `TOUCH_BUFFER_MS` ms
2175
- // for a touch event). We reset the origin at the next tick because Firefox focuses one tick
2176
- // after the interaction event. We wait `TOUCH_BUFFER_MS` ms before resetting the origin for
2177
- // a touch event because when a touch event is fired, the associated focus event isn't yet in
2178
- // the event queue. Before doing so, clear any pending timeouts.
2179
- if (this._detectionMode === 0 /* FocusMonitorDetectionMode.IMMEDIATE */) {
2180
- clearTimeout(this._originTimeoutId);
2181
- const ms = this._originFromTouchInteraction ? TOUCH_BUFFER_MS : 1;
2182
- this._originTimeoutId = setTimeout(() => (this._origin = null), ms);
2183
- }
2184
- });
2185
- }
2186
- /**
2187
- * Handles focus events on a registered element.
2188
- * @param event The focus event.
2189
- * @param element The monitored element.
2190
- */
2191
- _onFocus(event, element) {
2192
- // NOTE(mmalerba): We currently set the classes based on the focus origin of the most recent
2193
- // focus event affecting the monitored element. If we want to use the origin of the first event
2194
- // instead we should check for the cdk-focused class here and return if the element already has
2195
- // it. (This only matters for elements that have includesChildren = true).
2196
- // If we are not counting child-element-focus as focused, make sure that the event target is the
2197
- // monitored element itself.
2198
- const elementInfo = this._elementInfo.get(element);
2199
- const focusEventTarget = _getEventTarget(event);
2200
- if (!elementInfo || (!elementInfo.checkChildren && element !== focusEventTarget)) {
2201
- return;
2202
- }
2203
- this._originChanged(element, this._getFocusOrigin(focusEventTarget), elementInfo);
2204
- }
2205
- /**
2206
- * Handles blur events on a registered element.
2207
- * @param event The blur event.
2208
- * @param element The monitored element.
2209
- */
2210
- _onBlur(event, element) {
2211
- // If we are counting child-element-focus as focused, make sure that we aren't just blurring in
2212
- // order to focus another child of the monitored element.
2213
- const elementInfo = this._elementInfo.get(element);
2214
- if (!elementInfo ||
2215
- (elementInfo.checkChildren &&
2216
- event.relatedTarget instanceof Node &&
2217
- element.contains(event.relatedTarget))) {
2218
- return;
2219
- }
2220
- this._setClasses(element);
2221
- this._emitOrigin(elementInfo, null);
2222
- }
2223
- _emitOrigin(info, origin) {
2224
- if (info.subject.observers.length) {
2225
- this._ngZone.run(() => info.subject.next(origin));
2226
- }
2227
- }
2228
- _registerGlobalListeners(elementInfo) {
2229
- if (!this._platform.isBrowser) {
2230
- return;
2231
- }
2232
- const rootNode = elementInfo.rootNode;
2233
- const rootNodeFocusListeners = this._rootNodeFocusListenerCount.get(rootNode) || 0;
2234
- if (!rootNodeFocusListeners) {
2235
- this._ngZone.runOutsideAngular(() => {
2236
- rootNode.addEventListener('focus', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);
2237
- rootNode.addEventListener('blur', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);
2238
- });
2239
- }
2240
- this._rootNodeFocusListenerCount.set(rootNode, rootNodeFocusListeners + 1);
2241
- // Register global listeners when first element is monitored.
2242
- if (++this._monitoredElementCount === 1) {
2243
- // Note: we listen to events in the capture phase so we
2244
- // can detect them even if the user stops propagation.
2245
- this._ngZone.runOutsideAngular(() => {
2246
- const window = this._getWindow();
2247
- window.addEventListener('focus', this._windowFocusListener);
2248
- });
2249
- // The InputModalityDetector is also just a collection of global listeners.
2250
- this._inputModalityDetector.modalityDetected
2251
- .pipe(takeUntil(this._stopInputModalityDetector))
2252
- .subscribe(modality => {
2253
- this._setOrigin(modality, true /* isFromInteraction */);
2254
- });
2255
- }
2256
- }
2257
- _removeGlobalListeners(elementInfo) {
2258
- const rootNode = elementInfo.rootNode;
2259
- if (this._rootNodeFocusListenerCount.has(rootNode)) {
2260
- const rootNodeFocusListeners = this._rootNodeFocusListenerCount.get(rootNode);
2261
- if (rootNodeFocusListeners > 1) {
2262
- this._rootNodeFocusListenerCount.set(rootNode, rootNodeFocusListeners - 1);
2263
- }
2264
- else {
2265
- rootNode.removeEventListener('focus', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);
2266
- rootNode.removeEventListener('blur', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);
2267
- this._rootNodeFocusListenerCount.delete(rootNode);
2268
- }
2269
- }
2270
- // Unregister global listeners when last element is unmonitored.
2271
- if (!--this._monitoredElementCount) {
2272
- const window = this._getWindow();
2273
- window.removeEventListener('focus', this._windowFocusListener);
2274
- // Equivalently, stop our InputModalityDetector subscription.
2275
- this._stopInputModalityDetector.next();
2276
- // Clear timeouts for all potentially pending timeouts to prevent the leaks.
2277
- clearTimeout(this._windowFocusTimeoutId);
2278
- clearTimeout(this._originTimeoutId);
2279
- }
2280
- }
2281
- /** Updates all the state on an element once its focus origin has changed. */
2282
- _originChanged(element, origin, elementInfo) {
2283
- this._setClasses(element, origin);
2284
- this._emitOrigin(elementInfo, origin);
2285
- this._lastFocusOrigin = origin;
2286
- }
2287
- /**
2288
- * Collects the `MonitoredElementInfo` of a particular element and
2289
- * all of its ancestors that have enabled `checkChildren`.
2290
- * @param element Element from which to start the search.
2291
- */
2292
- _getClosestElementsInfo(element) {
2293
- const results = [];
2294
- this._elementInfo.forEach((info, currentElement) => {
2295
- if (currentElement === element || (info.checkChildren && currentElement.contains(element))) {
2296
- results.push([currentElement, info]);
2297
- }
2298
- });
2299
- return results;
2300
- }
2301
- /**
2302
- * Returns whether an interaction is likely to have come from the user clicking the `label` of
2303
- * an `input` or `textarea` in order to focus it.
2304
- * @param focusEventTarget Target currently receiving focus.
2305
- */
2306
- _isLastInteractionFromInputLabel(focusEventTarget) {
2307
- const { _mostRecentTarget: mostRecentTarget, mostRecentModality } = this._inputModalityDetector;
2308
- // If the last interaction used the mouse on an element contained by one of the labels
2309
- // of an `input`/`textarea` that is currently focused, it is very likely that the
2310
- // user redirected focus using the label.
2311
- if (mostRecentModality !== 'mouse' ||
2312
- !mostRecentTarget ||
2313
- mostRecentTarget === focusEventTarget ||
2314
- (focusEventTarget.nodeName !== 'INPUT' && focusEventTarget.nodeName !== 'TEXTAREA') ||
2315
- focusEventTarget.disabled) {
2316
- return false;
2317
- }
2318
- const labels = focusEventTarget.labels;
2319
- if (labels) {
2320
- for (let i = 0; i < labels.length; i++) {
2321
- if (labels[i].contains(mostRecentTarget)) {
2322
- return true;
2323
- }
2324
- }
2325
- }
2326
- return false;
2327
- }
2328
- }
2329
- FocusMonitor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: FocusMonitor, deps: [{ token: i0.NgZone }, { token: i1.Platform }, { token: InputModalityDetector }, { token: DOCUMENT, optional: true }, { token: FOCUS_MONITOR_DEFAULT_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
2330
- FocusMonitor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: FocusMonitor, providedIn: 'root' });
2331
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: FocusMonitor, decorators: [{
2332
- type: Injectable,
2333
- args: [{ providedIn: 'root' }]
2334
- }], ctorParameters: function () {
2335
- return [{ type: i0.NgZone }, { type: i1.Platform }, { type: InputModalityDetector }, { type: undefined, decorators: [{
2336
- type: Optional
2337
- }, {
2338
- type: Inject,
2339
- args: [DOCUMENT]
2340
- }] }, { type: undefined, decorators: [{
2341
- type: Optional
2342
- }, {
2343
- type: Inject,
2344
- args: [FOCUS_MONITOR_DEFAULT_OPTIONS]
2345
- }] }];
2346
- } });
2347
- /**
2348
- * Directive that determines how a particular element was focused (via keyboard, mouse, touch, or
2349
- * programmatically) and adds corresponding classes to the element.
2350
- *
2351
- * There are two variants of this directive:
2352
- * 1) cdkMonitorElementFocus: does not consider an element to be focused if one of its children is
2353
- * focused.
2354
- * 2) cdkMonitorSubtreeFocus: considers an element focused if it or any of its children are focused.
2355
- */
2356
- class CdkMonitorFocus {
2357
- constructor(_elementRef, _focusMonitor) {
2358
- this._elementRef = _elementRef;
2359
- this._focusMonitor = _focusMonitor;
2360
- this._focusOrigin = null;
2361
- this.cdkFocusChange = new EventEmitter();
2362
- }
2363
- get focusOrigin() {
2364
- return this._focusOrigin;
2365
- }
2366
- ngAfterViewInit() {
2367
- const element = this._elementRef.nativeElement;
2368
- this._monitorSubscription = this._focusMonitor
2369
- .monitor(element, element.nodeType === 1 && element.hasAttribute('cdkMonitorSubtreeFocus'))
2370
- .subscribe(origin => {
2371
- this._focusOrigin = origin;
2372
- this.cdkFocusChange.emit(origin);
2373
- });
2374
- }
2375
- ngOnDestroy() {
2376
- this._focusMonitor.stopMonitoring(this._elementRef);
2377
- if (this._monitorSubscription) {
2378
- this._monitorSubscription.unsubscribe();
2379
- }
2380
- }
2381
- }
2382
- CdkMonitorFocus.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: CdkMonitorFocus, deps: [{ token: i0.ElementRef }, { token: FocusMonitor }], target: i0.ɵɵFactoryTarget.Directive });
2383
- CdkMonitorFocus.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0-next.2", type: CdkMonitorFocus, selector: "[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]", outputs: { cdkFocusChange: "cdkFocusChange" }, exportAs: ["cdkMonitorFocus"], ngImport: i0 });
2384
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: CdkMonitorFocus, decorators: [{
2385
- type: Directive,
2386
- args: [{
2387
- selector: '[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]',
2388
- exportAs: 'cdkMonitorFocus',
2389
- }]
2390
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: FocusMonitor }]; }, propDecorators: { cdkFocusChange: [{
2391
- type: Output
2392
- }] } });
2393
-
2394
- /**
2395
- * @license
2396
- * Copyright Google LLC All Rights Reserved.
2397
- *
2398
- * Use of this source code is governed by an MIT-style license that can be
2399
- * found in the LICENSE file at https://angular.io/license
2400
- */
2401
- /** CSS class applied to the document body when in black-on-white high-contrast mode. */
2402
- const BLACK_ON_WHITE_CSS_CLASS = 'cdk-high-contrast-black-on-white';
2403
- /** CSS class applied to the document body when in white-on-black high-contrast mode. */
2404
- const WHITE_ON_BLACK_CSS_CLASS = 'cdk-high-contrast-white-on-black';
2405
- /** CSS class applied to the document body when in high-contrast mode. */
2406
- const HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS = 'cdk-high-contrast-active';
2407
- /**
2408
- * Service to determine whether the browser is currently in a high-contrast-mode environment.
2409
- *
2410
- * Microsoft Windows supports an accessibility feature called "High Contrast Mode". This mode
2411
- * changes the appearance of all applications, including web applications, to dramatically increase
2412
- * contrast.
2413
- *
2414
- * IE, Edge, and Firefox currently support this mode. Chrome does not support Windows High Contrast
2415
- * Mode. This service does not detect high-contrast mode as added by the Chrome "High Contrast"
2416
- * browser extension.
2417
- */
2418
- class HighContrastModeDetector {
2419
- constructor(_platform, document) {
2420
- this._platform = _platform;
2421
- this._document = document;
2422
- this._breakpointSubscription = inject(BreakpointObserver)
2423
- .observe('(forced-colors: active)')
2424
- .subscribe(() => {
2425
- if (this._hasCheckedHighContrastMode) {
2426
- this._hasCheckedHighContrastMode = false;
2427
- this._applyBodyHighContrastModeCssClasses();
2428
- }
2429
- });
2430
- }
2431
- /** Gets the current high-contrast-mode for the page. */
2432
- getHighContrastMode() {
2433
- if (!this._platform.isBrowser) {
2434
- return 0 /* HighContrastMode.NONE */;
2435
- }
2436
- // Create a test element with an arbitrary background-color that is neither black nor
2437
- // white; high-contrast mode will coerce the color to either black or white. Also ensure that
2438
- // appending the test element to the DOM does not affect layout by absolutely positioning it
2439
- const testElement = this._document.createElement('div');
2440
- testElement.style.backgroundColor = 'rgb(1,2,3)';
2441
- testElement.style.position = 'absolute';
2442
- this._document.body.appendChild(testElement);
2443
- // Get the computed style for the background color, collapsing spaces to normalize between
2444
- // browsers. Once we get this color, we no longer need the test element. Access the `window`
2445
- // via the document so we can fake it in tests. Note that we have extra null checks, because
2446
- // this logic will likely run during app bootstrap and throwing can break the entire app.
2447
- const documentWindow = this._document.defaultView || window;
2448
- const computedStyle = documentWindow && documentWindow.getComputedStyle
2449
- ? documentWindow.getComputedStyle(testElement)
2450
- : null;
2451
- const computedColor = ((computedStyle && computedStyle.backgroundColor) || '').replace(/ /g, '');
2452
- testElement.remove();
2453
- switch (computedColor) {
2454
- // Pre Windows 11 dark theme.
2455
- case 'rgb(0,0,0)':
2456
- // Windows 11 dark themes.
2457
- case 'rgb(45,50,54)':
2458
- case 'rgb(32,32,32)':
2459
- return 2 /* HighContrastMode.WHITE_ON_BLACK */;
2460
- // Pre Windows 11 light theme.
2461
- case 'rgb(255,255,255)':
2462
- // Windows 11 light theme.
2463
- case 'rgb(255,250,239)':
2464
- return 1 /* HighContrastMode.BLACK_ON_WHITE */;
2465
- }
2466
- return 0 /* HighContrastMode.NONE */;
2467
- }
2468
- ngOnDestroy() {
2469
- this._breakpointSubscription.unsubscribe();
2470
- }
2471
- /** Applies CSS classes indicating high-contrast mode to document body (browser-only). */
2472
- _applyBodyHighContrastModeCssClasses() {
2473
- if (!this._hasCheckedHighContrastMode && this._platform.isBrowser && this._document.body) {
2474
- const bodyClasses = this._document.body.classList;
2475
- bodyClasses.remove(HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS, BLACK_ON_WHITE_CSS_CLASS, WHITE_ON_BLACK_CSS_CLASS);
2476
- this._hasCheckedHighContrastMode = true;
2477
- const mode = this.getHighContrastMode();
2478
- if (mode === 1 /* HighContrastMode.BLACK_ON_WHITE */) {
2479
- bodyClasses.add(HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS, BLACK_ON_WHITE_CSS_CLASS);
2480
- }
2481
- else if (mode === 2 /* HighContrastMode.WHITE_ON_BLACK */) {
2482
- bodyClasses.add(HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS, WHITE_ON_BLACK_CSS_CLASS);
2483
- }
2484
- }
2485
- }
2486
- }
2487
- HighContrastModeDetector.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: HighContrastModeDetector, deps: [{ token: i1.Platform }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
2488
- HighContrastModeDetector.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: HighContrastModeDetector, providedIn: 'root' });
2489
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: HighContrastModeDetector, decorators: [{
2490
- type: Injectable,
2491
- args: [{ providedIn: 'root' }]
2492
- }], ctorParameters: function () {
2493
- return [{ type: i1.Platform }, { type: undefined, decorators: [{
2494
- type: Inject,
2495
- args: [DOCUMENT]
2496
- }] }];
2497
- } });
2498
-
2499
- /**
2500
- * @license
2501
- * Copyright Google LLC All Rights Reserved.
2502
- *
2503
- * Use of this source code is governed by an MIT-style license that can be
2504
- * found in the LICENSE file at https://angular.io/license
2505
- */
2506
- class A11yModule {
2507
- constructor(highContrastModeDetector) {
2508
- highContrastModeDetector._applyBodyHighContrastModeCssClasses();
2509
- }
2510
- }
2511
- A11yModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: A11yModule, deps: [{ token: HighContrastModeDetector }], target: i0.ɵɵFactoryTarget.NgModule });
2512
- A11yModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.0.0-next.2", ngImport: i0, type: A11yModule, declarations: [CdkAriaLive, CdkTrapFocus, CdkMonitorFocus], imports: [ObserversModule], exports: [CdkAriaLive, CdkTrapFocus, CdkMonitorFocus] });
2513
- A11yModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: A11yModule, imports: [ObserversModule] });
2514
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.2", ngImport: i0, type: A11yModule, decorators: [{
2515
- type: NgModule,
2516
- args: [{
2517
- imports: [ObserversModule],
2518
- declarations: [CdkAriaLive, CdkTrapFocus, CdkMonitorFocus],
2519
- exports: [CdkAriaLive, CdkTrapFocus, CdkMonitorFocus],
2520
- }]
2521
- }], ctorParameters: function () { return [{ type: HighContrastModeDetector }]; } });
2522
-
2523
- /**
2524
- * @license
2525
- * Copyright Google LLC All Rights Reserved.
2526
- *
2527
- * Use of this source code is governed by an MIT-style license that can be
2528
- * found in the LICENSE file at https://angular.io/license
2529
- */
2530
-
2531
- /**
2532
- * @license
2533
- * Copyright Google LLC All Rights Reserved.
2534
- *
2535
- * Use of this source code is governed by an MIT-style license that can be
2536
- * found in the LICENSE file at https://angular.io/license
2537
- */
2538
-
2539
- /**
2540
- * Generated bundle index. Do not edit.
2541
- */
2542
-
2543
- export { A11yModule, ActiveDescendantKeyManager, AriaDescriber, CDK_DESCRIBEDBY_HOST_ATTRIBUTE, CDK_DESCRIBEDBY_ID_PREFIX, CdkAriaLive, CdkMonitorFocus, CdkTrapFocus, ConfigurableFocusTrap, ConfigurableFocusTrapFactory, EventListenerFocusTrapInertStrategy, FOCUS_MONITOR_DEFAULT_OPTIONS, FOCUS_TRAP_INERT_STRATEGY, FocusKeyManager, FocusMonitor, FocusTrap, FocusTrapFactory, HighContrastModeDetector, INPUT_MODALITY_DETECTOR_DEFAULT_OPTIONS, INPUT_MODALITY_DETECTOR_OPTIONS, InputModalityDetector, InteractivityChecker, IsFocusableConfig, LIVE_ANNOUNCER_DEFAULT_OPTIONS, LIVE_ANNOUNCER_ELEMENT_TOKEN, LIVE_ANNOUNCER_ELEMENT_TOKEN_FACTORY, ListKeyManager, LiveAnnouncer, MESSAGES_CONTAINER_ID, isFakeMousedownFromScreenReader, isFakeTouchstartFromScreenReader };
2544
- //# sourceMappingURL=a11y.mjs.map