axe-core 4.1.2-canary.ec00dc7 → 4.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (640) hide show
  1. package/CHANGELOG.md +0 -46
  2. package/CONTRIBUTING.md +57 -112
  3. package/README.md +50 -59
  4. package/axe.d.ts +281 -282
  5. package/axe.js +678 -1285
  6. package/axe.min.js +2 -2
  7. package/bower.json +38 -44
  8. package/doc/API.md +133 -178
  9. package/doc/check-message-template.md +3 -3
  10. package/doc/check-options.md +25 -25
  11. package/doc/developer-guide.md +48 -48
  12. package/doc/examples/chrome-debugging-protocol/axe-cdp.js +56 -56
  13. package/doc/examples/chrome-debugging-protocol/package.json +9 -9
  14. package/doc/examples/html-handlebars.md +52 -52
  15. package/doc/examples/jasmine/karma.conf.js +15 -15
  16. package/doc/examples/jasmine/package.json +19 -19
  17. package/doc/examples/jasmine/spec/a11y.js +29 -29
  18. package/doc/examples/jest_react/link.js +3 -3
  19. package/doc/examples/jest_react/link.test.js +15 -15
  20. package/doc/examples/jest_react/package.json +26 -26
  21. package/doc/examples/jest_react/test-helpers.js +12 -12
  22. package/doc/examples/jsdom/package.json +13 -13
  23. package/doc/examples/mocha/karma.conf.js +15 -15
  24. package/doc/examples/mocha/package.json +20 -20
  25. package/doc/examples/phantomjs/axe-phantom.js +36 -36
  26. package/doc/examples/phantomjs/package.json +17 -17
  27. package/doc/examples/puppeteer/axe-puppeteer.js +37 -37
  28. package/doc/examples/puppeteer/package.json +11 -11
  29. package/doc/examples/qunit/package.json +19 -19
  30. package/doc/examples/test-examples.js +22 -22
  31. package/doc/plugins.md +64 -64
  32. package/doc/projects.md +9 -13
  33. package/doc/rule-descriptions.md +100 -104
  34. package/doc/rule-development.md +2 -2
  35. package/doc/standards-object.md +8 -14
  36. package/lib/checks/aria/abstractrole-evaluate.js +8 -8
  37. package/lib/checks/aria/abstractrole.json +12 -12
  38. package/lib/checks/aria/aria-allowed-attr-evaluate.js +25 -24
  39. package/lib/checks/aria/aria-allowed-attr.json +12 -12
  40. package/lib/checks/aria/aria-allowed-role-evaluate.js +21 -21
  41. package/lib/checks/aria/aria-allowed-role.json +20 -20
  42. package/lib/checks/aria/aria-errormessage-evaluate.js +30 -38
  43. package/lib/checks/aria/aria-errormessage.json +16 -16
  44. package/lib/checks/aria/aria-hidden-body-evaluate.js +1 -1
  45. package/lib/checks/aria/aria-hidden-body.json +9 -9
  46. package/lib/checks/aria/aria-required-attr-evaluate.js +34 -34
  47. package/lib/checks/aria/aria-required-attr.json +12 -12
  48. package/lib/checks/aria/aria-required-children-evaluate.js +103 -108
  49. package/lib/checks/aria/aria-required-children.json +30 -30
  50. package/lib/checks/aria/aria-required-parent-evaluate.js +65 -72
  51. package/lib/checks/aria/aria-required-parent.json +12 -12
  52. package/lib/checks/aria/aria-roledescription-evaluate.js +9 -9
  53. package/lib/checks/aria/aria-roledescription.json +21 -21
  54. package/lib/checks/aria/aria-unsupported-attr-evaluate.js +20 -17
  55. package/lib/checks/aria/aria-unsupported-attr.json +9 -9
  56. package/lib/checks/aria/aria-valid-attr-evaluate.js +20 -20
  57. package/lib/checks/aria/aria-valid-attr-value-evaluate.js +71 -82
  58. package/lib/checks/aria/aria-valid-attr-value.json +17 -17
  59. package/lib/checks/aria/aria-valid-attr.json +13 -13
  60. package/lib/checks/aria/fallbackrole-evaluate.js +1 -1
  61. package/lib/checks/aria/fallbackrole.json +9 -9
  62. package/lib/checks/aria/has-global-aria-attribute-evaluate.js +5 -5
  63. package/lib/checks/aria/has-global-aria-attribute.json +12 -12
  64. package/lib/checks/aria/has-widget-role-evaluate.js +6 -6
  65. package/lib/checks/aria/has-widget-role.json +10 -10
  66. package/lib/checks/aria/invalidrole-evaluate.js +12 -12
  67. package/lib/checks/aria/invalidrole.json +12 -12
  68. package/lib/checks/aria/is-element-focusable-evaluate.js +1 -1
  69. package/lib/checks/aria/is-element-focusable.json +9 -9
  70. package/lib/checks/aria/no-implicit-explicit-label-evaluate.js +18 -20
  71. package/lib/checks/aria/no-implicit-explicit-label.json +9 -9
  72. package/lib/checks/aria/unsupportedrole-evaluate.js +2 -2
  73. package/lib/checks/aria/unsupportedrole.json +9 -9
  74. package/lib/checks/aria/valid-scrollable-semantics-evaluate.js +23 -23
  75. package/lib/checks/aria/valid-scrollable-semantics.json +10 -10
  76. package/lib/checks/color/color-contrast-evaluate.js +164 -164
  77. package/lib/checks/color/color-contrast.json +40 -40
  78. package/lib/checks/color/link-in-text-block-evaluate.js +70 -70
  79. package/lib/checks/color/link-in-text-block.json +17 -17
  80. package/lib/checks/forms/autocomplete-appropriate-evaluate.js +68 -68
  81. package/lib/checks/forms/autocomplete-appropriate.json +9 -9
  82. package/lib/checks/forms/autocomplete-valid-evaluate.js +2 -2
  83. package/lib/checks/forms/autocomplete-valid.json +9 -9
  84. package/lib/checks/generic/README.md +5 -5
  85. package/lib/checks/generic/attr-non-space-content-evaluate.js +20 -20
  86. package/lib/checks/generic/has-descendant-after.js +10 -10
  87. package/lib/checks/generic/has-descendant-evaluate.js +12 -12
  88. package/lib/checks/generic/has-text-content-evaluate.js +5 -5
  89. package/lib/checks/generic/matches-definition-evaluate.js +1 -1
  90. package/lib/checks/generic/page-no-duplicate-after.js +2 -2
  91. package/lib/checks/generic/page-no-duplicate-evaluate.js +29 -29
  92. package/lib/checks/keyboard/accesskeys-after.js +19 -19
  93. package/lib/checks/keyboard/accesskeys-evaluate.js +5 -5
  94. package/lib/checks/keyboard/accesskeys.json +10 -10
  95. package/lib/checks/keyboard/focusable-content-evaluate.js +13 -13
  96. package/lib/checks/keyboard/focusable-content.json +9 -9
  97. package/lib/checks/keyboard/focusable-disabled-evaluate.js +30 -30
  98. package/lib/checks/keyboard/focusable-disabled.json +9 -9
  99. package/lib/checks/keyboard/focusable-element-evaluate.js +41 -41
  100. package/lib/checks/keyboard/focusable-element.json +9 -9
  101. package/lib/checks/keyboard/focusable-modal-open-evaluate.js +11 -11
  102. package/lib/checks/keyboard/focusable-modal-open.json +9 -9
  103. package/lib/checks/keyboard/focusable-no-name-evaluate.js +10 -10
  104. package/lib/checks/keyboard/focusable-no-name.json +10 -10
  105. package/lib/checks/keyboard/focusable-not-tabbable-evaluate.js +30 -30
  106. package/lib/checks/keyboard/focusable-not-tabbable.json +9 -9
  107. package/lib/checks/keyboard/landmark-is-top-level-evaluate.js +17 -22
  108. package/lib/checks/keyboard/landmark-is-top-level.json +9 -9
  109. package/lib/checks/keyboard/page-has-heading-one.json +13 -13
  110. package/lib/checks/keyboard/page-has-main.json +13 -13
  111. package/lib/checks/keyboard/page-no-duplicate-banner.json +14 -14
  112. package/lib/checks/keyboard/page-no-duplicate-contentinfo.json +14 -14
  113. package/lib/checks/keyboard/page-no-duplicate-main.json +13 -13
  114. package/lib/checks/keyboard/tabindex-evaluate.js +5 -5
  115. package/lib/checks/keyboard/tabindex.json +9 -9
  116. package/lib/checks/label/alt-space-value-evaluate.js +3 -3
  117. package/lib/checks/label/alt-space-value.json +9 -9
  118. package/lib/checks/label/duplicate-img-label-evaluate.js +12 -12
  119. package/lib/checks/label/duplicate-img-label.json +12 -12
  120. package/lib/checks/label/explicit-evaluate.js +20 -25
  121. package/lib/checks/label/explicit.json +10 -10
  122. package/lib/checks/label/help-same-as-label-evaluate.js +17 -17
  123. package/lib/checks/label/help-same-as-label.json +10 -10
  124. package/lib/checks/label/hidden-explicit-label-evaluate.js +15 -21
  125. package/lib/checks/label/hidden-explicit-label.json +10 -10
  126. package/lib/checks/label/implicit-evaluate.js +9 -9
  127. package/lib/checks/label/implicit.json +10 -10
  128. package/lib/checks/label/label-content-name-mismatch-evaluate.js +42 -42
  129. package/lib/checks/label/label-content-name-mismatch.json +13 -13
  130. package/lib/checks/label/multiple-label-evaluate.js +32 -32
  131. package/lib/checks/label/multiple-label.json +9 -9
  132. package/lib/checks/label/title-only-evaluate.js +4 -4
  133. package/lib/checks/label/title-only.json +9 -9
  134. package/lib/checks/landmarks/landmark-is-unique-after.js +20 -20
  135. package/lib/checks/landmarks/landmark-is-unique-evaluate.js +6 -6
  136. package/lib/checks/landmarks/landmark-is-unique.json +10 -10
  137. package/lib/checks/language/has-lang-evaluate.js +25 -25
  138. package/lib/checks/language/has-lang.json +15 -15
  139. package/lib/checks/language/valid-lang-evaluate.js +25 -25
  140. package/lib/checks/language/valid-lang.json +12 -12
  141. package/lib/checks/language/xml-lang-mismatch-evaluate.js +3 -3
  142. package/lib/checks/language/xml-lang-mismatch.json +9 -9
  143. package/lib/checks/lists/dlitem-evaluate.js +19 -19
  144. package/lib/checks/lists/dlitem.json +9 -9
  145. package/lib/checks/lists/listitem-evaluate.js +17 -17
  146. package/lib/checks/lists/listitem.json +12 -12
  147. package/lib/checks/lists/only-dlitems-evaluate.js +44 -44
  148. package/lib/checks/lists/only-dlitems.json +9 -9
  149. package/lib/checks/lists/only-listitems-evaluate.js +56 -56
  150. package/lib/checks/lists/only-listitems.json +12 -12
  151. package/lib/checks/lists/structured-dlitems-evaluate.js +20 -20
  152. package/lib/checks/lists/structured-dlitems.json +9 -9
  153. package/lib/checks/media/caption-evaluate.js +6 -6
  154. package/lib/checks/media/caption.json +9 -9
  155. package/lib/checks/media/frame-tested-evaluate.js +20 -20
  156. package/lib/checks/media/frame-tested.json +13 -13
  157. package/lib/checks/media/no-autoplay-audio-evaluate.js +81 -81
  158. package/lib/checks/media/no-autoplay-audio.json +13 -13
  159. package/lib/checks/mobile/css-orientation-lock-evaluate.js +250 -250
  160. package/lib/checks/mobile/css-orientation-lock.json +13 -13
  161. package/lib/checks/mobile/meta-viewport-large.json +13 -13
  162. package/lib/checks/mobile/meta-viewport-scale-evaluate.js +56 -56
  163. package/lib/checks/mobile/meta-viewport.json +12 -12
  164. package/lib/checks/navigation/header-present.json +13 -13
  165. package/lib/checks/navigation/heading-order-after.js +11 -134
  166. package/lib/checks/navigation/heading-order-evaluate.js +13 -51
  167. package/lib/checks/navigation/heading-order.json +10 -10
  168. package/lib/checks/navigation/identical-links-same-purpose-after.js +86 -86
  169. package/lib/checks/navigation/identical-links-same-purpose-evaluate.js +23 -23
  170. package/lib/checks/navigation/identical-links-same-purpose.json +10 -10
  171. package/lib/checks/navigation/internal-link-present-evaluate.js +4 -4
  172. package/lib/checks/navigation/internal-link-present.json +9 -9
  173. package/lib/checks/navigation/landmark.json +12 -12
  174. package/lib/checks/navigation/meta-refresh-evaluate.js +3 -3
  175. package/lib/checks/navigation/meta-refresh.json +9 -9
  176. package/lib/checks/navigation/p-as-heading-evaluate.js +72 -72
  177. package/lib/checks/navigation/p-as-heading.json +28 -28
  178. package/lib/checks/navigation/region-evaluate.js +73 -73
  179. package/lib/checks/navigation/region.json +12 -12
  180. package/lib/checks/navigation/skip-link-evaluate.js +5 -5
  181. package/lib/checks/navigation/skip-link.json +10 -10
  182. package/lib/checks/navigation/unique-frame-title-after.js +8 -8
  183. package/lib/checks/navigation/unique-frame-title-evaluate.js +3 -3
  184. package/lib/checks/navigation/unique-frame-title.json +10 -10
  185. package/lib/checks/parsing/duplicate-id-active.json +10 -10
  186. package/lib/checks/parsing/duplicate-id-after.js +8 -8
  187. package/lib/checks/parsing/duplicate-id-aria.json +10 -10
  188. package/lib/checks/parsing/duplicate-id-evaluate.js +15 -15
  189. package/lib/checks/parsing/duplicate-id.json +10 -10
  190. package/lib/checks/shared/aria-label-evaluate.js +1 -1
  191. package/lib/checks/shared/aria-label.json +9 -9
  192. package/lib/checks/shared/aria-labelledby-evaluate.js +5 -5
  193. package/lib/checks/shared/aria-labelledby.json +10 -10
  194. package/lib/checks/shared/avoid-inline-spacing-evaluate.js +10 -10
  195. package/lib/checks/shared/avoid-inline-spacing.json +15 -15
  196. package/lib/checks/shared/button-has-visible-text.json +10 -10
  197. package/lib/checks/shared/doc-has-title-evaluate.js +2 -2
  198. package/lib/checks/shared/doc-has-title.json +9 -9
  199. package/lib/checks/shared/exists-evaluate.js +1 -1
  200. package/lib/checks/shared/exists.json +9 -9
  201. package/lib/checks/shared/has-alt-evaluate.js +5 -5
  202. package/lib/checks/shared/has-alt.json +9 -9
  203. package/lib/checks/shared/has-visible-text.json +10 -10
  204. package/lib/checks/shared/is-on-screen-evaluate.js +2 -2
  205. package/lib/checks/shared/is-on-screen.json +9 -9
  206. package/lib/checks/shared/non-empty-alt.json +15 -15
  207. package/lib/checks/shared/non-empty-if-present-evaluate.js +13 -13
  208. package/lib/checks/shared/non-empty-if-present.json +12 -12
  209. package/lib/checks/shared/non-empty-placeholder.json +15 -15
  210. package/lib/checks/shared/non-empty-title.json +15 -15
  211. package/lib/checks/shared/non-empty-value.json +15 -15
  212. package/lib/checks/shared/presentational-role-evaluate.js +29 -29
  213. package/lib/checks/shared/presentational-role.json +14 -14
  214. package/lib/checks/shared/role-none.json +17 -17
  215. package/lib/checks/shared/role-presentation.json +17 -17
  216. package/lib/checks/shared/svg-non-empty-title-evaluate.js +20 -24
  217. package/lib/checks/shared/svg-non-empty-title.json +13 -13
  218. package/lib/checks/tables/caption-faked-evaluate.js +8 -8
  219. package/lib/checks/tables/caption-faked.json +9 -9
  220. package/lib/checks/tables/html5-scope-evaluate.js +4 -4
  221. package/lib/checks/tables/html5-scope.json +9 -9
  222. package/lib/checks/tables/same-caption-summary-evaluate.js +6 -6
  223. package/lib/checks/tables/same-caption-summary.json +9 -9
  224. package/lib/checks/tables/scope-value-evaluate.js +2 -2
  225. package/lib/checks/tables/scope-value.json +12 -12
  226. package/lib/checks/tables/td-has-header-evaluate.js +21 -21
  227. package/lib/checks/tables/td-has-header.json +9 -9
  228. package/lib/checks/tables/td-headers-attr-evaluate.js +48 -48
  229. package/lib/checks/tables/td-headers-attr.json +10 -10
  230. package/lib/checks/tables/th-has-data-cells-evaluate.js +64 -64
  231. package/lib/checks/tables/th-has-data-cells.json +10 -10
  232. package/lib/checks/visibility/hidden-content-evaluate.js +28 -28
  233. package/lib/checks/visibility/hidden-content.json +10 -10
  234. package/lib/commons/aria/allowed-attr.js +12 -12
  235. package/lib/commons/aria/arialabel-text.js +7 -7
  236. package/lib/commons/aria/arialabelledby-text.js +41 -41
  237. package/lib/commons/aria/get-accessible-refs.js +41 -41
  238. package/lib/commons/aria/get-element-unallowed-roles.js +69 -69
  239. package/lib/commons/aria/get-explicit-role.js +14 -14
  240. package/lib/commons/aria/get-owned-virtual.js +14 -14
  241. package/lib/commons/aria/get-role-type.js +5 -5
  242. package/lib/commons/aria/get-role.js +89 -89
  243. package/lib/commons/aria/get-roles-by-type.js +1 -1
  244. package/lib/commons/aria/get-roles-with-name-from-contents.js +1 -1
  245. package/lib/commons/aria/implicit-nodes.js +6 -6
  246. package/lib/commons/aria/implicit-role.js +32 -32
  247. package/lib/commons/aria/is-accessible-ref.js +1 -1
  248. package/lib/commons/aria/is-aria-role-allowed-on-element.js +12 -12
  249. package/lib/commons/aria/is-unsupported-role.js +2 -2
  250. package/lib/commons/aria/is-valid-role.js +6 -6
  251. package/lib/commons/aria/label-virtual.js +24 -24
  252. package/lib/commons/aria/label.js +2 -2
  253. package/lib/commons/aria/lookup-table.js +2395 -2395
  254. package/lib/commons/aria/named-from-contents.js +19 -19
  255. package/lib/commons/aria/required-attr.js +5 -5
  256. package/lib/commons/aria/required-context.js +5 -5
  257. package/lib/commons/aria/required-owned.js +5 -5
  258. package/lib/commons/aria/validate-attr-value.js +40 -44
  259. package/lib/commons/aria/validate-attr.js +2 -2
  260. package/lib/commons/color/center-point-of-rect.js +15 -15
  261. package/lib/commons/color/color.js +224 -224
  262. package/lib/commons/color/element-has-image.js +14 -14
  263. package/lib/commons/color/element-is-distinct.js +56 -55
  264. package/lib/commons/color/filtered-rect-stack.js +32 -32
  265. package/lib/commons/color/flatten-colors.js +6 -6
  266. package/lib/commons/color/get-background-color.js +40 -40
  267. package/lib/commons/color/get-background-stack.js +71 -71
  268. package/lib/commons/color/get-contrast.js +9 -9
  269. package/lib/commons/color/get-foreground-color.js +34 -34
  270. package/lib/commons/color/get-own-background-color.js +7 -7
  271. package/lib/commons/color/get-rect-stack.js +14 -14
  272. package/lib/commons/color/get-text-shadow-colors.js +87 -87
  273. package/lib/commons/color/has-valid-contrast-ratio.js +10 -10
  274. package/lib/commons/color/incomplete-data.js +37 -37
  275. package/lib/commons/dom/find-elms-in-context.js +11 -11
  276. package/lib/commons/dom/find-up-virtual.js +31 -31
  277. package/lib/commons/dom/find-up.js +1 -1
  278. package/lib/commons/dom/focus-disabled.js +13 -13
  279. package/lib/commons/dom/get-composed-parent.js +14 -14
  280. package/lib/commons/dom/get-element-by-reference.js +18 -18
  281. package/lib/commons/dom/get-element-coordinates.js +12 -12
  282. package/lib/commons/dom/get-element-stack.js +10 -10
  283. package/lib/commons/dom/get-rect-stack.js +427 -427
  284. package/lib/commons/dom/get-scroll-offset.js +17 -17
  285. package/lib/commons/dom/get-tabbable-elements.js +9 -9
  286. package/lib/commons/dom/get-text-element-stack.js +49 -64
  287. package/lib/commons/dom/get-viewport-size.js +19 -19
  288. package/lib/commons/dom/has-content-virtual.js +29 -29
  289. package/lib/commons/dom/has-content.js +2 -2
  290. package/lib/commons/dom/idrefs.js +15 -15
  291. package/lib/commons/dom/inserted-into-focus-order.js +6 -6
  292. package/lib/commons/dom/is-focusable.js +12 -16
  293. package/lib/commons/dom/is-hidden-with-css.js +47 -47
  294. package/lib/commons/dom/is-html5.js +5 -5
  295. package/lib/commons/dom/is-in-text-block.js +74 -74
  296. package/lib/commons/dom/is-modal-open.js +78 -78
  297. package/lib/commons/dom/is-natively-focusable.js +22 -22
  298. package/lib/commons/dom/is-node.js +1 -1
  299. package/lib/commons/dom/is-offscreen.js +43 -43
  300. package/lib/commons/dom/is-opaque.js +4 -4
  301. package/lib/commons/dom/is-skip-link.js +27 -27
  302. package/lib/commons/dom/is-visible.js +147 -147
  303. package/lib/commons/dom/is-visual-content.js +33 -33
  304. package/lib/commons/dom/reduce-to-elements-below-floating.js +18 -18
  305. package/lib/commons/dom/shadow-elements-from-point.js +29 -29
  306. package/lib/commons/dom/url-props-from-attribute.js +100 -100
  307. package/lib/commons/dom/visually-contains.js +77 -77
  308. package/lib/commons/dom/visually-overlaps.js +29 -29
  309. package/lib/commons/forms/is-aria-combobox.js +2 -2
  310. package/lib/commons/forms/is-aria-listbox.js +2 -2
  311. package/lib/commons/forms/is-aria-range.js +2 -2
  312. package/lib/commons/forms/is-aria-textbox.js +2 -2
  313. package/lib/commons/forms/is-disabled.js +20 -20
  314. package/lib/commons/forms/is-native-select.js +3 -3
  315. package/lib/commons/forms/is-native-textbox.js +17 -17
  316. package/lib/commons/index.js +9 -9
  317. package/lib/commons/matches/attributes.js +4 -4
  318. package/lib/commons/matches/condition.js +1 -1
  319. package/lib/commons/matches/explicit-role.js +1 -1
  320. package/lib/commons/matches/from-definition.js +30 -30
  321. package/lib/commons/matches/from-function.js +12 -12
  322. package/lib/commons/matches/from-primative.js +20 -20
  323. package/lib/commons/matches/implicit-role.js +1 -1
  324. package/lib/commons/matches/matches.js +1 -1
  325. package/lib/commons/matches/node-name.js +4 -4
  326. package/lib/commons/matches/properties.js +4 -4
  327. package/lib/commons/matches/semantic-role.js +1 -1
  328. package/lib/commons/standards/get-aria-roles-by-type.js +3 -3
  329. package/lib/commons/standards/get-aria-roles-supporting-name-from-content.js +8 -8
  330. package/lib/commons/standards/get-element-spec.js +42 -42
  331. package/lib/commons/standards/get-elements-by-content-type.js +15 -15
  332. package/lib/commons/standards/get-global-aria-attrs.js +8 -8
  333. package/lib/commons/standards/implicit-html-roles.js +140 -140
  334. package/lib/commons/table/get-all-cells.js +16 -16
  335. package/lib/commons/table/get-cell-position.js +15 -15
  336. package/lib/commons/table/get-headers.js +65 -72
  337. package/lib/commons/table/get-scope.js +42 -42
  338. package/lib/commons/table/is-column-header.js +1 -1
  339. package/lib/commons/table/is-data-cell.js +10 -10
  340. package/lib/commons/table/is-data-table.js +176 -176
  341. package/lib/commons/table/is-header.js +8 -8
  342. package/lib/commons/table/is-row-header.js +1 -1
  343. package/lib/commons/table/to-grid.js +20 -31
  344. package/lib/commons/table/traverse.js +55 -55
  345. package/lib/commons/text/accessible-text-virtual.js +90 -90
  346. package/lib/commons/text/accessible-text.js +2 -2
  347. package/lib/commons/text/form-control-value.js +112 -113
  348. package/lib/commons/text/has-unicode.js +17 -17
  349. package/lib/commons/text/index.js +4 -4
  350. package/lib/commons/text/is-human-interpretable.js +34 -34
  351. package/lib/commons/text/is-icon-ligature.js +194 -194
  352. package/lib/commons/text/is-valid-autocomplete.js +104 -104
  353. package/lib/commons/text/label-text.js +39 -39
  354. package/lib/commons/text/label-virtual.js +26 -26
  355. package/lib/commons/text/label.js +2 -2
  356. package/lib/commons/text/native-element-type.js +97 -97
  357. package/lib/commons/text/native-text-alternative.js +19 -19
  358. package/lib/commons/text/native-text-methods.js +113 -113
  359. package/lib/commons/text/remove-unicode.js +15 -15
  360. package/lib/commons/text/sanitize.js +8 -8
  361. package/lib/commons/text/subtree-text.js +89 -47
  362. package/lib/commons/text/title-text.js +14 -14
  363. package/lib/commons/text/unicode.js +56 -56
  364. package/lib/commons/text/unsupported.js +1 -1
  365. package/lib/commons/text/visible-text-nodes.js +12 -12
  366. package/lib/commons/text/visible-virtual.js +21 -21
  367. package/lib/commons/text/visible.js +2 -2
  368. package/lib/core/base/audit.js +613 -613
  369. package/lib/core/base/cache.js +22 -22
  370. package/lib/core/base/check-result.js +20 -20
  371. package/lib/core/base/check.js +132 -132
  372. package/lib/core/base/context.js +175 -179
  373. package/lib/core/base/metadata-function-map.js +167 -179
  374. package/lib/core/base/rule-result.js +25 -25
  375. package/lib/core/base/rule.js +473 -475
  376. package/lib/core/base/virtual-node/abstract-virtual-node.js +33 -37
  377. package/lib/core/base/virtual-node/serial-virtual-node.js +76 -85
  378. package/lib/core/base/virtual-node/virtual-node.js +151 -177
  379. package/lib/core/constants.js +50 -50
  380. package/lib/core/core.js +7 -11
  381. package/lib/core/imports/index.js +14 -14
  382. package/lib/core/index.js +21 -19
  383. package/lib/core/log.js +4 -4
  384. package/lib/core/public/cleanup.js +43 -41
  385. package/lib/core/public/configure.js +112 -112
  386. package/lib/core/public/get-rules.js +19 -19
  387. package/lib/core/public/load.js +49 -47
  388. package/lib/core/public/plugins.js +24 -22
  389. package/lib/core/public/reporter.js +12 -12
  390. package/lib/core/public/reset.js +6 -6
  391. package/lib/core/public/run-rules.js +76 -61
  392. package/lib/core/public/run-virtual-rule.js +42 -47
  393. package/lib/core/public/run.js +154 -154
  394. package/lib/core/reporters/helpers/failure-summary.js +22 -22
  395. package/lib/core/reporters/helpers/get-environment-data.js +29 -29
  396. package/lib/core/reporters/helpers/incomplete-fallback-msg.js +3 -3
  397. package/lib/core/reporters/helpers/index.js +8 -8
  398. package/lib/core/reporters/helpers/process-aggregate.js +69 -69
  399. package/lib/core/reporters/na.js +16 -16
  400. package/lib/core/reporters/no-passes.js +12 -12
  401. package/lib/core/reporters/raw-env.js +9 -9
  402. package/lib/core/reporters/raw.js +24 -24
  403. package/lib/core/reporters/v1.js +23 -23
  404. package/lib/core/reporters/v2.js +13 -13
  405. package/lib/core/utils/aggregate-checks.js +63 -63
  406. package/lib/core/utils/aggregate-node-results.js +44 -44
  407. package/lib/core/utils/aggregate-result.js +24 -24
  408. package/lib/core/utils/aggregate.js +6 -6
  409. package/lib/core/utils/are-styles-set.js +14 -14
  410. package/lib/core/utils/assert.js +3 -3
  411. package/lib/core/utils/check-helper.js +23 -23
  412. package/lib/core/utils/clone.js +18 -18
  413. package/lib/core/utils/closest.js +12 -12
  414. package/lib/core/utils/collect-results-from-frames.js +45 -63
  415. package/lib/core/utils/contains.js +29 -29
  416. package/lib/core/utils/css-parser.js +0 -1
  417. package/lib/core/utils/deep-merge.js +18 -18
  418. package/lib/core/utils/dq-element.js +88 -88
  419. package/lib/core/utils/element-matches.js +29 -29
  420. package/lib/core/utils/escape-selector.js +63 -63
  421. package/lib/core/utils/extend-meta-data.js +11 -11
  422. package/lib/core/utils/finalize-result.js +13 -15
  423. package/lib/core/utils/find-by.js +3 -3
  424. package/lib/core/utils/get-all-checks.js +5 -5
  425. package/lib/core/utils/get-ancestry.js +16 -16
  426. package/lib/core/utils/get-base-lang.js +7 -7
  427. package/lib/core/utils/get-check-message.js +9 -9
  428. package/lib/core/utils/get-check-option.js +26 -26
  429. package/lib/core/utils/get-flattened-tree.js +88 -88
  430. package/lib/core/utils/get-friendly-uri-end.js +87 -87
  431. package/lib/core/utils/get-node-attributes.js +9 -10
  432. package/lib/core/utils/get-node-from-tree.js +2 -2
  433. package/lib/core/utils/get-root-node.js +6 -6
  434. package/lib/core/utils/get-scroll-state.js +26 -26
  435. package/lib/core/utils/get-scroll.js +26 -26
  436. package/lib/core/utils/get-selector.js +256 -256
  437. package/lib/core/utils/get-shadow-selector.js +19 -19
  438. package/lib/core/utils/get-stylesheet-factory.js +32 -32
  439. package/lib/core/utils/get-xpath.js +65 -65
  440. package/lib/core/utils/index.js +3 -6
  441. package/lib/core/utils/inject-style.js +24 -24
  442. package/lib/core/utils/is-hidden.js +41 -41
  443. package/lib/core/utils/is-html-element.js +122 -122
  444. package/lib/core/utils/is-node-in-context.js +24 -24
  445. package/lib/core/utils/is-shadow-root.js +28 -28
  446. package/lib/core/utils/is-xhtml.js +4 -4
  447. package/lib/core/utils/matches.js +170 -176
  448. package/lib/core/utils/memoize.js +7 -7
  449. package/lib/core/utils/merge-results.js +91 -91
  450. package/lib/core/utils/node-sorter.js +11 -11
  451. package/lib/core/utils/parse-crossorigin-stylesheet.js +41 -41
  452. package/lib/core/utils/parse-sameorigin-stylesheet.js +70 -70
  453. package/lib/core/utils/parse-stylesheet.js +41 -41
  454. package/lib/core/utils/performance-timer.js +112 -112
  455. package/lib/core/utils/pollyfills.js +263 -263
  456. package/lib/core/utils/preload-cssom.js +134 -134
  457. package/lib/core/utils/preload-media.js +42 -42
  458. package/lib/core/utils/preload.js +110 -110
  459. package/lib/core/utils/process-message.js +43 -45
  460. package/lib/core/utils/publish-metadata.js +68 -68
  461. package/lib/core/utils/query-selector-all-filter.js +77 -79
  462. package/lib/core/utils/query-selector-all.js +1 -1
  463. package/lib/core/utils/queue.js +113 -113
  464. package/lib/core/utils/respondable.js +218 -119
  465. package/lib/core/utils/rule-should-run.js +53 -53
  466. package/lib/core/utils/select.js +54 -54
  467. package/lib/core/utils/send-command-to-frame.js +43 -43
  468. package/lib/core/utils/set-scroll-state.js +7 -7
  469. package/lib/core/utils/to-array.js +1 -1
  470. package/lib/core/utils/token-list.js +4 -4
  471. package/lib/core/utils/unique-array.js +3 -3
  472. package/lib/core/utils/uuid.js +161 -170
  473. package/lib/core/utils/valid-input-type.js +25 -25
  474. package/lib/core/utils/valid-langs.js +30 -30
  475. package/lib/misc/any-failure-summary.json +4 -4
  476. package/lib/misc/incomplete-fallback.json +1 -1
  477. package/lib/misc/none-failure-summary.json +4 -4
  478. package/lib/rules/accesskeys.json +11 -11
  479. package/lib/rules/area-alt.json +20 -20
  480. package/lib/rules/aria-allowed-attr-matches.js +13 -11
  481. package/lib/rules/aria-allowed-attr.json +10 -10
  482. package/lib/rules/aria-allowed-role-matches.js +6 -6
  483. package/lib/rules/aria-allowed-role.json +12 -12
  484. package/lib/rules/aria-command-name.json +16 -16
  485. package/lib/rules/aria-dialog-name.json +11 -11
  486. package/lib/rules/aria-has-attr-matches.js +10 -10
  487. package/lib/rules/aria-hidden-body.json +12 -12
  488. package/lib/rules/aria-hidden-focus-matches.js +8 -8
  489. package/lib/rules/aria-hidden-focus.json +16 -16
  490. package/lib/rules/aria-input-field-name.json +11 -11
  491. package/lib/rules/aria-meter-name.json +11 -11
  492. package/lib/rules/aria-progressbar-name.json +11 -11
  493. package/lib/rules/aria-required-attr.json +10 -10
  494. package/lib/rules/aria-required-children.json +10 -11
  495. package/lib/rules/aria-required-parent.json +10 -11
  496. package/lib/rules/aria-roledescription.json +10 -10
  497. package/lib/rules/aria-roles.json +11 -11
  498. package/lib/rules/aria-toggle-field-name.json +16 -16
  499. package/lib/rules/aria-tooltip-name.json +16 -16
  500. package/lib/rules/aria-treeitem-name.json +16 -16
  501. package/lib/rules/aria-valid-attr-value.json +10 -10
  502. package/lib/rules/aria-valid-attr.json +10 -10
  503. package/lib/rules/audio-caption.json +18 -18
  504. package/lib/rules/autocomplete-matches.js +50 -50
  505. package/lib/rules/autocomplete-valid.json +10 -10
  506. package/lib/rules/avoid-inline-spacing.json +10 -10
  507. package/lib/rules/blink.json +17 -17
  508. package/lib/rules/button-name.json +24 -24
  509. package/lib/rules/bypass-matches.js +7 -7
  510. package/lib/rules/bypass.json +18 -19
  511. package/lib/rules/color-contrast-matches.js +137 -145
  512. package/lib/rules/color-contrast.json +11 -11
  513. package/lib/rules/css-orientation-lock.json +11 -11
  514. package/lib/rules/data-table-large-matches.js +10 -10
  515. package/lib/rules/data-table-matches.js +1 -1
  516. package/lib/rules/definition-list.json +11 -11
  517. package/lib/rules/dlitem.json +11 -11
  518. package/lib/rules/document-title.json +11 -11
  519. package/lib/rules/duplicate-id-active-matches.js +6 -6
  520. package/lib/rules/duplicate-id-active.json +12 -12
  521. package/lib/rules/duplicate-id-aria-matches.js +1 -1
  522. package/lib/rules/duplicate-id-aria.json +12 -12
  523. package/lib/rules/duplicate-id-misc-matches.js +8 -8
  524. package/lib/rules/duplicate-id.json +12 -12
  525. package/lib/rules/empty-heading.json +17 -17
  526. package/lib/rules/focus-order-semantics.json +11 -11
  527. package/lib/rules/form-field-multiple-labels.json +11 -11
  528. package/lib/rules/frame-tested.json +10 -10
  529. package/lib/rules/frame-title-has-text-matches.js +2 -2
  530. package/lib/rules/frame-title-unique.json +11 -11
  531. package/lib/rules/frame-title.json +22 -22
  532. package/lib/rules/heading-matches.js +14 -14
  533. package/lib/rules/heading-order.json +11 -11
  534. package/lib/rules/hidden-content.json +11 -11
  535. package/lib/rules/html-has-lang.json +11 -11
  536. package/lib/rules/html-lang-valid.json +10 -10
  537. package/lib/rules/html-namespace-matches.js +1 -1
  538. package/lib/rules/html-xml-lang-mismatch.json +11 -11
  539. package/lib/rules/identical-links-same-purpose-matches.js +9 -9
  540. package/lib/rules/identical-links-same-purpose.json +12 -12
  541. package/lib/rules/image-alt.json +24 -24
  542. package/lib/rules/img-redundant-alt.json +10 -10
  543. package/lib/rules/input-button-name.json +24 -24
  544. package/lib/rules/input-image-alt.json +18 -18
  545. package/lib/rules/inserted-into-focus-order-matches.js +1 -1
  546. package/lib/rules/is-initiator-matches.js +1 -1
  547. package/lib/rules/label-content-name-mismatch-matches.js +38 -38
  548. package/lib/rules/label-content-name-mismatch.json +10 -10
  549. package/lib/rules/label-matches.js +10 -10
  550. package/lib/rules/label-title-only.json +11 -11
  551. package/lib/rules/label.json +27 -27
  552. package/lib/rules/landmark-banner-is-top-level.json +11 -11
  553. package/lib/rules/landmark-complementary-is-top-level.json +10 -10
  554. package/lib/rules/landmark-contentinfo-is-top-level.json +11 -11
  555. package/lib/rules/landmark-has-body-context-matches.js +6 -6
  556. package/lib/rules/landmark-main-is-top-level.json +10 -10
  557. package/lib/rules/landmark-no-duplicate-banner.json +10 -10
  558. package/lib/rules/landmark-no-duplicate-contentinfo.json +10 -10
  559. package/lib/rules/landmark-no-duplicate-main.json +10 -10
  560. package/lib/rules/landmark-one-main.json +10 -10
  561. package/lib/rules/landmark-unique-matches.js +36 -36
  562. package/lib/rules/landmark-unique.json +11 -11
  563. package/lib/rules/layout-table-matches.js +2 -1
  564. package/lib/rules/link-in-text-block-matches.js +12 -12
  565. package/lib/rules/link-in-text-block.json +12 -12
  566. package/lib/rules/link-name.json +23 -23
  567. package/lib/rules/list.json +11 -11
  568. package/lib/rules/listitem.json +11 -11
  569. package/lib/rules/marquee.json +11 -11
  570. package/lib/rules/meta-refresh.json +18 -18
  571. package/lib/rules/meta-viewport-large.json +11 -11
  572. package/lib/rules/meta-viewport.json +11 -11
  573. package/lib/rules/no-autoplay-audio-matches.js +16 -16
  574. package/lib/rules/no-autoplay-audio.json +13 -13
  575. package/lib/rules/no-empty-role-matches.js +7 -7
  576. package/lib/rules/no-explicit-name-required-matches.js +9 -9
  577. package/lib/rules/no-naming-method-matches.js +12 -12
  578. package/lib/rules/no-role-matches.js +1 -1
  579. package/lib/rules/not-html-matches.js +2 -2
  580. package/lib/rules/object-alt.json +22 -22
  581. package/lib/rules/p-as-heading-matches.js +14 -14
  582. package/lib/rules/p-as-heading.json +11 -11
  583. package/lib/rules/page-has-heading-one.json +10 -10
  584. package/lib/rules/presentation-role-conflict.json +10 -10
  585. package/lib/rules/region.json +10 -10
  586. package/lib/rules/role-img-alt.json +18 -18
  587. package/lib/rules/scope-attr-valid.json +10 -10
  588. package/lib/rules/scrollable-region-focusable-matches.js +59 -59
  589. package/lib/rules/scrollable-region-focusable.json +10 -10
  590. package/lib/rules/select-name.json +25 -25
  591. package/lib/rules/server-side-image-map.json +16 -16
  592. package/lib/rules/skip-link-matches.js +1 -1
  593. package/lib/rules/skip-link.json +11 -11
  594. package/lib/rules/svg-img-alt.json +23 -23
  595. package/lib/rules/svg-namespace-matches.js +10 -10
  596. package/lib/rules/tabindex.json +10 -10
  597. package/lib/rules/table-duplicate-name.json +10 -10
  598. package/lib/rules/table-fake-caption.json +18 -18
  599. package/lib/rules/td-has-header.json +18 -18
  600. package/lib/rules/td-headers-attr.json +10 -10
  601. package/lib/rules/th-has-data-cells.json +11 -11
  602. package/lib/rules/valid-lang.json +11 -11
  603. package/lib/rules/video-caption.json +17 -17
  604. package/lib/rules/window-is-top-matches.js +3 -3
  605. package/lib/rules/xml-lang-mismatch-matches.js +6 -6
  606. package/lib/standards/aria-attrs.js +195 -204
  607. package/lib/standards/aria-roles.js +781 -812
  608. package/lib/standards/css-colors.js +148 -148
  609. package/lib/standards/dpub-roles.js +213 -214
  610. package/lib/standards/html-elms.js +912 -914
  611. package/lib/standards/index.js +16 -18
  612. package/locales/de.json +572 -909
  613. package/package.json +151 -174
  614. package/sri-history.json +1 -5
  615. package/typings/axe-core/axe-core-tests.ts +144 -144
  616. package/.eslintrc.js +0 -111
  617. package/lib/checks/aria/aria-prohibited-attr-evaluate.js +0 -67
  618. package/lib/checks/aria/aria-prohibited-attr.json +0 -12
  619. package/lib/checks/keyboard/frame-focusable-content.json +0 -12
  620. package/lib/checks/keyboard/no-focusable-content-evaluate.js +0 -35
  621. package/lib/checks/keyboard/no-focusable-content.json +0 -12
  622. package/lib/core/public/setup.js +0 -20
  623. package/lib/core/public/teardown.js +0 -21
  624. package/lib/core/utils/filter-html-attrs.js +0 -75
  625. package/lib/core/utils/get-rule.js +0 -17
  626. package/lib/core/utils/respondable/assert-window.js +0 -21
  627. package/lib/core/utils/respondable/callback-store.js +0 -36
  628. package/lib/core/utils/respondable/message-id.js +0 -22
  629. package/lib/core/utils/respondable/message-parser.js +0 -109
  630. package/lib/core/utils/respondable/post.js +0 -32
  631. package/lib/rules/aria-required-children-matches.js +0 -8
  632. package/lib/rules/aria-required-parent-matches.js +0 -8
  633. package/lib/rules/aria-text.json +0 -12
  634. package/lib/rules/empty-table-header.json +0 -13
  635. package/lib/rules/frame-focusable-content-matches.js +0 -9
  636. package/lib/rules/frame-focusable-content.json +0 -13
  637. package/lib/rules/nested-interactive-matches.js +0 -13
  638. package/lib/rules/nested-interactive.json +0 -12
  639. package/lib/standards/graphics-roles.js +0 -22
  640. package/locales/pl.json +0 -911
@@ -14,133 +14,133 @@ const gridSize = 200; // arbitrary size, increase to reduce memory use (less cel
14
14
  * @return {Boolean}
15
15
  */
16
16
  function isStackingContext(vNode, parentVNode) {
17
- const position = vNode.getComputedStylePropertyValue('position');
18
- const zIndex = vNode.getComputedStylePropertyValue('z-index');
19
-
20
- // the root element (HTML) is skipped since we always start with a
21
- // stacking order of [0]
22
-
23
- // position: fixed or sticky
24
- if (position === 'fixed' || position === 'sticky') {
25
- return true;
26
- }
27
-
28
- // positioned (absolutely or relatively) with a z-index value other than "auto",
29
- if (zIndex !== 'auto' && position !== 'static') {
30
- return true;
31
- }
32
-
33
- // elements with an opacity value less than 1.
34
- if (vNode.getComputedStylePropertyValue('opacity') !== '1') {
35
- return true;
36
- }
37
-
38
- // elements with a transform value other than "none"
39
- const transform =
40
- vNode.getComputedStylePropertyValue('-webkit-transform') ||
41
- vNode.getComputedStylePropertyValue('-ms-transform') ||
42
- vNode.getComputedStylePropertyValue('transform') ||
43
- 'none';
44
-
45
- if (transform !== 'none') {
46
- return true;
47
- }
48
-
49
- // elements with a mix-blend-mode value other than "normal"
50
- const mixBlendMode = vNode.getComputedStylePropertyValue('mix-blend-mode');
51
- if (mixBlendMode && mixBlendMode !== 'normal') {
52
- return true;
53
- }
54
-
55
- // elements with a filter value other than "none"
56
- const filter = vNode.getComputedStylePropertyValue('filter');
57
- if (filter && filter !== 'none') {
58
- return true;
59
- }
60
-
61
- // elements with a perspective value other than "none"
62
- const perspective = vNode.getComputedStylePropertyValue('perspective');
63
- if (perspective && perspective !== 'none') {
64
- return true;
65
- }
66
-
67
- // element with a clip-path value other than "none"
68
- const clipPath = vNode.getComputedStylePropertyValue('clip-path');
69
- if (clipPath && clipPath !== 'none') {
70
- return true;
71
- }
72
-
73
- // element with a mask value other than "none"
74
- const mask =
75
- vNode.getComputedStylePropertyValue('-webkit-mask') ||
76
- vNode.getComputedStylePropertyValue('mask') ||
77
- 'none';
78
- if (mask !== 'none') {
79
- return true;
80
- }
81
-
82
- // element with a mask-image value other than "none"
83
- const maskImage =
84
- vNode.getComputedStylePropertyValue('-webkit-mask-image') ||
85
- vNode.getComputedStylePropertyValue('mask-image') ||
86
- 'none';
87
- if (maskImage !== 'none') {
88
- return true;
89
- }
90
-
91
- // element with a mask-border value other than "none"
92
- const maskBorder =
93
- vNode.getComputedStylePropertyValue('-webkit-mask-border') ||
94
- vNode.getComputedStylePropertyValue('mask-border') ||
95
- 'none';
96
- if (maskBorder !== 'none') {
97
- return true;
98
- }
99
-
100
- // elements with isolation set to "isolate"
101
- if (vNode.getComputedStylePropertyValue('isolation') === 'isolate') {
102
- return true;
103
- }
104
-
105
- // transform or opacity in will-change even if you don't specify values for these attributes directly
106
- const willChange = vNode.getComputedStylePropertyValue('will-change');
107
- if (willChange === 'transform' || willChange === 'opacity') {
108
- return true;
109
- }
110
-
111
- // elements with -webkit-overflow-scrolling set to "touch"
112
- if (
113
- vNode.getComputedStylePropertyValue('-webkit-overflow-scrolling') ===
114
- 'touch'
115
- ) {
116
- return true;
117
- }
118
-
119
- // element with a contain value of "layout" or "paint" or a composite value
120
- // that includes either of them (i.e. contain: strict, contain: content).
121
- const contain = vNode.getComputedStylePropertyValue('contain');
122
- if (['layout', 'paint', 'strict', 'content'].includes(contain)) {
123
- return true;
124
- }
125
-
126
- // a flex item or gird item with a z-index value other than "auto", that is the parent element display: flex|inline-flex|grid|inline-grid,
127
- if (zIndex !== 'auto' && parentVNode) {
128
- const parentDsiplay = parentVNode.getComputedStylePropertyValue('display');
129
- if (
130
- [
131
- 'flex',
132
- 'inline-flex',
133
- 'inline flex',
134
- 'grid',
135
- 'inline-grid',
136
- 'inline grid'
137
- ].includes(parentDsiplay)
138
- ) {
139
- return true;
140
- }
141
- }
142
-
143
- return false;
17
+ const position = vNode.getComputedStylePropertyValue('position');
18
+ const zIndex = vNode.getComputedStylePropertyValue('z-index');
19
+
20
+ // the root element (HTML) is skipped since we always start with a
21
+ // stacking order of [0]
22
+
23
+ // position: fixed or sticky
24
+ if (position === 'fixed' || position === 'sticky') {
25
+ return true;
26
+ }
27
+
28
+ // positioned (absolutely or relatively) with a z-index value other than "auto",
29
+ if (zIndex !== 'auto' && position !== 'static') {
30
+ return true;
31
+ }
32
+
33
+ // elements with an opacity value less than 1.
34
+ if (vNode.getComputedStylePropertyValue('opacity') !== '1') {
35
+ return true;
36
+ }
37
+
38
+ // elements with a transform value other than "none"
39
+ const transform =
40
+ vNode.getComputedStylePropertyValue('-webkit-transform') ||
41
+ vNode.getComputedStylePropertyValue('-ms-transform') ||
42
+ vNode.getComputedStylePropertyValue('transform') ||
43
+ 'none';
44
+
45
+ if (transform !== 'none') {
46
+ return true;
47
+ }
48
+
49
+ // elements with a mix-blend-mode value other than "normal"
50
+ const mixBlendMode = vNode.getComputedStylePropertyValue('mix-blend-mode');
51
+ if (mixBlendMode && mixBlendMode !== 'normal') {
52
+ return true;
53
+ }
54
+
55
+ // elements with a filter value other than "none"
56
+ const filter = vNode.getComputedStylePropertyValue('filter');
57
+ if (filter && filter !== 'none') {
58
+ return true;
59
+ }
60
+
61
+ // elements with a perspective value other than "none"
62
+ const perspective = vNode.getComputedStylePropertyValue('perspective');
63
+ if (perspective && perspective !== 'none') {
64
+ return true;
65
+ }
66
+
67
+ // element with a clip-path value other than "none"
68
+ const clipPath = vNode.getComputedStylePropertyValue('clip-path');
69
+ if (clipPath && clipPath !== 'none') {
70
+ return true;
71
+ }
72
+
73
+ // element with a mask value other than "none"
74
+ const mask =
75
+ vNode.getComputedStylePropertyValue('-webkit-mask') ||
76
+ vNode.getComputedStylePropertyValue('mask') ||
77
+ 'none';
78
+ if (mask !== 'none') {
79
+ return true;
80
+ }
81
+
82
+ // element with a mask-image value other than "none"
83
+ const maskImage =
84
+ vNode.getComputedStylePropertyValue('-webkit-mask-image') ||
85
+ vNode.getComputedStylePropertyValue('mask-image') ||
86
+ 'none';
87
+ if (maskImage !== 'none') {
88
+ return true;
89
+ }
90
+
91
+ // element with a mask-border value other than "none"
92
+ const maskBorder =
93
+ vNode.getComputedStylePropertyValue('-webkit-mask-border') ||
94
+ vNode.getComputedStylePropertyValue('mask-border') ||
95
+ 'none';
96
+ if (maskBorder !== 'none') {
97
+ return true;
98
+ }
99
+
100
+ // elements with isolation set to "isolate"
101
+ if (vNode.getComputedStylePropertyValue('isolation') === 'isolate') {
102
+ return true;
103
+ }
104
+
105
+ // transform or opacity in will-change even if you don't specify values for these attributes directly
106
+ const willChange = vNode.getComputedStylePropertyValue('will-change');
107
+ if (willChange === 'transform' || willChange === 'opacity') {
108
+ return true;
109
+ }
110
+
111
+ // elements with -webkit-overflow-scrolling set to "touch"
112
+ if (
113
+ vNode.getComputedStylePropertyValue('-webkit-overflow-scrolling') ===
114
+ 'touch'
115
+ ) {
116
+ return true;
117
+ }
118
+
119
+ // element with a contain value of "layout" or "paint" or a composite value
120
+ // that includes either of them (i.e. contain: strict, contain: content).
121
+ const contain = vNode.getComputedStylePropertyValue('contain');
122
+ if (['layout', 'paint', 'strict', 'content'].includes(contain)) {
123
+ return true;
124
+ }
125
+
126
+ // a flex item or gird item with a z-index value other than "auto", that is the parent element display: flex|inline-flex|grid|inline-grid,
127
+ if (zIndex !== 'auto' && parentVNode) {
128
+ const parentDsiplay = parentVNode.getComputedStylePropertyValue('display');
129
+ if (
130
+ [
131
+ 'flex',
132
+ 'inline-flex',
133
+ 'inline flex',
134
+ 'grid',
135
+ 'inline-grid',
136
+ 'inline grid'
137
+ ].includes(parentDsiplay)
138
+ ) {
139
+ return true;
140
+ }
141
+ }
142
+
143
+ return false;
144
144
  }
145
145
 
146
146
  /**
@@ -149,24 +149,24 @@ function isStackingContext(vNode, parentVNode) {
149
149
  * @see https://github.com/dequelabs/axe-core/issues/2222
150
150
  */
151
151
  function isFloated(vNode) {
152
- if (!vNode) {
153
- return false;
154
- }
152
+ if (!vNode) {
153
+ return false;
154
+ }
155
155
 
156
- if (vNode._isFloated !== undefined) {
157
- return vNode._isFloated;
158
- }
156
+ if (vNode._isFloated !== undefined) {
157
+ return vNode._isFloated;
158
+ }
159
159
 
160
- const floatStyle = vNode.getComputedStylePropertyValue('float');
160
+ const floatStyle = vNode.getComputedStylePropertyValue('float');
161
161
 
162
- if (floatStyle !== 'none') {
163
- vNode._isFloated = true;
164
- return true;
165
- }
162
+ if (floatStyle !== 'none') {
163
+ vNode._isFloated = true;
164
+ return true;
165
+ }
166
166
 
167
- const floated = isFloated(vNode.parent);
168
- vNode._isFloated = floated;
169
- return floated;
167
+ const floated = isFloated(vNode.parent);
168
+ vNode._isFloated = floated;
169
+ return floated;
170
170
  }
171
171
 
172
172
  /**
@@ -179,25 +179,25 @@ function isFloated(vNode) {
179
179
  * @return {Number}
180
180
  */
181
181
  function getPositionOrder(vNode) {
182
- if (vNode.getComputedStylePropertyValue('position') === 'static') {
183
- // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
184
- if (
185
- vNode.getComputedStylePropertyValue('display').indexOf('inline') !== -1
186
- ) {
187
- return 2;
188
- }
189
-
190
- // 4. the non-positioned floats.
191
- if (isFloated(vNode)) {
192
- return 1;
193
- }
194
-
195
- // 3. the in-flow, non-inline-level, non-positioned descendants.
196
- return 0;
197
- }
198
-
199
- // 6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
200
- return 3;
182
+ if (vNode.getComputedStylePropertyValue('position') === 'static') {
183
+ // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
184
+ if (
185
+ vNode.getComputedStylePropertyValue('display').indexOf('inline') !== -1
186
+ ) {
187
+ return 2;
188
+ }
189
+
190
+ // 4. the non-positioned floats.
191
+ if (isFloated(vNode)) {
192
+ return 1;
193
+ }
194
+
195
+ // 3. the in-flow, non-inline-level, non-positioned descendants.
196
+ return 0;
197
+ }
198
+
199
+ // 6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
200
+ return 3;
201
201
  }
202
202
 
203
203
  /**
@@ -208,82 +208,82 @@ function getPositionOrder(vNode) {
208
208
  * @param {VirtualNode}
209
209
  */
210
210
  function visuallySort(a, b) {
211
- /*eslint no-bitwise: 0 */
212
- for (let i = 0; i < a._stackingOrder.length; i++) {
213
- if (typeof b._stackingOrder[i] === 'undefined') {
214
- return -1;
215
- }
216
-
217
- // 7. the child stacking contexts with positive stack levels (least positive first).
218
- if (b._stackingOrder[i] > a._stackingOrder[i]) {
219
- return 1;
220
- }
221
-
222
- // 2. the child stacking contexts with negative stack levels (most negative first).
223
- if (b._stackingOrder[i] < a._stackingOrder[i]) {
224
- return -1;
225
- }
226
- }
227
-
228
- // nodes are the same stacking order
229
- let aNode = a.actualNode;
230
- let bNode = b.actualNode;
231
-
232
- // elements don't correctly calculate document position when comparing
233
- // across shadow boundaries, so we need to compare the position of a
234
- // shared host instead
235
-
236
- // elements have different hosts
237
- if (aNode.getRootNode && aNode.getRootNode() !== bNode.getRootNode()) {
238
- // keep track of all parent hosts and find the one both nodes share
239
- const boundaries = [];
240
- while (aNode) {
241
- boundaries.push({
242
- root: aNode.getRootNode(),
243
- node: aNode
244
- });
245
- aNode = aNode.getRootNode().host;
246
- }
247
-
248
- while (
249
- bNode &&
250
- !boundaries.find(boundary => boundary.root === bNode.getRootNode())
251
- ) {
252
- bNode = bNode.getRootNode().host;
253
- }
254
-
255
- // bNode is a node that shares a host with some part of the a parent
256
- // shadow tree, find the aNode that shares the same host as bNode
257
- aNode = boundaries.find(boundary => boundary.root === bNode.getRootNode())
258
- .node;
259
-
260
- // sort child of shadow to it's host node by finding which element is
261
- // the child of the host and sorting it before the host
262
- if (aNode === bNode) {
263
- return a.actualNode.getRootNode() !== aNode.getRootNode() ? -1 : 1;
264
- }
265
- }
266
-
267
- const {
268
- DOCUMENT_POSITION_FOLLOWING,
269
- DOCUMENT_POSITION_CONTAINS,
270
- DOCUMENT_POSITION_CONTAINED_BY
271
- } = window.Node;
272
-
273
- const docPosition = aNode.compareDocumentPosition(bNode);
274
- const DOMOrder = docPosition & DOCUMENT_POSITION_FOLLOWING ? 1 : -1;
275
- const isDescendant =
276
- docPosition & DOCUMENT_POSITION_CONTAINS ||
277
- docPosition & DOCUMENT_POSITION_CONTAINED_BY;
278
- const aPosition = getPositionOrder(a);
279
- const bPosition = getPositionOrder(b);
280
-
281
- // a child of a positioned element should also be on top of the parent
282
- if (aPosition === bPosition || isDescendant) {
283
- return DOMOrder;
284
- }
285
-
286
- return bPosition - aPosition;
211
+ /*eslint no-bitwise: 0 */
212
+ for (let i = 0; i < a._stackingOrder.length; i++) {
213
+ if (typeof b._stackingOrder[i] === 'undefined') {
214
+ return -1;
215
+ }
216
+
217
+ // 7. the child stacking contexts with positive stack levels (least positive first).
218
+ if (b._stackingOrder[i] > a._stackingOrder[i]) {
219
+ return 1;
220
+ }
221
+
222
+ // 2. the child stacking contexts with negative stack levels (most negative first).
223
+ if (b._stackingOrder[i] < a._stackingOrder[i]) {
224
+ return -1;
225
+ }
226
+ }
227
+
228
+ // nodes are the same stacking order
229
+ let aNode = a.actualNode;
230
+ let bNode = b.actualNode;
231
+
232
+ // elements don't correctly calculate document position when comparing
233
+ // across shadow boundaries, so we need to compare the position of a
234
+ // shared host instead
235
+
236
+ // elements have different hosts
237
+ if (aNode.getRootNode && aNode.getRootNode() !== bNode.getRootNode()) {
238
+ // keep track of all parent hosts and find the one both nodes share
239
+ const boundaries = [];
240
+ while (aNode) {
241
+ boundaries.push({
242
+ root: aNode.getRootNode(),
243
+ node: aNode
244
+ });
245
+ aNode = aNode.getRootNode().host;
246
+ }
247
+
248
+ while (
249
+ bNode &&
250
+ !boundaries.find(boundary => boundary.root === bNode.getRootNode())
251
+ ) {
252
+ bNode = bNode.getRootNode().host;
253
+ }
254
+
255
+ // bNode is a node that shares a host with some part of the a parent
256
+ // shadow tree, find the aNode that shares the same host as bNode
257
+ aNode = boundaries.find(boundary => boundary.root === bNode.getRootNode())
258
+ .node;
259
+
260
+ // sort child of shadow to it's host node by finding which element is
261
+ // the child of the host and sorting it before the host
262
+ if (aNode === bNode) {
263
+ return a.actualNode.getRootNode() !== aNode.getRootNode() ? -1 : 1;
264
+ }
265
+ }
266
+
267
+ const {
268
+ DOCUMENT_POSITION_FOLLOWING,
269
+ DOCUMENT_POSITION_CONTAINS,
270
+ DOCUMENT_POSITION_CONTAINED_BY
271
+ } = window.Node;
272
+
273
+ const docPosition = aNode.compareDocumentPosition(bNode);
274
+ const DOMOrder = docPosition & DOCUMENT_POSITION_FOLLOWING ? 1 : -1;
275
+ const isDescendant =
276
+ docPosition & DOCUMENT_POSITION_CONTAINS ||
277
+ docPosition & DOCUMENT_POSITION_CONTAINED_BY;
278
+ const aPosition = getPositionOrder(a);
279
+ const bPosition = getPositionOrder(b);
280
+
281
+ // a child of a positioned element should also be on top of the parent
282
+ if (aPosition === bPosition || isDescendant) {
283
+ return DOMOrder;
284
+ }
285
+
286
+ return bPosition - aPosition;
287
287
  }
288
288
 
289
289
  /**
@@ -293,16 +293,16 @@ function visuallySort(a, b) {
293
293
  * @return {Number[]}
294
294
  */
295
295
  function getStackingOrder(vNode, parentVNode) {
296
- const stackingOrder = parentVNode._stackingOrder.slice();
297
- const zIndex = vNode.getComputedStylePropertyValue('z-index');
298
- if (zIndex !== 'auto') {
299
- stackingOrder[stackingOrder.length - 1] = parseInt(zIndex);
300
- }
301
- if (isStackingContext(vNode, parentVNode)) {
302
- stackingOrder.push(0);
303
- }
304
-
305
- return stackingOrder;
296
+ const stackingOrder = parentVNode._stackingOrder.slice();
297
+ const zIndex = vNode.getComputedStylePropertyValue('z-index');
298
+ if (zIndex !== 'auto') {
299
+ stackingOrder[stackingOrder.length - 1] = parseInt(zIndex);
300
+ }
301
+ if (isStackingContext(vNode, parentVNode)) {
302
+ stackingOrder.push(0);
303
+ }
304
+
305
+ return stackingOrder;
306
306
  }
307
307
 
308
308
  /**
@@ -311,32 +311,32 @@ function getStackingOrder(vNode, parentVNode) {
311
311
  * @return {VirtualNode|null}
312
312
  */
313
313
  function findScrollRegionParent(vNode, parentVNode) {
314
- let scrollRegionParent = null;
315
- const checkedNodes = [vNode];
316
-
317
- while (parentVNode) {
318
- if (parentVNode._scrollRegionParent) {
319
- scrollRegionParent = parentVNode._scrollRegionParent;
320
- break;
321
- }
322
-
323
- if (getScroll(parentVNode.actualNode)) {
324
- scrollRegionParent = parentVNode;
325
- break;
326
- }
327
-
328
- checkedNodes.push(parentVNode);
329
- parentVNode = getNodeFromTree(
330
- parentVNode.actualNode.parentElement || parentVNode.actualNode.parentNode
331
- );
332
- }
333
-
334
- // cache result of parent scroll region so we don't have to look up the entire
335
- // tree again for a child node
336
- checkedNodes.forEach(
337
- vNode => (vNode._scrollRegionParent = scrollRegionParent)
338
- );
339
- return scrollRegionParent;
314
+ let scrollRegionParent = null;
315
+ let checkedNodes = [vNode];
316
+
317
+ while (parentVNode) {
318
+ if (parentVNode._scrollRegionParent) {
319
+ scrollRegionParent = parentVNode._scrollRegionParent;
320
+ break;
321
+ }
322
+
323
+ if (getScroll(parentVNode.actualNode)) {
324
+ scrollRegionParent = parentVNode;
325
+ break;
326
+ }
327
+
328
+ checkedNodes.push(parentVNode);
329
+ parentVNode = getNodeFromTree(
330
+ parentVNode.actualNode.parentElement || parentVNode.actualNode.parentNode
331
+ );
332
+ }
333
+
334
+ // cache result of parent scroll region so we don't have to look up the entire
335
+ // tree again for a child node
336
+ checkedNodes.forEach(
337
+ vNode => (vNode._scrollRegionParent = scrollRegionParent)
338
+ );
339
+ return scrollRegionParent;
340
340
  }
341
341
 
342
342
  /**
@@ -345,33 +345,33 @@ function findScrollRegionParent(vNode, parentVNode) {
345
345
  * @param {VirtualNode}
346
346
  */
347
347
  function addNodeToGrid(grid, vNode) {
348
- // save a reference to where this element is in the grid so we
349
- // can find it even if it's in a subgrid
350
- vNode._grid = grid;
351
-
352
- vNode.clientRects.forEach(rect => {
353
- const x = rect.left;
354
- const y = rect.top;
355
-
356
- // "| 0" is a faster way to do Math.floor
357
- // @see https://jsperf.com/math-floor-vs-math-round-vs-parseint/152
358
- const startRow = (y / gridSize) | 0;
359
- const startCol = (x / gridSize) | 0;
360
- const endRow = ((y + rect.height) / gridSize) | 0;
361
- const endCol = ((x + rect.width) / gridSize) | 0;
362
-
363
- for (let row = startRow; row <= endRow; row++) {
364
- grid.cells[row] = grid.cells[row] || [];
365
-
366
- for (let col = startCol; col <= endCol; col++) {
367
- grid.cells[row][col] = grid.cells[row][col] || [];
368
-
369
- if (!grid.cells[row][col].includes(vNode)) {
370
- grid.cells[row][col].push(vNode);
371
- }
372
- }
373
- }
374
- });
348
+ // save a reference to where this element is in the grid so we
349
+ // can find it even if it's in a subgrid
350
+ vNode._grid = grid;
351
+
352
+ vNode.clientRects.forEach(rect => {
353
+ const x = rect.left;
354
+ const y = rect.top;
355
+
356
+ // "| 0" is a faster way to do Math.floor
357
+ // @see https://jsperf.com/math-floor-vs-math-round-vs-parseint/152
358
+ const startRow = (y / gridSize) | 0;
359
+ const startCol = (x / gridSize) | 0;
360
+ const endRow = ((y + rect.height) / gridSize) | 0;
361
+ const endCol = ((x + rect.width) / gridSize) | 0;
362
+
363
+ for (let row = startRow; row <= endRow; row++) {
364
+ grid.cells[row] = grid.cells[row] || [];
365
+
366
+ for (let col = startCol; col <= endCol; col++) {
367
+ grid.cells[row][col] = grid.cells[row][col] || [];
368
+
369
+ if (!grid.cells[row][col].includes(vNode)) {
370
+ grid.cells[row][col].push(vNode);
371
+ }
372
+ }
373
+ }
374
+ });
375
375
  }
376
376
 
377
377
  /**
@@ -379,136 +379,136 @@ function addNodeToGrid(grid, vNode) {
379
379
  * included in the flat tree
380
380
  */
381
381
  export function createGrid(
382
- root = document.body,
383
- rootGrid = {
384
- container: null,
385
- cells: []
386
- },
387
- parentVNode = null
382
+ root = document.body,
383
+ rootGrid = {
384
+ container: null,
385
+ cells: []
386
+ },
387
+ parentVNode = null
388
388
  ) {
389
- // by not starting at the htmlElement we don't have to pass a custom
390
- // filter function into the treeWalker to filter out head elements,
391
- // which would be called for every node
392
- if (!parentVNode) {
393
- let vNode = getNodeFromTree(document.documentElement);
394
- if (!vNode) {
395
- vNode = new VirtualNode(document.documentElement);
396
- }
397
-
398
- vNode._stackingOrder = [0];
399
- addNodeToGrid(rootGrid, vNode);
400
-
401
- if (getScroll(vNode.actualNode)) {
402
- const subGrid = {
403
- container: vNode,
404
- cells: []
405
- };
406
- vNode._subGrid = subGrid;
407
- }
408
- }
409
-
410
- // IE11 requires the first 3 parameters
411
- // @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createTreeWalker
412
- const treeWalker = document.createTreeWalker(
413
- root,
414
- window.NodeFilter.SHOW_ELEMENT,
415
- null,
416
- false
417
- );
418
- let node = parentVNode ? treeWalker.nextNode() : treeWalker.currentNode;
419
- while (node) {
420
- let vNode = getNodeFromTree(node);
421
-
422
- // an svg in IE11 does not have a parentElement but instead has a
423
- // parentNode. but parentNode could be a shadow root so we need to
424
- // verity it's in the tree first
425
- if (node.parentElement) {
426
- parentVNode = getNodeFromTree(node.parentElement);
427
- } else if (node.parentNode && getNodeFromTree(node.parentNode)) {
428
- parentVNode = getNodeFromTree(node.parentNode);
429
- }
430
-
431
- if (!vNode) {
432
- vNode = new axe.VirtualNode(node, parentVNode);
433
- }
434
-
435
- vNode._stackingOrder = getStackingOrder(vNode, parentVNode);
436
-
437
- const scrollRegionParent = findScrollRegionParent(vNode, parentVNode);
438
- const grid = scrollRegionParent ? scrollRegionParent._subGrid : rootGrid;
439
-
440
- if (getScroll(vNode.actualNode)) {
441
- const subGrid = {
442
- container: vNode,
443
- cells: []
444
- };
445
- vNode._subGrid = subGrid;
446
- }
447
-
448
- // filter out any elements with 0 width or height
449
- // (we don't do this before so we can calculate stacking context
450
- // of parents with 0 width/height)
451
- const rect = vNode.boundingClientRect;
452
- if (rect.width !== 0 && rect.height !== 0 && isVisible(node)) {
453
- addNodeToGrid(grid, vNode);
454
- }
455
-
456
- // add shadow root elements to the grid
457
- if (isShadowRoot(node)) {
458
- createGrid(node.shadowRoot, grid, vNode);
459
- }
460
-
461
- node = treeWalker.nextNode();
462
- }
389
+ // by not starting at the htmlElement we don't have to pass a custom
390
+ // filter function into the treeWalker to filter out head elements,
391
+ // which would be called for every node
392
+ if (!parentVNode) {
393
+ let vNode = getNodeFromTree(document.documentElement);
394
+ if (!vNode) {
395
+ vNode = new VirtualNode(document.documentElement);
396
+ }
397
+
398
+ vNode._stackingOrder = [0];
399
+ addNodeToGrid(rootGrid, vNode);
400
+
401
+ if (getScroll(vNode.actualNode)) {
402
+ const subGrid = {
403
+ container: vNode,
404
+ cells: []
405
+ };
406
+ vNode._subGrid = subGrid;
407
+ }
408
+ }
409
+
410
+ // IE11 requires the first 3 parameters
411
+ // @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createTreeWalker
412
+ const treeWalker = document.createTreeWalker(
413
+ root,
414
+ window.NodeFilter.SHOW_ELEMENT,
415
+ null,
416
+ false
417
+ );
418
+ let node = parentVNode ? treeWalker.nextNode() : treeWalker.currentNode;
419
+ while (node) {
420
+ let vNode = getNodeFromTree(node);
421
+
422
+ // an svg in IE11 does not have a parentElement but instead has a
423
+ // parentNode. but parentNode could be a shadow root so we need to
424
+ // verity it's in the tree first
425
+ if (node.parentElement) {
426
+ parentVNode = getNodeFromTree(node.parentElement);
427
+ } else if (node.parentNode && getNodeFromTree(node.parentNode)) {
428
+ parentVNode = getNodeFromTree(node.parentNode);
429
+ }
430
+
431
+ if (!vNode) {
432
+ vNode = new axe.VirtualNode(node, parentVNode);
433
+ }
434
+
435
+ vNode._stackingOrder = getStackingOrder(vNode, parentVNode);
436
+
437
+ const scrollRegionParent = findScrollRegionParent(vNode, parentVNode);
438
+ const grid = scrollRegionParent ? scrollRegionParent._subGrid : rootGrid;
439
+
440
+ if (getScroll(vNode.actualNode)) {
441
+ const subGrid = {
442
+ container: vNode,
443
+ cells: []
444
+ };
445
+ vNode._subGrid = subGrid;
446
+ }
447
+
448
+ // filter out any elements with 0 width or height
449
+ // (we don't do this before so we can calculate stacking context
450
+ // of parents with 0 width/height)
451
+ const rect = vNode.boundingClientRect;
452
+ if (rect.width !== 0 && rect.height !== 0 && isVisible(node)) {
453
+ addNodeToGrid(grid, vNode);
454
+ }
455
+
456
+ // add shadow root elements to the grid
457
+ if (isShadowRoot(node)) {
458
+ createGrid(node.shadowRoot, grid, vNode);
459
+ }
460
+
461
+ node = treeWalker.nextNode();
462
+ }
463
463
  }
464
464
 
465
465
  export function getRectStack(grid, rect, recursed = false) {
466
- // use center point of rect
467
- const x = rect.left + rect.width / 2;
468
- const y = rect.top + rect.height / 2;
469
-
470
- // NOTE: there is a very rare edge case in Chrome vs Firefox that can
471
- // return different results of `document.elementsFromPoint`. If the center
472
- // point of the element is <1px outside of another elements bounding rect,
473
- // Chrome appears to round the number up and return the element while Firefox
474
- // keeps the number as is and won't return the element. In this case, we
475
- // went with pixel perfect collision rather than rounding
476
- const row = (y / gridSize) | 0;
477
- const col = (x / gridSize) | 0;
478
- let stack = grid.cells[row][col].filter(gridCellNode => {
479
- return gridCellNode.clientRects.find(clientRect => {
480
- const rectX = clientRect.left;
481
- const rectY = clientRect.top;
482
-
483
- // perform an AABB (axis-aligned bounding box) collision check for the
484
- // point inside the rect
485
- return (
486
- x <= rectX + clientRect.width &&
487
- x >= rectX &&
488
- y <= rectY + clientRect.height &&
489
- y >= rectY
490
- );
491
- });
492
- });
493
-
494
- const gridContainer = grid.container;
495
- if (gridContainer) {
496
- stack = getRectStack(
497
- gridContainer._grid,
498
- gridContainer.boundingClientRect,
499
- true
500
- ).concat(stack);
501
- }
502
-
503
- if (!recursed) {
504
- stack = stack
505
- .sort(visuallySort)
506
- .map(vNode => vNode.actualNode)
507
- // always make sure html is the last element
508
- .concat(document.documentElement)
509
- // remove duplicates caused by adding client rects of the same node
510
- .filter((node, index, array) => array.indexOf(node) === index);
511
- }
512
-
513
- return stack;
466
+ // use center point of rect
467
+ let x = rect.left + rect.width / 2;
468
+ let y = rect.top + rect.height / 2;
469
+
470
+ // NOTE: there is a very rare edge case in Chrome vs Firefox that can
471
+ // return different results of `document.elementsFromPoint`. If the center
472
+ // point of the element is <1px outside of another elements bounding rect,
473
+ // Chrome appears to round the number up and return the element while Firefox
474
+ // keeps the number as is and won't return the element. In this case, we
475
+ // went with pixel perfect collision rather than rounding
476
+ const row = (y / gridSize) | 0;
477
+ const col = (x / gridSize) | 0;
478
+ let stack = grid.cells[row][col].filter(gridCellNode => {
479
+ return gridCellNode.clientRects.find(clientRect => {
480
+ let rectX = clientRect.left;
481
+ let rectY = clientRect.top;
482
+
483
+ // perform an AABB (axis-aligned bounding box) collision check for the
484
+ // point inside the rect
485
+ return (
486
+ x <= rectX + clientRect.width &&
487
+ x >= rectX &&
488
+ y <= rectY + clientRect.height &&
489
+ y >= rectY
490
+ );
491
+ });
492
+ });
493
+
494
+ const gridContainer = grid.container;
495
+ if (gridContainer) {
496
+ stack = getRectStack(
497
+ gridContainer._grid,
498
+ gridContainer.boundingClientRect,
499
+ true
500
+ ).concat(stack);
501
+ }
502
+
503
+ if (!recursed) {
504
+ stack = stack
505
+ .sort(visuallySort)
506
+ .map(vNode => vNode.actualNode)
507
+ // always make sure html is the last element
508
+ .concat(document.documentElement)
509
+ // remove duplicates caused by adding client rects of the same node
510
+ .filter((node, index, array) => array.indexOf(node) === index);
511
+ }
512
+
513
+ return stack;
514
514
  }