govuk_publishing_components 21.22.1 → 21.22.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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -3
  3. data/app/assets/stylesheets/govuk_publishing_components/components/_breadcrumbs.scss +34 -0
  4. data/app/assets/stylesheets/govuk_publishing_components/components/_document-list.scss +2 -2
  5. data/app/views/govuk_publishing_components/components/_breadcrumbs.html.erb +0 -3
  6. data/app/views/govuk_publishing_components/components/_contextual_breadcrumbs.html.erb +0 -2
  7. data/lib/govuk_publishing_components/version.rb +1 -1
  8. data/node_modules/axe-core/CHANGELOG.md +70 -10
  9. data/node_modules/axe-core/axe.js +1295 -632
  10. data/node_modules/axe-core/axe.min.js +2 -2
  11. data/node_modules/axe-core/bower.json +1 -1
  12. data/node_modules/axe-core/doc/API.md +1 -0
  13. data/node_modules/axe-core/doc/aria-supported.md +0 -1
  14. data/node_modules/axe-core/doc/developer-guide.md +2 -2
  15. data/node_modules/axe-core/doc/rule-descriptions.md +91 -87
  16. data/node_modules/axe-core/lib/checks/aria/abstractrole.js +10 -1
  17. data/node_modules/axe-core/lib/checks/aria/abstractrole.json +4 -1
  18. data/node_modules/axe-core/lib/checks/aria/fallbackrole.js +1 -0
  19. data/node_modules/axe-core/lib/checks/aria/fallbackrole.json +11 -0
  20. data/node_modules/axe-core/lib/checks/aria/invalidrole.js +14 -3
  21. data/node_modules/axe-core/lib/checks/aria/invalidrole.json +4 -1
  22. data/node_modules/axe-core/lib/checks/aria/required-children.js +41 -30
  23. data/node_modules/axe-core/lib/checks/aria/valid-attr-value.js +24 -9
  24. data/node_modules/axe-core/lib/checks/aria/valid-attr-value.json +2 -2
  25. data/node_modules/axe-core/lib/checks/color/color-contrast.js +23 -7
  26. data/node_modules/axe-core/lib/checks/color/color-contrast.json +7 -1
  27. data/node_modules/axe-core/lib/checks/keyboard/focusable-disabled.js +5 -0
  28. data/node_modules/axe-core/lib/checks/keyboard/focusable-modal-open.js +14 -0
  29. data/node_modules/axe-core/lib/checks/keyboard/focusable-modal-open.json +11 -0
  30. data/node_modules/axe-core/lib/checks/keyboard/focusable-not-tabbable.js +5 -0
  31. data/node_modules/axe-core/lib/checks/keyboard/page-has-elm.js +5 -1
  32. data/node_modules/axe-core/lib/checks/keyboard/page-no-duplicate-after.js +2 -0
  33. data/node_modules/axe-core/lib/checks/keyboard/page-no-duplicate-banner.json +1 -0
  34. data/node_modules/axe-core/lib/checks/keyboard/page-no-duplicate-contentinfo.json +1 -0
  35. data/node_modules/axe-core/lib/checks/keyboard/page-no-duplicate-main.json +1 -0
  36. data/node_modules/axe-core/lib/checks/keyboard/page-no-duplicate.js +14 -2
  37. data/node_modules/axe-core/lib/checks/lists/only-listitems.js +43 -49
  38. data/node_modules/axe-core/lib/checks/lists/only-listitems.json +4 -1
  39. data/node_modules/axe-core/lib/checks/media/no-autoplay-audio.js +93 -0
  40. data/node_modules/axe-core/lib/checks/media/no-autoplay-audio.json +15 -0
  41. data/node_modules/axe-core/lib/checks/navigation/identical-links-same-purpose-after.js +100 -0
  42. data/node_modules/axe-core/lib/checks/navigation/identical-links-same-purpose.js +31 -0
  43. data/node_modules/axe-core/lib/checks/navigation/identical-links-same-purpose.json +12 -0
  44. data/node_modules/axe-core/lib/checks/navigation/region.js +42 -8
  45. data/node_modules/axe-core/lib/checks/navigation/region.json +0 -1
  46. data/node_modules/axe-core/lib/checks/shared/svg-non-empty-title.js +4 -0
  47. data/node_modules/axe-core/lib/checks/shared/svg-non-empty-title.json +11 -0
  48. data/node_modules/axe-core/lib/commons/aria/index.js +12 -4
  49. data/node_modules/axe-core/lib/commons/color/get-background-color.js +5 -157
  50. data/node_modules/axe-core/lib/commons/dom/get-element-stack.js +272 -174
  51. data/node_modules/axe-core/lib/commons/dom/is-focusable.js +3 -1
  52. data/node_modules/axe-core/lib/commons/dom/is-hidden-with-css.js +2 -2
  53. data/node_modules/axe-core/lib/commons/dom/is-modal-open.js +98 -0
  54. data/node_modules/axe-core/lib/commons/dom/is-visible.js +57 -2
  55. data/node_modules/axe-core/lib/commons/dom/url-props-from-attribute.js +143 -0
  56. data/node_modules/axe-core/lib/commons/dom/visually-contains.js +62 -12
  57. data/node_modules/axe-core/lib/commons/matches/attributes.js +12 -8
  58. data/node_modules/axe-core/lib/commons/matches/from-definition.js +15 -10
  59. data/node_modules/axe-core/lib/commons/matches/index.js +11 -9
  60. data/node_modules/axe-core/lib/commons/matches/node-name.js +11 -21
  61. data/node_modules/axe-core/lib/commons/matches/properties.js +12 -9
  62. data/node_modules/axe-core/lib/commons/text/unicode.js +27 -24
  63. data/node_modules/axe-core/lib/core/base/virtual-node/virtual-node.js +11 -3
  64. data/node_modules/axe-core/lib/core/constants.js +1 -1
  65. data/node_modules/axe-core/lib/core/reporters/v1.js +6 -3
  66. data/node_modules/axe-core/lib/core/utils/contains.js +1 -1
  67. data/node_modules/axe-core/lib/core/utils/is-hidden.js +6 -6
  68. data/node_modules/axe-core/lib/core/utils/matches.js +263 -0
  69. data/node_modules/axe-core/lib/core/utils/preload-media.js +65 -0
  70. data/node_modules/axe-core/lib/core/utils/preload.js +33 -24
  71. data/node_modules/axe-core/lib/core/utils/qsa.js +7 -208
  72. data/node_modules/axe-core/lib/rules/aria-hidden-focus.json +5 -1
  73. data/node_modules/axe-core/lib/rules/aria-roles.json +1 -1
  74. data/node_modules/axe-core/lib/rules/button-name.json +1 -1
  75. data/node_modules/axe-core/lib/rules/color-contrast-matches.js +1 -1
  76. data/node_modules/axe-core/lib/rules/color-contrast.json +0 -3
  77. data/node_modules/axe-core/lib/rules/html-namespace-matches.js +1 -0
  78. data/node_modules/axe-core/lib/rules/identical-links-same-purpose-matches.js +13 -0
  79. data/node_modules/axe-core/lib/rules/identical-links-same-purpose.json +14 -0
  80. data/node_modules/axe-core/lib/rules/landmark-no-duplicate-banner.json +1 -1
  81. data/node_modules/axe-core/lib/rules/landmark-no-duplicate-contentinfo.json +1 -1
  82. data/node_modules/axe-core/lib/rules/landmark-no-duplicate-main.json +12 -0
  83. data/node_modules/axe-core/lib/rules/landmark-one-main.json +2 -2
  84. data/node_modules/axe-core/lib/rules/link-name.json +2 -4
  85. data/node_modules/axe-core/lib/rules/meta-viewport.json +1 -1
  86. data/node_modules/axe-core/lib/rules/no-autoplay-audio-matches.js +18 -0
  87. data/node_modules/axe-core/lib/rules/no-autoplay-audio.json +15 -0
  88. data/node_modules/axe-core/lib/rules/region.json +1 -2
  89. data/node_modules/axe-core/lib/rules/role-img-alt.json +2 -1
  90. data/node_modules/axe-core/lib/rules/svg-img-alt.json +24 -0
  91. data/node_modules/axe-core/lib/rules/svg-namespace-matches.js +1 -0
  92. data/node_modules/axe-core/locales/da.json +782 -0
  93. data/node_modules/axe-core/locales/fr.json +221 -42
  94. data/node_modules/axe-core/locales/ja.json +124 -24
  95. data/node_modules/axe-core/package.json +29 -26
  96. data/node_modules/axe-core/sri-history.json +26 -10
  97. metadata +27 -9
  98. data/node_modules/axe-core/doc/examples/jasmine/package-lock.json +0 -1489
  99. data/node_modules/axe-core/doc/examples/jest_react/package-lock.json +0 -7525
  100. data/node_modules/axe-core/doc/examples/mocha/package-lock.json +0 -1671
  101. data/node_modules/axe-core/doc/examples/phantomjs/package-lock.json +0 -862
  102. data/node_modules/axe-core/doc/examples/qunit/package-lock.json +0 -2951
  103. data/node_modules/axe-core/lib/checks/navigation/region-after.js +0 -1
  104. data/node_modules/axe-core/typings/axe-core/axe-core-tests.js +0 -151
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b4fbce34bcd064f394e73fd7f2934e8fc63e75c83f7a060074e77f4e5e9dc158
4
- data.tar.gz: a4448f2e003b564116ca50fc04b23f8a68f0146c6a7ac8aade4cb2ced2baf85e
3
+ metadata.gz: 4f90a6f2455647f21585244ee5a6893bfa8474baceee038ca4a5190446a68367
4
+ data.tar.gz: 49aeec37d6161caa77934cceca478f2ba27f08f6f96eb4018717ab71d19ecbe9
5
5
  SHA512:
6
- metadata.gz: b649960d546156ccc749d22f80fd109d4a7af1fef1cd6c7891609625a3e6712ef6c14e30693a7b485a4f28142478e3adc785a8c76369c4787c11655439f96b1e
7
- data.tar.gz: 16c5887e164e664b97925061636097f0142391b32081ec86a75cee11eef7dc6aa681a2b341b4095b9b0f49ff9c533b2df82f7fa657f611caea7b6594cc617c7f
6
+ metadata.gz: beb447c9295c02c585f9e0cbacb6302324b31dce14915e34bc3b41654937e3495ddde3364c5abfe860f3469808967f3d58ab2bb3c7db4e8e58951558435e8aca
7
+ data.tar.gz: 692091eab0e27eb475dffe97d24ce579ac6e6f17f3d8154591a04da2df83344c9a7064ce3615fcecee1e24fab3c7ac2853854494a9a5c1f327459af530037102
data/README.md CHANGED
@@ -1,4 +1,7 @@
1
- # GOV.UK Publishing Components
1
+ GOV.UK Publishing Components ·
2
+ [![status](https://badgen.net/github/status/alphagov/govuk_publishing_components/master)](https://ci.integration.publishing.service.gov.uk/job/govuk_publishing_components/job/master/)
3
+ [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
4
+ =====================
2
5
 
3
6
  This gem:
4
7
 
@@ -8,8 +11,6 @@ This gem:
8
11
 
9
12
  Components should be added to this gem if they are required in more than one application, otherwise they should be added to that application.
10
13
 
11
- ![Screenshot of component guide](docs/screenshot.png)
12
-
13
14
  ## How to
14
15
 
15
16
  - [Install and use this gem](/docs/install-and-use.md)
@@ -20,3 +20,37 @@
20
20
  .gem-c-breadcrumbs--inverse .govuk-breadcrumbs__list-item:before {
21
21
  border-color: govuk-colour("white");
22
22
  }
23
+
24
+ @include govuk-media-query($until: tablet) {
25
+
26
+ .govuk-breadcrumbs__list {
27
+ display: flex;
28
+ }
29
+
30
+ .govuk-breadcrumbs__list-item:not(:last-child):not(:first-child) {
31
+ display: none;
32
+ }
33
+
34
+ .govuk-breadcrumbs__list-item {
35
+ padding-top: 14px;
36
+ padding-bottom: 14px;
37
+ }
38
+
39
+ .govuk-breadcrumbs__list-item:before {
40
+ margin: 0;
41
+ top: 18px;
42
+ }
43
+
44
+ .govuk-breadcrumbs__link {
45
+ position: relative;
46
+ }
47
+
48
+ .govuk-breadcrumbs__link::after {
49
+ content: "";
50
+ position: absolute;
51
+ top: -14px;
52
+ right: 0;
53
+ left: 0;
54
+ bottom: -14px;
55
+ }
56
+ }
@@ -7,8 +7,8 @@
7
7
 
8
8
  .gem-c-document-list__item {
9
9
  overflow: hidden;
10
- margin-bottom: govuk-spacing(2);
11
- padding-bottom: govuk-spacing(2);
10
+ margin-bottom: govuk-spacing(4);
11
+ padding-bottom: govuk-spacing(4);
12
12
  border-bottom: 1px solid $govuk-border-colour;
13
13
  list-style: none;
14
14
 
@@ -1,8 +1,6 @@
1
1
  <%
2
2
  breadcrumbs ||= []
3
- collapse_on_mobile ||= false
4
3
  inverse ||= false
5
- collapse_class = collapse_on_mobile && breadcrumbs.any? { |crumb| crumb[:is_page_parent] } ? "gem-c-breadcrumbs--collapse-on-mobile" : ""
6
4
  invert_class = inverse ? "gem-c-breadcrumbs--inverse" : ""
7
5
  breadcrumb_presenter = GovukPublishingComponents::Presenters::Breadcrumbs.new(breadcrumbs, request.path)
8
6
  %>
@@ -33,4 +31,3 @@
33
31
  <% end %>
34
32
  </ol>
35
33
  </div>
36
-
@@ -15,7 +15,6 @@
15
15
  and we want to prioritise them over all other breadcrumbs %>
16
16
  <%= render 'govuk_publishing_components/components/breadcrumbs',
17
17
  breadcrumbs: navigation.taxon_breadcrumbs[:breadcrumbs],
18
- collapse_on_mobile: true,
19
18
  inverse: inverse %>
20
19
  <% elsif navigation.content_tagged_to_mainstream_browse_pages? %>
21
20
  <%# Rendering parent-based breadcrumbs because the page is tagged to mainstream browse %>
@@ -27,7 +26,6 @@
27
26
  <%# Rendering taxonomy breadcrumbs because the page is tagged to live taxons %>
28
27
  <%= render 'govuk_publishing_components/components/breadcrumbs',
29
28
  breadcrumbs: navigation.taxon_breadcrumbs[:breadcrumbs],
30
- collapse_on_mobile: true,
31
29
  inverse: inverse %>
32
30
  <% elsif navigation.breadcrumbs.any? %>
33
31
  <%# Rendering parent-based breadcrumbs because no browse, no related links, no live taxons %>
@@ -1,3 +1,3 @@
1
1
  module GovukPublishingComponents
2
- VERSION = '21.22.1'.freeze
2
+ VERSION = '21.22.2'.freeze
3
3
  end
@@ -2,42 +2,88 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
- ### [3.4.2](https://github.com/dequelabs/axe-core/compare/v3.4.0...v3.4.2) (2020-02-04)
5
+ ### [3.5.1](https://github.com/dequelabs/axe-core/compare/v3.5.0...v3.5.1) (2020-02-12)
6
+
7
+ ### Bug Fixes
8
+
9
+ - **color-contrast:** parse font-weight value as number ([#2031](https://github.com/dequelabs/axe-core/issues/2031)) ([#2040](https://github.com/dequelabs/axe-core/issues/2040)) ([0bb2166](https://github.com/dequelabs/axe-core/commit/0bb21669f75b3adc0e3345c85680d437c57f94d8))
10
+ - **color-contrast:** properly pass options to check ([#2033](https://github.com/dequelabs/axe-core/issues/2033)) ([26b99c0](https://github.com/dequelabs/axe-core/commit/26b99c0a511bd6fffaaca7535d732f26b39ef46e))
11
+ - **commons:** avoid unicode regex encoding in axe.min.js ([#2024](https://github.com/dequelabs/axe-core/issues/2024)) ([ae90dc4](https://github.com/dequelabs/axe-core/commit/ae90dc47521f6047f71befcb3551686cf857208d))
12
+ - **sri-history:** correct SRI for various versions ([#2041](https://github.com/dequelabs/axe-core/issues/2041)) ([940c017](https://github.com/dequelabs/axe-core/commit/940c01708cede33e796972ce810a815ddf492ba4))
13
+
14
+ ## [3.5.0](https://github.com/dequelabs/axe-core/compare/v3.4.0...v3.5.0) (2020-02-04)
6
15
 
7
16
  ### Features
8
17
 
9
18
  - **aria-dpub-role-fallback:** depreacte aria-dpub-role-fallback and move into aria-allowed-role ([#1899](https://github.com/dequelabs/axe-core/issues/1899)) ([8e25c20](https://github.com/dequelabs/axe-core/commit/8e25c20a479b03820117c6cd349b51ce7f2e94ee))
10
19
  - **aria-label:** deprecate Element arg; use virtualNode ([#1922](https://github.com/dequelabs/axe-core/issues/1922)) ([d14981c](https://github.com/dequelabs/axe-core/commit/d14981c1f67ba849f9519ee826ac646d281649c7))
11
20
  - **audit:** allow runOnly option to accept an array of rules ([#1889](https://github.com/dequelabs/axe-core/issues/1889)) ([38d6a3f](https://github.com/dequelabs/axe-core/commit/38d6a3fb26c66215cca0f3df8da268b34bcb6be5))
21
+ - **color-contrast:** greatly improve performance for very large sites ([#1943](https://github.com/dequelabs/axe-core/issues/1943)) ([9ea0065](https://github.com/dequelabs/axe-core/commit/9ea006534a423b2b7df1826a40e8214c6bb1fc48))
22
+ - **core:** add preload configuration option for media files ([#1958](https://github.com/dequelabs/axe-core/issues/1958)) ([8a62649](https://github.com/dequelabs/axe-core/commit/8a626498dc9694a992e76855781e2ad1cbd4fe9b))
23
+ - **core/reporters/v1:** Add failureSummary to incomplete results ([#1972](https://github.com/dequelabs/axe-core/issues/1972)) ([c88883d](https://github.com/dequelabs/axe-core/commit/c88883d00b6578593b83f3134ebf897d22a3ba61))
12
24
  - **get-element-stack:** performant api to replace document.elementsFromPoint ([#1842](https://github.com/dequelabs/axe-core/issues/1842)) ([9ae07fb](https://github.com/dequelabs/axe-core/commit/9ae07fbda36afd18a42a96d6755055006f309a4c))
25
+ - **i18n:** add Danish (da-DK) translation ([#1876](https://github.com/dequelabs/axe-core/issues/1876)) ([fb6fc41](https://github.com/dequelabs/axe-core/commit/fb6fc414246bdaf1590d367352e4bea033822639))
26
+ - **landmark-no-duplicate-\*:** add rule landmark-no-duplicate-main, don't use html as element source for all duplicate rules ([#1949](https://github.com/dequelabs/axe-core/issues/1949)) ([5ec7894](https://github.com/dequelabs/axe-core/commit/5ec7894394f8348761f5fe48ad0d09b31a27d2b2))
13
27
  - **layout-table:** deprecate layout-table rule and checks ([#1885](https://github.com/dequelabs/axe-core/issues/1885)) ([d22cb30](https://github.com/dequelabs/axe-core/commit/d22cb30ad29f5d1aec089eea3544ff88f3b4f8ab))
28
+ - **matches:** use VirtualNode and deprecate HTMLElement ([#1988](https://github.com/dequelabs/axe-core/issues/1988)) ([2600a06](https://github.com/dequelabs/axe-core/commit/2600a062d65f0c079b30d6a9f2aa3b6faeea6872))
29
+ - **rule:** add color-contrast check for unicode characters, behind flags. ([#1969](https://github.com/dequelabs/axe-core/issues/1969)) ([0cd4037](https://github.com/dequelabs/axe-core/commit/0cd40373ff9a080ffcb128ce66f9eaf80f0d19b4)), closes [#1906](https://github.com/dequelabs/axe-core/issues/1906)
30
+ - **rule:** identical-links-same-purpose ([#1649](https://github.com/dequelabs/axe-core/issues/1649)) ([9c73f62](https://github.com/dequelabs/axe-core/commit/9c73f62fea2be68cb555c36fc32c79f7ce2697dd))
31
+ - **rule:** no-autoplay-audio ([#1946](https://github.com/dequelabs/axe-core/issues/1946)) ([b2373cb](https://github.com/dequelabs/axe-core/commit/b2373cb9ce73a15e79aec86af7edff62c9a4e2b3))
32
+ - **svg-img-alt:** rule for when svg needs a title ([#1953](https://github.com/dequelabs/axe-core/issues/1953)) ([9491e09](https://github.com/dequelabs/axe-core/commit/9491e094fe82c4dba45eb253ed18bf0a0165197c))
14
33
  - deprecate the use doT.js for messages ([#1938](https://github.com/dequelabs/axe-core/issues/1938)) ([a2ddba3](https://github.com/dequelabs/axe-core/commit/a2ddba305003db0540c093f4ad9015c8854cd98d))
15
34
 
16
35
  ### Bug Fixes
17
36
 
18
- - **td-has-headers:** greatly improve performance of td-has-headers rule ([#1887](https://github.com/dequelabs/axe-core/issues/1887)) ([a550309](https://github.com/dequelabs/axe-core/commit/a550309255b025cb1e63710af2142f2c02d79657))
37
+ - **color-contrast:** properly pass options to check ([#2033](https://github.com/dequelabs/axe-core/issues/2033)) ([26b99c0](https://github.com/dequelabs/axe-core/commit/26b99c0a511bd6fffaaca7535d732f26b39ef46e))
38
+ - **commons:** avoid unicode regex encoding in axe.min.js ([#2024](https://github.com/dequelabs/axe-core/issues/2024)) ([ae90dc4](https://github.com/dequelabs/axe-core/commit/ae90dc47521f6047f71befcb3551686cf857208d))
19
39
  - add tags with dots for wcag sc ([#1849](https://github.com/dequelabs/axe-core/issues/1849)) ([2f1ab36](https://github.com/dequelabs/axe-core/commit/2f1ab36354add65fe77be3e2831278ce37c3bbab))
40
+ - compute orientation lock from various transformation func… ([#1937](https://github.com/dequelabs/axe-core/issues/1937)) ([c987de0](https://github.com/dequelabs/axe-core/commit/c987de0ce7cfcde5a280a9d6c643879093df1bcd))
41
+ - ignores axe.ping responses that do not contain axe=true ([26cb1fb](https://github.com/dequelabs/axe-core/commit/26cb1fbdd7127c421bb7ca60e07d72385c6e2ea1))
42
+ - input[role=button][value='correct'] should pass ([#1897](https://github.com/dequelabs/axe-core/issues/1897)) ([4635fef](https://github.com/dequelabs/axe-core/commit/4635fef8bafd1c1cf916962693d0deee082266cf))
43
+ - remove heading from list of widget roles ([#1882](https://github.com/dequelabs/axe-core/issues/1882)) ([a8cbf71](https://github.com/dequelabs/axe-core/commit/a8cbf717ef3aa8b0bf09ddcb17f3a95fd2d1a64a))
44
+ - **link-name:** test role=link when there is no href ([#1921](https://github.com/dequelabs/axe-core/issues/1921)) ([6db28bc](https://github.com/dequelabs/axe-core/commit/6db28bc455b1c8937f44346aa232eacc4a1c3457))
45
+ - remove isNaN check ([#2010](https://github.com/dequelabs/axe-core/issues/2010)) ([5359b3f](https://github.com/dequelabs/axe-core/commit/5359b3f06ac051963ee61fcef417bcc20bdec55b))
46
+ - **aria-allowed-attr:** allow aria-details ([#1956](https://github.com/dequelabs/axe-core/issues/1956)) ([79e1c58](https://github.com/dequelabs/axe-core/commit/79e1c58cad4fdbd1409a0b545981c12f13252432))
20
47
  - **aria-allowed-role:** allow role combobox on input tel, search, url, and email ([#1850](https://github.com/dequelabs/axe-core/issues/1850)) ([ba75961](https://github.com/dequelabs/axe-core/commit/ba759618ed8068f4eb74b6cd00f002322b20eca5))
48
+ - **aria-hidden-focus:** mark as needs review if a modal is open ([#1995](https://github.com/dequelabs/axe-core/issues/1995)) ([28a3553](https://github.com/dequelabs/axe-core/commit/28a35531b97b987e2fd1ad0beb25fbda3822fbd5))
49
+ - **aria-required-children:** allow comboboxes with more popup roles ([#1950](https://github.com/dequelabs/axe-core/issues/1950)) ([35a24c0](https://github.com/dequelabs/axe-core/commit/35a24c034520e3c6d95514e3b9d9f2ab6ca10e06))
50
+ - **aria-roles:** report error for fallback roles ([#1970](https://github.com/dequelabs/axe-core/issues/1970)) ([a1b7e08](https://github.com/dequelabs/axe-core/commit/a1b7e08f1f8e1c1caff228469cd891d0458680de))
51
+ - **aria-valid-attr-value:** mark as needs review for aria-current with invalid value ([#1998](https://github.com/dequelabs/axe-core/issues/1998)) ([39b8eae](https://github.com/dequelabs/axe-core/commit/39b8eae9d3352be4f77bef41abcb8eab268a6809))
21
52
  - **axe.d.ts:** RunOnly.values should not accept a RunOnlyOption ([#1888](https://github.com/dequelabs/axe-core/issues/1888)) ([b68aa19](https://github.com/dequelabs/axe-core/commit/b68aa19500ffb57fdf370707d7614384ac239ad6))
22
53
  - **build:** add lang query parameter to helpUrl when builing with a locale ([#1909](https://github.com/dequelabs/axe-core/issues/1909)) ([8c5f9ef](https://github.com/dequelabs/axe-core/commit/8c5f9efd6449f82e410eb7c6a68cfb5304fc66ae))
23
- - **color-contrast:** support IE extension context ([#2008](https://github.com/dequelabs/axe-core/issues/2008)) ([64f6910](https://github.com/dequelabs/axe-core/commit/64f6910e8051cd5daed8a7094dfd383ba1090273))
54
+ - **color-contrast:** improve speed and accuracy of code blocks with syntax highlighting ([#2003](https://github.com/dequelabs/axe-core/issues/2003)) ([1b6ab42](https://github.com/dequelabs/axe-core/commit/1b6ab42f72b1ea0d2ed223c6fd63b9b1e54cfa9b))
55
+ - **color-contrast:** mark as needs review for text that contains only non-BMP characters ([#2005](https://github.com/dequelabs/axe-core/issues/2005)) ([e559be0](https://github.com/dequelabs/axe-core/commit/e559be041e90951c734de4e7ad70d7299f590cf6))
56
+ - **color-contrast:** support IE extension context ([#2008](https://github.com/dequelabs/axe-core/issues/2008)) ([62e31ea](https://github.com/dequelabs/axe-core/commit/62e31ea5034871f572f8bb47dba2596fb1b13063))
24
57
  - **color-contrast:** take into account parent opacity for foreground color ([#1902](https://github.com/dequelabs/axe-core/issues/1902)) ([8719700](https://github.com/dequelabs/axe-core/commit/87197005d046cc8c845764ff9107683938864c65))
58
+ - **getElementStack:** do not add hidden elements to the stack ([#1991](https://github.com/dequelabs/axe-core/issues/1991)) ([759d88d](https://github.com/dequelabs/axe-core/commit/759d88d08af059755d908794038770cc57448252))
25
59
  - **is-focusable:** use tabindex attribute instead of property ([#1912](https://github.com/dequelabs/axe-core/issues/1912)) ([042a148](https://github.com/dequelabs/axe-core/commit/042a1487df76489483330274933d06fd27b842e0))
26
60
  - **is-icon-ligature:** ignore whitespace characters ([#1908](https://github.com/dequelabs/axe-core/issues/1908)) ([7d2b2a6](https://github.com/dequelabs/axe-core/commit/7d2b2a6fca992e27bab36ed8ab64b7ba3385d7e5))
27
61
  - **is-ligature-icon:** rename canvas to canvasContext ([#1880](https://github.com/dequelabs/axe-core/issues/1880)) ([de9885d](https://github.com/dequelabs/axe-core/commit/de9885d5708d6928fa2eb2816351879307a31a5b))
28
- - **link-name:** test role=link when there is no href ([#1921](https://github.com/dequelabs/axe-core/issues/1921)) ([6db28bc](https://github.com/dequelabs/axe-core/commit/6db28bc455b1c8937f44346aa232eacc4a1c3457))
62
+ - **isFocusable:** return true for summary element and false for details element with summary child ([#1957](https://github.com/dequelabs/axe-core/issues/1957)) ([34ec2d7](https://github.com/dequelabs/axe-core/commit/34ec2d7326786347f8704786e886fc8d13dd3f9b))
29
63
  - **listitem:** clarify that li elements must be contained in a list or role=list ([#1894](https://github.com/dequelabs/axe-core/issues/1894)) ([6d8cfee](https://github.com/dequelabs/axe-core/commit/6d8cfee91f0f0b5dcacba7ffb0b3d6505862e6b7))
30
64
  - **locales:** fix incompeteMessageFallback to be a string rather than an object ([#1853](https://github.com/dequelabs/axe-core/issues/1853)) ([88677a9](https://github.com/dequelabs/axe-core/commit/88677a93d0ffe32d7305984314a37e623fb51153))
65
+ - **meta-viewport:** mark as a best-practice rule instead of wcag failure ([#1960](https://github.com/dequelabs/axe-core/issues/1960)) ([766f962](https://github.com/dequelabs/axe-core/commit/766f96210d05d35cab0139839db4f009b1139ce1))
66
+ - **only-listitem:** add message about invalid role on li elements ([#1954](https://github.com/dequelabs/axe-core/issues/1954)) ([c3049ab](https://github.com/dequelabs/axe-core/commit/c3049abaccff72412ec3d58fab9b386fe8a2ae5a))
67
+ - **page-has-main:** do not find hidden elements ([#2001](https://github.com/dequelabs/axe-core/issues/2001)) ([6429e60](https://github.com/dequelabs/axe-core/commit/6429e608f082db76b4cc445679b61a6e0ab8f034))
68
+ - **page-no-duplicate-main:** do not fail for duplicate hidden elements ([#2000](https://github.com/dequelabs/axe-core/issues/2000)) ([414dfb1](https://github.com/dequelabs/axe-core/commit/414dfb1c9a4ade645ce60e8918e8143fe58b3eb6))
69
+ - **preload:** reject promise `axe.utils.preload` when XHR fails ([#2009](https://github.com/dequelabs/axe-core/issues/2009)) ([b406b1f](https://github.com/dequelabs/axe-core/commit/b406b1fd09d72f9193d5b4011fa6f24bd33e3576))
70
+ - **region:** allow content in roles with implicit aria-live ([#2002](https://github.com/dequelabs/axe-core/issues/2002)) ([a8d829e](https://github.com/dequelabs/axe-core/commit/a8d829e081dabb62a5247e8956adbf7a2ef000a2))
71
+ - **region:** return outermost regionless node instead of html ([#1980](https://github.com/dequelabs/axe-core/issues/1980)) ([8d77be2](https://github.com/dequelabs/axe-core/commit/8d77be206e11537e8b509d593707c98143181bfa))
72
+ - **region-rule:** allow live regions with explicit roles ([#1999](https://github.com/dequelabs/axe-core/issues/1999)) ([b49bd95](https://github.com/dequelabs/axe-core/commit/b49bd9547b7d8ac392ebf958356f90aca7e48a38))
31
73
  - **run:** throw error if axe.run is called after a run has started but not completed ([#1914](https://github.com/dequelabs/axe-core/issues/1914)) ([3252a02](https://github.com/dequelabs/axe-core/commit/3252a020ffd372e9583d39c989affd3d3b22957b))
32
74
  - **server-side-image-map:** return as needs review rather than failure ([#1898](https://github.com/dequelabs/axe-core/issues/1898)) ([d544856](https://github.com/dequelabs/axe-core/commit/d5448567b23de8289443c9c314b34b3140f68c30))
33
75
  - **tabindex:** don't error when tabindex property is overridden ([#1910](https://github.com/dequelabs/axe-core/issues/1910)) ([6b82a4c](https://github.com/dequelabs/axe-core/commit/6b82a4c513a1d5be78dcc54ad90a90768613b918))
34
- - **typings:** add proper return value to getRule ([#1900](https://github.com/dequelabs/axe-core/issues/1900)) ([4d907f8](https://github.com/dequelabs/axe-core/commit/4d907f86b0152122f92cceae0b242e09aff0f49a))
35
- - **unicode:** stop parsing escaped unicode strings ([#1997](https://github.com/dequelabs/axe-core/issues/1997)) ([5b49264](https://github.com/dequelabs/axe-core/commit/5b49264e2a2b5e84c839825bf88e3a0745731153))
36
- - compute orientation lock from various transformation func… ([#1937](https://github.com/dequelabs/axe-core/issues/1937)) ([c987de0](https://github.com/dequelabs/axe-core/commit/c987de0ce7cfcde5a280a9d6c643879093df1bcd))
37
- - ignores axe.ping responses that do not contain axe=true ([26cb1fb](https://github.com/dequelabs/axe-core/commit/26cb1fbdd7127c421bb7ca60e07d72385c6e2ea1))
38
- - input[role=button][value='correct'] should pass ([#1897](https://github.com/dequelabs/axe-core/issues/1897)) ([4635fef](https://github.com/dequelabs/axe-core/commit/4635fef8bafd1c1cf916962693d0deee082266cf))
39
- - remove heading from list of widget roles ([#1882](https://github.com/dequelabs/axe-core/issues/1882)) ([a8cbf71](https://github.com/dequelabs/axe-core/commit/a8cbf717ef3aa8b0bf09ddcb17f3a95fd2d1a64a))
76
+ - **td-has-headers:** greatly improve performance of td-has-headers rule ([#1887](https://github.com/dequelabs/axe-core/issues/1887)) ([a550309](https://github.com/dequelabs/axe-core/commit/a550309255b025cb1e63710af2142f2c02d79657))
40
77
  - removes flaky test in axe Pro api check ([b2bdcd1](https://github.com/dequelabs/axe-core/commit/b2bdcd13e7623d3111f7035f2e951ff6b330132c))
78
+ - **typings:** add proper return value to getRule ([#1900](https://github.com/dequelabs/axe-core/issues/1900)) ([4d907f8](https://github.com/dequelabs/axe-core/commit/4d907f86b0152122f92cceae0b242e09aff0f49a))
79
+ - **unicode:** stop parsing escaped unicode strings ([#1997](https://github.com/dequelabs/axe-core/issues/1997)) ([7447d03](https://github.com/dequelabs/axe-core/commit/7447d03bcfd118897d8114fded1ea8a42f3da08f))
80
+
81
+ ## [3.4.2](https://github.com/dequelabs/axe-core/compare/v3.4.1...v3.4.2) (2020-02-04)
82
+
83
+ ### Bug Fixes
84
+
85
+ - **color-contrast:** support IE extension context ([#2008](https://github.com/dequelabs/axe-core/issues/2008)) ([cd651a0](https://github.com/dequelabs/axe-core/commit/cd651a0713fa2f4b307cc7fc2be033f8636b40d2))
86
+ - **unicode:** stop parsing escaped unicode strings ([#1997](https://github.com/dequelabs/axe-core/issues/1997)) ([523a31c](https://github.com/dequelabs/axe-core/commit/523a31c19fefd330e0b4f4c45f51d400c6f66164))
41
87
 
42
88
  ### [3.4.1](https://github.com/dequelabs/axe-core/compare/v3.4.0...v3.4.1) (2019-12-11)
43
89
 
@@ -103,6 +149,13 @@ All notable changes to this project will be documented in this file. See [standa
103
149
  - **runVirtualNode:** Allow serialised nodes [experimental](<[512d51b](https://github.com/dequelabs/axe-core/commit/512d51b)>)
104
150
  - **video-description:** deprecate video-description rule ([#1737](https://github.com/dequelabs/axe-core/issues/1737)) ([e91c25f](https://github.com/dequelabs/axe-core/commit/e91c25f))
105
151
 
152
+ ## [3.3.3](https://github.com/dequelabs/axe-core/compare/v3.3.2...v3.3.3) (2020-02-04)
153
+
154
+ ### Bug Fixes
155
+
156
+ - **color-contrast:** support IE extension context ([#2008](https://github.com/dequelabs/axe-core/issues/2008)) ([cd651a0](https://github.com/dequelabs/axe-core/commit/cd651a0713fa2f4b307cc7fc2be033f8636b40d2))
157
+ - **unicode:** stop parsing escaped unicode strings ([#1997](https://github.com/dequelabs/axe-core/issues/1997)) ([523a31c](https://github.com/dequelabs/axe-core/commit/523a31c19fefd330e0b4f4c45f51d400c6f66164))
158
+
106
159
  ### [3.3.2](https://github.com/dequelabs/axe-core/compare/v3.3.1...v3.3.2) (2019-08-12)
107
160
 
108
161
  ### Bug Fixes
@@ -203,6 +256,13 @@ All notable changes to this project will be documented in this file. See [standa
203
256
  - only run IE11 tests in appveyor ([#1571](https://github.com/dequelabs/axe-core/issues/1571)) ([35261ef](https://github.com/dequelabs/axe-core/commit/35261ef))
204
257
  - watch integration html and json files ([#1598](https://github.com/dequelabs/axe-core/issues/1598)) ([3de0b05](https://github.com/dequelabs/axe-core/commit/3de0b05))
205
258
 
259
+ ## [3.2.3](https://github.com/dequelabs/axe-core/compare/v3.2.2...v3.2.3) (2020-02-04)
260
+
261
+ ### Bug Fixes
262
+
263
+ - **color-contrast:** support IE extension context ([#2008](https://github.com/dequelabs/axe-core/issues/2008)) ([cd651a0](https://github.com/dequelabs/axe-core/commit/cd651a0713fa2f4b307cc7fc2be033f8636b40d2))
264
+ - **unicode:** stop parsing escaped unicode strings ([#1997](https://github.com/dequelabs/axe-core/issues/1997)) ([523a31c](https://github.com/dequelabs/axe-core/commit/523a31c19fefd330e0b4f4c45f51d400c6f66164))
265
+
206
266
  ## [3.2.2](https://github.com/dequelabs/axe-core/compare/v3.2.0...v3.2.2) (2019-03-07)
207
267
 
208
268
  ### Bug Fixes
@@ -1,4 +1,4 @@
1
- /*! axe v3.4.2
1
+ /*! axe v3.5.1
2
2
  * Copyright (c) 2020 Deque Systems, Inc.
3
3
  *
4
4
  * Your use of this Source Code Form is subject to the terms of the Mozilla Public
@@ -27,7 +27,7 @@
27
27
  return _typeof(obj);
28
28
  }
29
29
  var axe = axe || {};
30
- axe.version = '3.4.2';
30
+ axe.version = '3.5.1';
31
31
  if (typeof define === 'function' && define.amd) {
32
32
  define('axe-core', [], function() {
33
33
  'use strict';
@@ -9692,6 +9692,7 @@
9692
9692
  };
9693
9693
  return _setPrototypeOf(o, p);
9694
9694
  }
9695
+ var isXHTMLGlobal;
9695
9696
  var VirtualNode = function(_axe$AbstractVirtualN) {
9696
9697
  _inherits(VirtualNode, _axe$AbstractVirtualN);
9697
9698
  function VirtualNode(node, parent, shadowId) {
@@ -9704,6 +9705,10 @@
9704
9705
  _this.parent = parent;
9705
9706
  _this._isHidden = null;
9706
9707
  _this._cache = {};
9708
+ if (typeof isXHTMLGlobal === 'undefined') {
9709
+ isXHTMLGlobal = axe.utils.isXHTML(node.ownerDocument);
9710
+ }
9711
+ _this._isXHTML = isXHTMLGlobal;
9707
9712
  if (axe._cache.get('nodeMap')) {
9708
9713
  axe._cache.get('nodeMap').set(node, _assertThisInitialized(_this));
9709
9714
  }
@@ -9740,12 +9745,13 @@
9740
9745
  }, {
9741
9746
  key: 'props',
9742
9747
  get: function get() {
9743
- var _this$actualNode = this.actualNode, nodeType = _this$actualNode.nodeType, nodeName = _this$actualNode.nodeName, id = _this$actualNode.id, type = _this$actualNode.type;
9748
+ var _this$actualNode = this.actualNode, nodeType = _this$actualNode.nodeType, nodeName = _this$actualNode.nodeName, id = _this$actualNode.id, type = _this$actualNode.type, multiple = _this$actualNode.multiple;
9744
9749
  return {
9745
9750
  nodeType: nodeType,
9746
- nodeName: nodeName.toLowerCase(),
9751
+ nodeName: this._isXHTML ? nodeName : nodeName.toLowerCase(),
9747
9752
  id: id,
9748
- type: type
9753
+ type: type,
9754
+ multiple: multiple
9749
9755
  };
9750
9756
  }
9751
9757
  }, {
@@ -9816,7 +9822,7 @@
9816
9822
  resultGroupMap: {},
9817
9823
  impact: Object.freeze([ 'minor', 'moderate', 'serious', 'critical' ]),
9818
9824
  preload: Object.freeze({
9819
- assets: [ 'cssom' ],
9825
+ assets: [ 'cssom', 'media' ],
9820
9826
  timeout: 1e4
9821
9827
  })
9822
9828
  };
@@ -10648,11 +10654,13 @@
10648
10654
  options = {};
10649
10655
  }
10650
10656
  var out = helpers.processAggregate(results, options);
10651
- out.violations.forEach(function(result) {
10652
- return result.nodes.forEach(function(nodeResult) {
10657
+ var addFailureSummaries = function addFailureSummaries(result) {
10658
+ result.nodes.forEach(function(nodeResult) {
10653
10659
  nodeResult.failureSummary = helpers.failureSummary(nodeResult);
10654
10660
  });
10655
- });
10661
+ };
10662
+ out.incomplete.forEach(addFailureSummaries);
10663
+ out.violations.forEach(addFailureSummaries);
10656
10664
  callback(_extends({}, helpers.getEnvironmentData(), {
10657
10665
  toolOptions: options,
10658
10666
  violations: out.violations,
@@ -11889,6 +11897,186 @@
11889
11897
  return doc.createElement('A').localName === 'A';
11890
11898
  };
11891
11899
  'use strict';
11900
+ function matchesTag(vNode, exp) {
11901
+ return vNode.props.nodeType === 1 && (exp.tag === '*' || vNode.props.nodeName === exp.tag);
11902
+ }
11903
+ function matchesClasses(vNode, exp) {
11904
+ return !exp.classes || exp.classes.every(function(cl) {
11905
+ return vNode.hasClass(cl.value);
11906
+ });
11907
+ }
11908
+ function matchesAttributes(vNode, exp) {
11909
+ return !exp.attributes || exp.attributes.every(function(att) {
11910
+ var nodeAtt = vNode.attr(att.key);
11911
+ return nodeAtt !== null && (!att.value || att.test(nodeAtt));
11912
+ });
11913
+ }
11914
+ function matchesId(vNode, exp) {
11915
+ return !exp.id || vNode.props.id === exp.id;
11916
+ }
11917
+ function matchesPseudos(target, exp) {
11918
+ if (!exp.pseudos || exp.pseudos.every(function(pseudo) {
11919
+ if (pseudo.name === 'not') {
11920
+ return !axe.utils.matchesExpression(target, pseudo.expressions[0]);
11921
+ }
11922
+ throw new Error('the pseudo selector ' + pseudo.name + ' has not yet been implemented');
11923
+ })) {
11924
+ return true;
11925
+ }
11926
+ return false;
11927
+ }
11928
+ function matchExpression(vNode, expression) {
11929
+ return matchesTag(vNode, expression) && matchesClasses(vNode, expression) && matchesAttributes(vNode, expression) && matchesId(vNode, expression) && matchesPseudos(vNode, expression);
11930
+ }
11931
+ var escapeRegExp = function() {
11932
+ var from = /(?=[\-\[\]{}()*+?.\\\^$|,#\s])/g;
11933
+ var to = '\\';
11934
+ return function(string) {
11935
+ return string.replace(from, to);
11936
+ };
11937
+ }();
11938
+ var reUnescape = /\\/g;
11939
+ function convertAttributes(atts) {
11940
+ if (!atts) {
11941
+ return;
11942
+ }
11943
+ return atts.map(function(att) {
11944
+ var attributeKey = att.name.replace(reUnescape, '');
11945
+ var attributeValue = (att.value || '').replace(reUnescape, '');
11946
+ var test, regexp;
11947
+ switch (att.operator) {
11948
+ case '^=':
11949
+ regexp = new RegExp('^' + escapeRegExp(attributeValue));
11950
+ break;
11951
+
11952
+ case '$=':
11953
+ regexp = new RegExp(escapeRegExp(attributeValue) + '$');
11954
+ break;
11955
+
11956
+ case '~=':
11957
+ regexp = new RegExp('(^|\\s)' + escapeRegExp(attributeValue) + '(\\s|$)');
11958
+ break;
11959
+
11960
+ case '|=':
11961
+ regexp = new RegExp('^' + escapeRegExp(attributeValue) + '(-|$)');
11962
+ break;
11963
+
11964
+ case '=':
11965
+ test = function test(value) {
11966
+ return attributeValue === value;
11967
+ };
11968
+ break;
11969
+
11970
+ case '*=':
11971
+ test = function test(value) {
11972
+ return value && value.includes(attributeValue);
11973
+ };
11974
+ break;
11975
+
11976
+ case '!=':
11977
+ test = function test(value) {
11978
+ return attributeValue !== value;
11979
+ };
11980
+ break;
11981
+
11982
+ default:
11983
+ test = function test(value) {
11984
+ return !!value;
11985
+ };
11986
+ }
11987
+ if (attributeValue === '' && /^[*$^]=$/.test(att.operator)) {
11988
+ test = function test() {
11989
+ return false;
11990
+ };
11991
+ }
11992
+ if (!test) {
11993
+ test = function test(value) {
11994
+ return value && regexp.test(value);
11995
+ };
11996
+ }
11997
+ return {
11998
+ key: attributeKey,
11999
+ value: attributeValue,
12000
+ test: test
12001
+ };
12002
+ });
12003
+ }
12004
+ function convertClasses(classes) {
12005
+ if (!classes) {
12006
+ return;
12007
+ }
12008
+ return classes.map(function(className) {
12009
+ className = className.replace(reUnescape, '');
12010
+ return {
12011
+ value: className,
12012
+ regexp: new RegExp('(^|\\s)' + escapeRegExp(className) + '(\\s|$)')
12013
+ };
12014
+ });
12015
+ }
12016
+ function convertPseudos(pseudos) {
12017
+ if (!pseudos) {
12018
+ return;
12019
+ }
12020
+ return pseudos.map(function(p) {
12021
+ var expressions;
12022
+ if (p.name === 'not') {
12023
+ expressions = p.value;
12024
+ expressions = expressions.selectors ? expressions.selectors : [ expressions ];
12025
+ expressions = convertExpressions(expressions);
12026
+ }
12027
+ return {
12028
+ name: p.name,
12029
+ expressions: expressions,
12030
+ value: p.value
12031
+ };
12032
+ });
12033
+ }
12034
+ function convertExpressions(expressions) {
12035
+ return expressions.map(function(exp) {
12036
+ var newExp = [];
12037
+ var rule = exp.rule;
12038
+ while (rule) {
12039
+ newExp.push({
12040
+ tag: rule.tagName ? rule.tagName.toLowerCase() : '*',
12041
+ combinator: rule.nestingOperator ? rule.nestingOperator : ' ',
12042
+ id: rule.id,
12043
+ attributes: convertAttributes(rule.attrs),
12044
+ classes: convertClasses(rule.classNames),
12045
+ pseudos: convertPseudos(rule.pseudos)
12046
+ });
12047
+ rule = rule.rule;
12048
+ }
12049
+ return newExp;
12050
+ });
12051
+ }
12052
+ axe.utils.convertSelector = function convertSelector(selector) {
12053
+ var expressions = axe.utils.cssParser.parse(selector);
12054
+ expressions = expressions.selectors ? expressions.selectors : [ expressions ];
12055
+ return convertExpressions(expressions);
12056
+ };
12057
+ axe.utils.matchesExpression = function matchesExpression(vNode, expressions, matchAnyParent) {
12058
+ var exps = [].concat(expressions);
12059
+ var expression = exps.pop();
12060
+ var matches = matchExpression(vNode, expression);
12061
+ while (!matches && matchAnyParent && vNode.parent) {
12062
+ vNode = vNode.parent;
12063
+ matches = matchExpression(vNode, expression);
12064
+ }
12065
+ if (exps.length) {
12066
+ if ([ ' ', '>' ].includes(expression.combinator) === false) {
12067
+ throw new Error('axe.utils.matchesExpression does not support the combinator: ' + expression.combinator);
12068
+ }
12069
+ matches = matches && axe.utils.matchesExpression(vNode.parent, exps, expression.combinator === ' ');
12070
+ }
12071
+ return matches;
12072
+ };
12073
+ axe.utils.matches = function matches(vNode, selector) {
12074
+ var expressions = axe.utils.convertSelector(selector);
12075
+ return expressions.some(function(expression) {
12076
+ return axe.utils.matchesExpression(vNode, expression);
12077
+ });
12078
+ };
12079
+ 'use strict';
11892
12080
  axe._memoizedFns = [];
11893
12081
  axe.utils.memoize = function(fn) {
11894
12082
  var memoized = axe.imports.memoize(fn);
@@ -12482,6 +12670,39 @@
12482
12670
  });
12483
12671
  }
12484
12672
  'use strict';
12673
+ axe.utils.preloadMedia = function preloadMedia(_ref) {
12674
+ var _ref$treeRoot = _ref.treeRoot, treeRoot = _ref$treeRoot === void 0 ? axe._tree[0] : _ref$treeRoot;
12675
+ var mediaVirtualNodes = axe.utils.querySelectorAllFilter(treeRoot, 'video, audio', function(_ref2) {
12676
+ var actualNode = _ref2.actualNode;
12677
+ if (actualNode.hasAttribute('src')) {
12678
+ return !!actualNode.getAttribute('src');
12679
+ }
12680
+ var sourceWithSrc = Array.from(actualNode.getElementsByTagName('source')).filter(function(source) {
12681
+ return !!source.getAttribute('src');
12682
+ });
12683
+ if (sourceWithSrc.length <= 0) {
12684
+ return false;
12685
+ }
12686
+ return true;
12687
+ });
12688
+ return Promise.all(mediaVirtualNodes.map(function(_ref3) {
12689
+ var actualNode = _ref3.actualNode;
12690
+ return isMediaElementReady(actualNode);
12691
+ }));
12692
+ };
12693
+ function isMediaElementReady(elm) {
12694
+ return new Promise(function(resolve) {
12695
+ if (elm.readyState > 0) {
12696
+ resolve(elm);
12697
+ }
12698
+ function onMediaReady() {
12699
+ elm.removeEventListener('loadedmetadata', onMediaReady);
12700
+ resolve(elm);
12701
+ }
12702
+ elm.addEventListener('loadedmetadata', onMediaReady);
12703
+ });
12704
+ }
12705
+ 'use strict';
12485
12706
  function _extends() {
12486
12707
  _extends = Object.assign || function(target) {
12487
12708
  for (var i = 1; i < arguments.length; i++) {
@@ -12555,14 +12776,15 @@
12555
12776
  config.assets = axe.utils.uniqueArray(options.preload.assets.map(function(a) {
12556
12777
  return a.toLowerCase();
12557
12778
  }), []);
12558
- if (options.preload.timeout && typeof options.preload.timeout === 'number' && !Number.isNaN(options.preload.timeout)) {
12779
+ if (options.preload.timeout && typeof options.preload.timeout === 'number' && !isNaN(options.preload.timeout)) {
12559
12780
  config.timeout = options.preload.timeout;
12560
12781
  }
12561
12782
  return config;
12562
12783
  };
12563
12784
  axe.utils.preload = function preload(options) {
12564
12785
  var preloadFunctionsMap = {
12565
- cssom: axe.utils.preloadCssom
12786
+ cssom: axe.utils.preloadCssom,
12787
+ media: axe.utils.preloadMedia
12566
12788
  };
12567
12789
  var shouldPreload = axe.utils.shouldPreload(options);
12568
12790
  if (!shouldPreload) {
@@ -12570,8 +12792,8 @@
12570
12792
  }
12571
12793
  return new Promise(function(resolve, reject) {
12572
12794
  var _axe$utils$getPreload = axe.utils.getPreloadConfig(options), assets = _axe$utils$getPreload.assets, timeout = _axe$utils$getPreload.timeout;
12573
- setTimeout(function() {
12574
- return reject('Preload assets timed out.');
12795
+ var preloadTimeout = setTimeout(function() {
12796
+ return reject(new Error('Preload assets timed out.'));
12575
12797
  }, timeout);
12576
12798
  Promise.all(assets.map(function(asset) {
12577
12799
  return preloadFunctionsMap[asset](options).then(function(results) {
@@ -12581,7 +12803,11 @@
12581
12803
  var preloadAssets = results.reduce(function(out, result) {
12582
12804
  return _extends({}, out, {}, result);
12583
12805
  }, {});
12806
+ clearTimeout(preloadTimeout);
12584
12807
  resolve(preloadAssets);
12808
+ })['catch'](function(err) {
12809
+ clearTimeout(preloadTimeout);
12810
+ reject(err);
12585
12811
  });
12586
12812
  });
12587
12813
  };
@@ -12667,195 +12893,44 @@
12667
12893
  }
12668
12894
  }
12669
12895
  function extender(checksData, shouldBeTrue) {
12670
- 'use strict';
12671
- return function(check) {
12672
- var sourceData = checksData[check.id] || {};
12673
- var messages = sourceData.messages || {};
12674
- var data = Object.assign({}, sourceData);
12675
- delete data.messages;
12676
- if (check.result === undefined) {
12677
- if (_typeof(messages.incomplete) === 'object' && !Array.isArray(check.data)) {
12678
- data.message = getIncompleteReason(check.data, messages);
12679
- }
12680
- if (!data.message) {
12681
- data.message = messages.incomplete;
12682
- }
12683
- } else {
12684
- data.message = check.result === shouldBeTrue ? messages.pass : messages.fail;
12685
- }
12686
- if (typeof data.message !== 'function') {
12687
- data.message = axe.utils.processMessage(data.message, check.data);
12688
- }
12689
- axe.utils.extendMetaData(check, data);
12690
- };
12691
- }
12692
- axe.utils.publishMetaData = function(ruleResult) {
12693
- 'use strict';
12694
- var checksData = axe._audit.data.checks || {};
12695
- var rulesData = axe._audit.data.rules || {};
12696
- var rule = axe.utils.findBy(axe._audit.rules, 'id', ruleResult.id) || {};
12697
- ruleResult.tags = axe.utils.clone(rule.tags || []);
12698
- var shouldBeTrue = extender(checksData, true);
12699
- var shouldBeFalse = extender(checksData, false);
12700
- ruleResult.nodes.forEach(function(detail) {
12701
- detail.any.forEach(shouldBeTrue);
12702
- detail.all.forEach(shouldBeTrue);
12703
- detail.none.forEach(shouldBeFalse);
12704
- });
12705
- axe.utils.extendMetaData(ruleResult, axe.utils.clone(rulesData[ruleResult.id] || {}));
12706
- };
12707
- 'use strict';
12708
- var convertExpressions = function convertExpressions() {};
12709
- var matchExpressions = function matchExpressions() {};
12710
- function matchesTag(vNode, exp) {
12711
- return vNode.props.nodeType === 1 && (exp.tag === '*' || vNode.props.nodeName === exp.tag);
12712
- }
12713
- function matchesClasses(vNode, exp) {
12714
- return !exp.classes || exp.classes.every(function(cl) {
12715
- return vNode.hasClass(cl.value);
12716
- });
12717
- }
12718
- function matchesAttributes(vNode, exp) {
12719
- return !exp.attributes || exp.attributes.every(function(att) {
12720
- var nodeAtt = vNode.attr(att.key);
12721
- return nodeAtt !== null && (!att.value || att.test(nodeAtt));
12722
- });
12723
- }
12724
- function matchesId(vNode, exp) {
12725
- return !exp.id || vNode.props.id === exp.id;
12726
- }
12727
- function matchesPseudos(target, exp) {
12728
- if (!exp.pseudos || exp.pseudos.every(function(pseudo) {
12729
- if (pseudo.name === 'not') {
12730
- return !matchExpressions([ target ], pseudo.expressions, false).length;
12731
- }
12732
- throw new Error('the pseudo selector ' + pseudo.name + ' has not yet been implemented');
12733
- })) {
12734
- return true;
12735
- }
12736
- return false;
12737
- }
12738
- var escapeRegExp = function() {
12739
- var from = /(?=[\-\[\]{}()*+?.\\\^$|,#\s])/g;
12740
- var to = '\\';
12741
- return function(string) {
12742
- return string.replace(from, to);
12743
- };
12744
- }();
12745
- var reUnescape = /\\/g;
12746
- function convertAttributes(atts) {
12747
- if (!atts) {
12748
- return;
12749
- }
12750
- return atts.map(function(att) {
12751
- var attributeKey = att.name.replace(reUnescape, '');
12752
- var attributeValue = (att.value || '').replace(reUnescape, '');
12753
- var test, regexp;
12754
- switch (att.operator) {
12755
- case '^=':
12756
- regexp = new RegExp('^' + escapeRegExp(attributeValue));
12757
- break;
12758
-
12759
- case '$=':
12760
- regexp = new RegExp(escapeRegExp(attributeValue) + '$');
12761
- break;
12762
-
12763
- case '~=':
12764
- regexp = new RegExp('(^|\\s)' + escapeRegExp(attributeValue) + '(\\s|$)');
12765
- break;
12766
-
12767
- case '|=':
12768
- regexp = new RegExp('^' + escapeRegExp(attributeValue) + '(-|$)');
12769
- break;
12770
-
12771
- case '=':
12772
- test = function test(value) {
12773
- return attributeValue === value;
12774
- };
12775
- break;
12776
-
12777
- case '*=':
12778
- test = function test(value) {
12779
- return value && value.includes(attributeValue);
12780
- };
12781
- break;
12782
-
12783
- case '!=':
12784
- test = function test(value) {
12785
- return attributeValue !== value;
12786
- };
12787
- break;
12788
-
12789
- default:
12790
- test = function test(value) {
12791
- return !!value;
12792
- };
12793
- }
12794
- if (attributeValue === '' && /^[*$^]=$/.test(att.operator)) {
12795
- test = function test() {
12796
- return false;
12797
- };
12798
- }
12799
- if (!test) {
12800
- test = function test(value) {
12801
- return value && regexp.test(value);
12802
- };
12803
- }
12804
- return {
12805
- key: attributeKey,
12806
- value: attributeValue,
12807
- test: test
12808
- };
12809
- });
12810
- }
12811
- function convertClasses(classes) {
12812
- if (!classes) {
12813
- return;
12814
- }
12815
- return classes.map(function(className) {
12816
- className = className.replace(reUnescape, '');
12817
- return {
12818
- value: className,
12819
- regexp: new RegExp('(^|\\s)' + escapeRegExp(className) + '(\\s|$)')
12820
- };
12821
- });
12822
- }
12823
- function convertPseudos(pseudos) {
12824
- if (!pseudos) {
12825
- return;
12826
- }
12827
- return pseudos.map(function(p) {
12828
- var expressions;
12829
- if (p.name === 'not') {
12830
- expressions = p.value;
12831
- expressions = expressions.selectors ? expressions.selectors : [ expressions ];
12832
- expressions = convertExpressions(expressions);
12833
- }
12834
- return {
12835
- name: p.name,
12836
- expressions: expressions,
12837
- value: p.value
12838
- };
12839
- });
12840
- }
12841
- convertExpressions = function convertExpressions(expressions) {
12842
- return expressions.map(function(exp) {
12843
- var newExp = [];
12844
- var rule = exp.rule;
12845
- while (rule) {
12846
- newExp.push({
12847
- tag: rule.tagName ? rule.tagName.toLowerCase() : '*',
12848
- combinator: rule.nestingOperator ? rule.nestingOperator : ' ',
12849
- id: rule.id,
12850
- attributes: convertAttributes(rule.attrs),
12851
- classes: convertClasses(rule.classNames),
12852
- pseudos: convertPseudos(rule.pseudos)
12853
- });
12854
- rule = rule.rule;
12896
+ 'use strict';
12897
+ return function(check) {
12898
+ var sourceData = checksData[check.id] || {};
12899
+ var messages = sourceData.messages || {};
12900
+ var data = Object.assign({}, sourceData);
12901
+ delete data.messages;
12902
+ if (check.result === undefined) {
12903
+ if (_typeof(messages.incomplete) === 'object' && !Array.isArray(check.data)) {
12904
+ data.message = getIncompleteReason(check.data, messages);
12905
+ }
12906
+ if (!data.message) {
12907
+ data.message = messages.incomplete;
12908
+ }
12909
+ } else {
12910
+ data.message = check.result === shouldBeTrue ? messages.pass : messages.fail;
12855
12911
  }
12856
- return newExp;
12912
+ if (typeof data.message !== 'function') {
12913
+ data.message = axe.utils.processMessage(data.message, check.data);
12914
+ }
12915
+ axe.utils.extendMetaData(check, data);
12916
+ };
12917
+ }
12918
+ axe.utils.publishMetaData = function(ruleResult) {
12919
+ 'use strict';
12920
+ var checksData = axe._audit.data.checks || {};
12921
+ var rulesData = axe._audit.data.rules || {};
12922
+ var rule = axe.utils.findBy(axe._audit.rules, 'id', ruleResult.id) || {};
12923
+ ruleResult.tags = axe.utils.clone(rule.tags || []);
12924
+ var shouldBeTrue = extender(checksData, true);
12925
+ var shouldBeFalse = extender(checksData, false);
12926
+ ruleResult.nodes.forEach(function(detail) {
12927
+ detail.any.forEach(shouldBeTrue);
12928
+ detail.all.forEach(shouldBeTrue);
12929
+ detail.none.forEach(shouldBeFalse);
12857
12930
  });
12931
+ axe.utils.extendMetaData(ruleResult, axe.utils.clone(rulesData[ruleResult.id] || {}));
12858
12932
  };
12933
+ 'use strict';
12859
12934
  function createLocalVariables(vNodes, anyLevel, thisLevel, parentShadowId) {
12860
12935
  var retVal = {
12861
12936
  vNodes: vNodes.slice(),
@@ -12866,10 +12941,7 @@
12866
12941
  retVal.vNodes.reverse();
12867
12942
  return retVal;
12868
12943
  }
12869
- function matchesSelector(vNode, exp) {
12870
- return matchesTag(vNode, exp[0]) && matchesClasses(vNode, exp[0]) && matchesAttributes(vNode, exp[0]) && matchesId(vNode, exp[0]) && matchesPseudos(vNode, exp[0]);
12871
- }
12872
- matchExpressions = function matchExpressions(domTree, expressions, recurse, filter) {
12944
+ function matchExpressions(domTree, expressions, filter) {
12873
12945
  var stack = [];
12874
12946
  var vNodes = Array.isArray(domTree) ? domTree : [ domTree ];
12875
12947
  var currentLevel = createLocalVariables(vNodes, expressions, [], domTree[0].shadowId);
@@ -12882,7 +12954,7 @@
12882
12954
  var added = false;
12883
12955
  for (var i = 0; i < combined.length; i++) {
12884
12956
  var exp = combined[i];
12885
- if ((!exp[0].id || vNode.shadowId === currentLevel.parentShadowId) && matchesSelector(vNode, exp)) {
12957
+ if ((!exp[0].id || vNode.shadowId === currentLevel.parentShadowId) && axe.utils.matchesExpression(vNode, exp[0])) {
12886
12958
  if (exp.length === 1) {
12887
12959
  if (!added && (!filter || filter(vNode))) {
12888
12960
  result.push(vNode);
@@ -12904,7 +12976,7 @@
12904
12976
  childAny.push(exp);
12905
12977
  }
12906
12978
  }
12907
- if (vNode.children && vNode.children.length && recurse) {
12979
+ if (vNode.children && vNode.children.length) {
12908
12980
  stack.push(currentLevel);
12909
12981
  currentLevel = createLocalVariables(vNode.children, childAny, childOnly, vNode.shadowId);
12910
12982
  }
@@ -12913,16 +12985,14 @@
12913
12985
  }
12914
12986
  }
12915
12987
  return result;
12916
- };
12988
+ }
12917
12989
  axe.utils.querySelectorAll = function(domTree, selector) {
12918
12990
  return axe.utils.querySelectorAllFilter(domTree, selector);
12919
12991
  };
12920
12992
  axe.utils.querySelectorAllFilter = function(domTree, selector, filter) {
12921
12993
  domTree = Array.isArray(domTree) ? domTree : [ domTree ];
12922
- var expressions = axe.utils.cssParser.parse(selector);
12923
- expressions = expressions.selectors ? expressions.selectors : [ expressions ];
12924
- expressions = convertExpressions(expressions);
12925
- return matchExpressions(domTree, expressions, true, filter);
12994
+ var expressions = axe.utils.convertSelector(selector);
12995
+ return matchExpressions(domTree, expressions, filter);
12926
12996
  };
12927
12997
  'use strict';
12928
12998
  function _typeof(obj) {
@@ -13493,6 +13563,20 @@
13493
13563
  return langs;
13494
13564
  };
13495
13565
  'use strict';
13566
+ function _extends() {
13567
+ _extends = Object.assign || function(target) {
13568
+ for (var i = 1; i < arguments.length; i++) {
13569
+ var source = arguments[i];
13570
+ for (var key in source) {
13571
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
13572
+ target[key] = source[key];
13573
+ }
13574
+ }
13575
+ }
13576
+ return target;
13577
+ };
13578
+ return _extends.apply(this, arguments);
13579
+ }
13496
13580
  function _toConsumableArray(arr) {
13497
13581
  return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
13498
13582
  }
@@ -13512,20 +13596,6 @@
13512
13596
  return arr2;
13513
13597
  }
13514
13598
  }
13515
- function _extends() {
13516
- _extends = Object.assign || function(target) {
13517
- for (var i = 1; i < arguments.length; i++) {
13518
- var source = arguments[i];
13519
- for (var key in source) {
13520
- if (Object.prototype.hasOwnProperty.call(source, key)) {
13521
- target[key] = source[key];
13522
- }
13523
- }
13524
- }
13525
- return target;
13526
- };
13527
- return _extends.apply(this, arguments);
13528
- }
13529
13599
  function _slicedToArray(arr, i) {
13530
13600
  return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
13531
13601
  }
@@ -13753,6 +13823,10 @@
13753
13823
  description: 'Ensure that HTML elements with both valid lang and xml:lang attributes agree on the base language of the page',
13754
13824
  help: 'HTML elements with lang and xml:lang must have the same base language'
13755
13825
  },
13826
+ 'identical-links-same-purpose': {
13827
+ description: 'Ensure that links with the same accessible name serve a similar purpose',
13828
+ help: 'Links with the same name have a similar purpose'
13829
+ },
13756
13830
  'image-alt': {
13757
13831
  description: 'Ensures <img> elements have alternate text or a role of none or presentation',
13758
13832
  help: 'Images must have alternate text'
@@ -13805,8 +13879,12 @@
13805
13879
  description: 'Ensures the document has at most one contentinfo landmark',
13806
13880
  help: 'Document must not have more than one contentinfo landmark'
13807
13881
  },
13882
+ 'landmark-no-duplicate-main': {
13883
+ description: 'Ensures the document has at most one main landmark',
13884
+ help: 'Document must not have more than one main landmark'
13885
+ },
13808
13886
  'landmark-one-main': {
13809
- description: 'Ensures the document has only one main landmark and each iframe in the page has at most one main landmark',
13887
+ description: 'Ensures the document has a main landmark',
13810
13888
  help: 'Document must have one main landmark'
13811
13889
  },
13812
13890
  'landmark-unique': {
@@ -13849,6 +13927,10 @@
13849
13927
  description: 'Ensures <meta name="viewport"> does not disable text scaling and zooming',
13850
13928
  help: 'Zooming and scaling must not be disabled'
13851
13929
  },
13930
+ 'no-autoplay-audio': {
13931
+ description: 'Ensures <video> or <audio> elements do not autoplay audio for more than 3 seconds without a control mechanism to stop or mute the audio',
13932
+ help: '<video> or <audio> elements do not autoplay audio'
13933
+ },
13852
13934
  'object-alt': {
13853
13935
  description: 'Ensures <object> elements have alternate text',
13854
13936
  help: '<object> elements must have alternate text'
@@ -13889,6 +13971,10 @@
13889
13971
  description: 'Ensure all skip links have a focusable target',
13890
13972
  help: 'The skip-link target should exist and be focusable'
13891
13973
  },
13974
+ 'svg-img-alt': {
13975
+ description: 'Ensures svg elements with an img, graphics-document or graphics-symbol role have an accessible text',
13976
+ help: 'svg elements with an img role have an alternative text'
13977
+ },
13892
13978
  tabindex: {
13893
13979
  description: 'Ensures tabindex attribute values are not greater than 0',
13894
13980
  help: 'Elements should not have tabindex greater than zero'
@@ -14007,6 +14093,13 @@
14007
14093
  fail: 'aria-hidden=true should not be present on the document body'
14008
14094
  }
14009
14095
  },
14096
+ 'focusable-modal-open': {
14097
+ impact: 'serious',
14098
+ messages: {
14099
+ pass: 'No focusable elements while a modal is open',
14100
+ incomplete: 'Check that focusable elements are not tabbable in the current state'
14101
+ }
14102
+ },
14010
14103
  'focusable-disabled': {
14011
14104
  impact: 'serious',
14012
14105
  messages: {
@@ -14070,18 +14163,31 @@
14070
14163
  fail: 'Give the element a role that supports aria-roledescription'
14071
14164
  }
14072
14165
  },
14166
+ fallbackrole: {
14167
+ impact: 'serious',
14168
+ messages: {
14169
+ pass: 'Only one role value used',
14170
+ fail: 'Use only one role value, since fallback roles are not supported in older browsers'
14171
+ }
14172
+ },
14073
14173
  invalidrole: {
14074
14174
  impact: 'critical',
14075
14175
  messages: {
14076
14176
  pass: 'ARIA role is valid',
14077
- fail: 'Role must be one of the valid ARIA roles'
14177
+ fail: {
14178
+ singular: 'Role must be one of the valid ARIA roles: ${data.values}',
14179
+ plural: 'Roles must be one of the valid ARIA roles: ${data.values}'
14180
+ }
14078
14181
  }
14079
14182
  },
14080
14183
  abstractrole: {
14081
14184
  impact: 'serious',
14082
14185
  messages: {
14083
14186
  pass: 'Abstract roles are not used',
14084
- fail: 'Abstract roles cannot be directly used'
14187
+ fail: {
14188
+ singular: 'Abstract role cannot be directly used: ${data.values}',
14189
+ plural: 'Abstract roles cannot be directly used: ${data.values}'
14190
+ }
14085
14191
  }
14086
14192
  },
14087
14193
  unsupportedrole: {
@@ -14107,8 +14213,8 @@
14107
14213
  plural: 'Invalid ARIA attribute values: ${data.values}'
14108
14214
  },
14109
14215
  incomplete: {
14110
- singular: 'ARIA attribute element ID does not exist on the page: ${data.values}',
14111
- plural: 'ARIA attributes element ID does not exist on the page: ${data.values}'
14216
+ noId: 'ARIA attribute element ID does not exist on the page: ${data.needsReview}',
14217
+ ariaCurrent: 'ARIA attribute value is invalid and will be treated as "aria-current=true": ${data.needsReview}'
14112
14218
  }
14113
14219
  }
14114
14220
  },
@@ -14253,7 +14359,8 @@
14253
14359
  elmPartiallyObscuring: 'Element\'s background color could not be determined because it partially overlaps other elements',
14254
14360
  outsideViewport: 'Element\'s background color could not be determined because it\'s outside the viewport',
14255
14361
  equalRatio: 'Element has a 1:1 contrast ratio with the background',
14256
- shortTextContent: 'Element content is too short to determine if it is actual text content'
14362
+ shortTextContent: 'Element content is too short to determine if it is actual text content',
14363
+ nonBmp: 'Element content contains only non-text characters'
14257
14364
  }
14258
14365
  }
14259
14366
  },
@@ -14386,6 +14493,13 @@
14386
14493
  fail: 'Lang and xml:lang attributes do not have the same base language'
14387
14494
  }
14388
14495
  },
14496
+ 'identical-links-same-purpose': {
14497
+ impact: 'minor',
14498
+ messages: {
14499
+ pass: 'There are no other links with the same name, that go to a different URL',
14500
+ incomplete: 'Check that links have the same purpose, or are intentionally ambiguous.'
14501
+ }
14502
+ },
14389
14503
  'has-alt': {
14390
14504
  impact: 'critical',
14391
14505
  messages: {
@@ -14487,18 +14601,18 @@
14487
14601
  fail: 'Document has more than one contentinfo landmark'
14488
14602
  }
14489
14603
  },
14490
- 'page-has-main': {
14604
+ 'page-no-duplicate-main': {
14491
14605
  impact: 'moderate',
14492
14606
  messages: {
14493
- pass: 'Document has at least one main landmark',
14494
- fail: 'Document does not have a main landmark'
14607
+ pass: 'Document does not have more than one main landmark',
14608
+ fail: 'Document has more than one main landmark'
14495
14609
  }
14496
14610
  },
14497
- 'page-no-duplicate-main': {
14611
+ 'page-has-main': {
14498
14612
  impact: 'moderate',
14499
14613
  messages: {
14500
- pass: 'Document does not have more than one main landmark',
14501
- fail: 'Document has more than one main landmark'
14614
+ pass: 'Document has at least one main landmark',
14615
+ fail: 'Document does not have a main landmark'
14502
14616
  }
14503
14617
  },
14504
14618
  'landmark-is-unique': {
@@ -14555,7 +14669,10 @@
14555
14669
  impact: 'serious',
14556
14670
  messages: {
14557
14671
  pass: 'List element only has direct children that are allowed inside <li> elements',
14558
- fail: 'List element has direct children that are not allowed inside <li> elements'
14672
+ fail: {
14673
+ default: 'List element has direct children that are not allowed inside <li> elements',
14674
+ roleNotValid: 'List element has direct children with a role that is not allowed: ${data.roles}'
14675
+ }
14559
14676
  }
14560
14677
  },
14561
14678
  listitem: {
@@ -14589,6 +14706,14 @@
14589
14706
  fail: '${data} on <meta> tag disables zooming on mobile devices'
14590
14707
  }
14591
14708
  },
14709
+ 'no-autoplay-audio': {
14710
+ impact: 'moderate',
14711
+ messages: {
14712
+ pass: '<video> or <audio> does not output audio for more than allowed duration or has controls mechanism',
14713
+ fail: '<video> or <audio> outputs audio for more than allowed duration and does not have a controls mechanism',
14714
+ incomplete: 'Check that the <video> or <audio> does not output audio for more than allowed duration or provides a controls mechanism'
14715
+ }
14716
+ },
14592
14717
  'p-as-heading': {
14593
14718
  impact: 'serious',
14594
14719
  messages: {
@@ -14653,6 +14778,13 @@
14653
14778
  fail: 'No skip link target'
14654
14779
  }
14655
14780
  },
14781
+ 'svg-non-empty-title': {
14782
+ impact: 'serious',
14783
+ messages: {
14784
+ pass: 'element has a child that is a title',
14785
+ fail: 'element has no child that is a title'
14786
+ }
14787
+ },
14656
14788
  tabindex: {
14657
14789
  impact: 'serious',
14658
14790
  messages: {
@@ -14829,7 +14961,7 @@
14829
14961
  },
14830
14962
  excludeHidden: false,
14831
14963
  tags: [ 'cat.name-role-value', 'wcag2a', 'wcag412', 'wcag131' ],
14832
- all: [ 'focusable-disabled', 'focusable-not-tabbable' ],
14964
+ all: [ 'focusable-modal-open', 'focusable-disabled', 'focusable-not-tabbable' ],
14833
14965
  any: [],
14834
14966
  none: []
14835
14967
  }, {
@@ -14906,7 +15038,7 @@
14906
15038
  tags: [ 'cat.aria', 'wcag2a', 'wcag412' ],
14907
15039
  all: [],
14908
15040
  any: [],
14909
- none: [ 'invalidrole', 'abstractrole', 'unsupportedrole' ]
15041
+ none: [ 'fallbackrole', 'invalidrole', 'abstractrole', 'unsupportedrole' ]
14910
15042
  }, {
14911
15043
  id: 'aria-toggle-field-name',
14912
15044
  selector: '[role="checkbox"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="radio"], [role="switch"]',
@@ -15122,7 +15254,7 @@
15122
15254
  var visibleText = axe.commons.text.visibleVirtual(virtualNode, false, true);
15123
15255
  if (visibleText === '' || axe.commons.text.removeUnicode(visibleText, {
15124
15256
  emoji: true,
15125
- nonBmp: true,
15257
+ nonBmp: false,
15126
15258
  punctuations: true
15127
15259
  }) === '') {
15128
15260
  return false;
@@ -15148,12 +15280,16 @@
15148
15280
  return false;
15149
15281
  },
15150
15282
  excludeHidden: false,
15151
- options: {
15152
- noScroll: false
15153
- },
15154
15283
  tags: [ 'cat.color', 'wcag2aa', 'wcag143' ],
15155
15284
  all: [],
15156
- any: [ 'color-contrast' ],
15285
+ any: [ {
15286
+ options: {
15287
+ noScroll: false,
15288
+ ignoreUnicode: true,
15289
+ ignoreLength: false
15290
+ },
15291
+ id: 'color-contrast'
15292
+ } ],
15157
15293
  none: []
15158
15294
  }, {
15159
15295
  id: 'css-orientation-lock',
@@ -15375,6 +15511,26 @@
15375
15511
  all: [ 'xml-lang-mismatch' ],
15376
15512
  any: [],
15377
15513
  none: []
15514
+ }, {
15515
+ id: 'identical-links-same-purpose',
15516
+ selector: 'a[href], area[href], [role="link"]',
15517
+ excludeHidden: false,
15518
+ matches: function matches(node, virtualNode, context) {
15519
+ var _axe$commons4 = axe.commons, aria = _axe$commons4.aria, text = _axe$commons4.text;
15520
+ var hasAccName = !!text.accessibleTextVirtual(virtualNode);
15521
+ if (!hasAccName) {
15522
+ return false;
15523
+ }
15524
+ var role = aria.getRole(node);
15525
+ if (role && role !== 'link') {
15526
+ return false;
15527
+ }
15528
+ return true;
15529
+ },
15530
+ tags: [ 'wcag2aaa', 'wcag249', 'best-practice' ],
15531
+ all: [ 'identical-links-same-purpose' ],
15532
+ any: [],
15533
+ none: []
15378
15534
  }, {
15379
15535
  id: 'image-alt',
15380
15536
  selector: 'img',
@@ -15406,7 +15562,7 @@
15406
15562
  }, {
15407
15563
  id: 'label-content-name-mismatch',
15408
15564
  matches: function matches(node, virtualNode, context) {
15409
- var _axe$commons4 = axe.commons, aria = _axe$commons4.aria, text = _axe$commons4.text;
15565
+ var _axe$commons5 = axe.commons, aria = _axe$commons5.aria, text = _axe$commons5.text;
15410
15566
  var role = aria.getRole(node);
15411
15567
  if (!role) {
15412
15568
  return false;
@@ -15503,7 +15659,7 @@
15503
15659
  none: []
15504
15660
  }, {
15505
15661
  id: 'landmark-no-duplicate-banner',
15506
- selector: 'html',
15662
+ selector: 'header:not([role]), [role=banner]',
15507
15663
  tags: [ 'cat.semantics', 'best-practice' ],
15508
15664
  all: [],
15509
15665
  any: [ {
@@ -15516,7 +15672,7 @@
15516
15672
  none: []
15517
15673
  }, {
15518
15674
  id: 'landmark-no-duplicate-contentinfo',
15519
- selector: 'html',
15675
+ selector: 'footer:not([role]), [role=contentinfo]',
15520
15676
  tags: [ 'cat.semantics', 'best-practice' ],
15521
15677
  all: [],
15522
15678
  any: [ {
@@ -15527,6 +15683,18 @@
15527
15683
  id: 'page-no-duplicate-contentinfo'
15528
15684
  } ],
15529
15685
  none: []
15686
+ }, {
15687
+ id: 'landmark-no-duplicate-main',
15688
+ selector: 'main:not([role]), [role=main]',
15689
+ tags: [ 'cat.semantics', 'best-practice' ],
15690
+ all: [],
15691
+ any: [ {
15692
+ options: {
15693
+ selector: 'main:not([role]), [role=\'main\']'
15694
+ },
15695
+ id: 'page-no-duplicate-main'
15696
+ } ],
15697
+ none: []
15530
15698
  }, {
15531
15699
  id: 'landmark-one-main',
15532
15700
  selector: 'html',
@@ -15536,11 +15704,6 @@
15536
15704
  selector: 'main:not([role]), [role=\'main\']'
15537
15705
  },
15538
15706
  id: 'page-has-main'
15539
- }, {
15540
- options: {
15541
- selector: 'main:not([role]), [role=\'main\']'
15542
- },
15543
- id: 'page-no-duplicate-main'
15544
15707
  } ],
15545
15708
  any: [],
15546
15709
  none: []
@@ -15670,7 +15833,7 @@
15670
15833
  id: 'meta-viewport',
15671
15834
  selector: 'meta[name="viewport"]',
15672
15835
  excludeHidden: false,
15673
- tags: [ 'cat.sensory-and-visual-cues', 'wcag2aa', 'wcag144' ],
15836
+ tags: [ 'cat.sensory-and-visual-cues', 'best-practice' ],
15674
15837
  all: [],
15675
15838
  any: [ {
15676
15839
  options: {
@@ -15679,6 +15842,29 @@
15679
15842
  id: 'meta-viewport'
15680
15843
  } ],
15681
15844
  none: []
15845
+ }, {
15846
+ id: 'no-autoplay-audio',
15847
+ excludeHidden: false,
15848
+ selector: 'audio[autoplay], video[autoplay]',
15849
+ matches: function matches(node, virtualNode, context) {
15850
+ if (!node.currentSrc) {
15851
+ return false;
15852
+ }
15853
+ if (node.hasAttribute('paused') || node.hasAttribute('muted')) {
15854
+ return false;
15855
+ }
15856
+ return true;
15857
+ },
15858
+ tags: [ 'wcag2a', 'wcag142', 'experimental' ],
15859
+ preload: true,
15860
+ all: [ {
15861
+ options: {
15862
+ allowedDuration: 3
15863
+ },
15864
+ id: 'no-autoplay-audio'
15865
+ } ],
15866
+ any: [],
15867
+ none: []
15682
15868
  }, {
15683
15869
  id: 'object-alt',
15684
15870
  selector: 'object',
@@ -15743,15 +15929,17 @@
15743
15929
  none: []
15744
15930
  }, {
15745
15931
  id: 'region',
15746
- selector: 'html',
15747
- pageLevel: true,
15932
+ selector: 'body *',
15748
15933
  tags: [ 'cat.keyboard', 'best-practice' ],
15749
15934
  all: [],
15750
15935
  any: [ 'region' ],
15751
15936
  none: []
15752
15937
  }, {
15753
15938
  id: 'role-img-alt',
15754
- selector: '[role=\'img\']:not(svg):not(img):not(area):not(input):not(object)',
15939
+ selector: '[role=\'img\']:not(img):not(area):not(input):not(object)',
15940
+ matches: function matches(node, virtualNode, context) {
15941
+ return node.namespaceURI === 'http://www.w3.org/1999/xhtml';
15942
+ },
15755
15943
  tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ],
15756
15944
  all: [],
15757
15945
  any: [ 'aria-label', 'aria-labelledby', 'non-empty-title' ],
@@ -15801,6 +15989,16 @@
15801
15989
  all: [],
15802
15990
  any: [ 'skip-link' ],
15803
15991
  none: []
15992
+ }, {
15993
+ id: 'svg-img-alt',
15994
+ selector: '[role="img"], [role="graphics-symbol"], svg[role="graphics-document"]',
15995
+ matches: function matches(node, virtualNode, context) {
15996
+ return node.namespaceURI === 'http://www.w3.org/2000/svg';
15997
+ },
15998
+ tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ],
15999
+ all: [],
16000
+ any: [ 'svg-non-empty-title', 'aria-label', 'aria-labelledby', 'non-empty-title' ],
16001
+ none: []
15804
16002
  }, {
15805
16003
  id: 'tabindex',
15806
16004
  selector: '[tabindex]',
@@ -15887,7 +16085,14 @@
15887
16085
  checks: [ {
15888
16086
  id: 'abstractrole',
15889
16087
  evaluate: function evaluate(node, options, virtualNode, context) {
15890
- return axe.commons.aria.getRoleType(node.getAttribute('role')) === 'abstract';
16088
+ var abstractRoles = axe.utils.tokenList(virtualNode.attr('role')).filter(function(role) {
16089
+ return axe.commons.aria.getRoleType(role) === 'abstract';
16090
+ });
16091
+ if (abstractRoles.length > 0) {
16092
+ this.data(abstractRoles);
16093
+ return true;
16094
+ }
16095
+ return false;
15891
16096
  }
15892
16097
  }, {
15893
16098
  id: 'aria-allowed-attr',
@@ -15967,7 +16172,7 @@
15967
16172
  }, {
15968
16173
  id: 'aria-errormessage',
15969
16174
  evaluate: function evaluate(node, options, virtualNode, context) {
15970
- var _axe$commons5 = axe.commons, aria = _axe$commons5.aria, dom = _axe$commons5.dom;
16175
+ var _axe$commons6 = axe.commons, aria = _axe$commons6.aria, dom = _axe$commons6.dom;
15971
16176
  options = Array.isArray(options) ? options : [];
15972
16177
  var attr = node.getAttribute('aria-errormessage');
15973
16178
  var hasAttr = node.hasAttribute('aria-errormessage');
@@ -15989,6 +16194,11 @@
15989
16194
  }
15990
16195
  return true;
15991
16196
  }
16197
+ }, {
16198
+ id: 'fallbackrole',
16199
+ evaluate: function evaluate(node, options, virtualNode, context) {
16200
+ return axe.utils.tokenList(virtualNode.attr('role')).length > 1;
16201
+ }
15992
16202
  }, {
15993
16203
  id: 'has-widget-role',
15994
16204
  evaluate: function evaluate(node, options, virtualNode, context) {
@@ -16014,14 +16224,21 @@
16014
16224
  }, {
16015
16225
  id: 'invalidrole',
16016
16226
  evaluate: function evaluate(node, options, virtualNode, context) {
16017
- return !axe.commons.aria.isValidRole(node.getAttribute('role'), {
16018
- allowAbstract: true
16227
+ var invalidRoles = axe.utils.tokenList(virtualNode.attr('role')).filter(function(role) {
16228
+ return !axe.commons.aria.isValidRole(role, {
16229
+ allowAbstract: true
16230
+ });
16019
16231
  });
16232
+ if (invalidRoles.length > 0) {
16233
+ this.data(invalidRoles);
16234
+ return true;
16235
+ }
16236
+ return false;
16020
16237
  }
16021
16238
  }, {
16022
16239
  id: 'no-implicit-explicit-label',
16023
16240
  evaluate: function evaluate(node, options, virtualNode, context) {
16024
- var _axe$commons6 = axe.commons, aria = _axe$commons6.aria, text = _axe$commons6.text;
16241
+ var _axe$commons7 = axe.commons, aria = _axe$commons7.aria, text = _axe$commons7.text;
16025
16242
  var role = aria.getRole(node, {
16026
16243
  noImplicit: true
16027
16244
  });
@@ -16084,7 +16301,8 @@
16084
16301
  if (node === null) {
16085
16302
  return false;
16086
16303
  }
16087
- var implicit = implicitNodes(role), selector = [ '[role="' + role + '"]' ];
16304
+ var implicit = implicitNodes(role);
16305
+ var selector = [ '[role="' + role + '"]' ];
16088
16306
  if (implicit) {
16089
16307
  selector = selector.concat(implicit.map(function(implicitSelector) {
16090
16308
  return implicitSelector + ':not([role])';
@@ -16094,21 +16312,21 @@
16094
16312
  return ariaOwned ? matchesSelector(node, selector) || !!axe.utils.querySelectorAll(virtualTree, selector)[0] : !!axe.utils.querySelectorAll(virtualTree, selector)[0];
16095
16313
  }
16096
16314
  function ariaOwns(nodes, role) {
16097
- var index, length;
16098
- for (index = 0, length = nodes.length; index < length; index++) {
16099
- if (nodes[index] === null) {
16315
+ for (var index = 0; index < nodes.length; index++) {
16316
+ var _node = nodes[index];
16317
+ if (_node === null) {
16100
16318
  continue;
16101
16319
  }
16102
- var virtualTree = axe.utils.getNodeFromTree(nodes[index]);
16103
- if (owns(nodes[index], virtualTree, role, true)) {
16320
+ var virtualTree = axe.utils.getNodeFromTree(_node);
16321
+ if (owns(_node, virtualTree, role, true)) {
16104
16322
  return true;
16105
16323
  }
16106
16324
  }
16107
16325
  return false;
16108
16326
  }
16109
16327
  function missingRequiredChildren(node, childRoles, all, role) {
16110
- var index, length = childRoles.length, missing = [], ownedElements = idrefs(node, 'aria-owns');
16111
- for (index = 0; index < length; index++) {
16328
+ var missing = [], ownedElements = idrefs(node, 'aria-owns');
16329
+ for (var index = 0; index < childRoles.length; index++) {
16112
16330
  var childRole = childRoles[index];
16113
16331
  if (owns(node, virtualNode, childRole) || ariaOwns(ownedElements, childRole)) {
16114
16332
  if (!all) {
@@ -16126,10 +16344,19 @@
16126
16344
  if (textboxIndex >= 0 && node.nodeName.toUpperCase() === 'INPUT' && textTypeInputs.includes(node.type) || owns(node, virtualNode, 'searchbox') || ariaOwns(ownedElements, 'searchbox')) {
16127
16345
  missing.splice(textboxIndex, 1);
16128
16346
  }
16129
- var listboxIndex = missing.indexOf('listbox');
16130
- var expanded = node.getAttribute('aria-expanded');
16131
- if (listboxIndex >= 0 && (!expanded || expanded === 'false')) {
16132
- missing.splice(listboxIndex, 1);
16347
+ var expandedChildRoles = [ 'listbox', 'tree', 'grid', 'dialog' ];
16348
+ var expandedValue = node.getAttribute('aria-expanded');
16349
+ var expanded = expandedValue && expandedValue !== 'false';
16350
+ var popupRole = (node.getAttribute('aria-haspopup') || 'listbox').toLowerCase();
16351
+ for (var _index = 0; _index < expandedChildRoles.length; _index++) {
16352
+ var expandedChildRole = expandedChildRoles[_index];
16353
+ if (expanded && expandedChildRole === popupRole) {
16354
+ continue;
16355
+ }
16356
+ var missingIndex = missing.indexOf(expandedChildRole);
16357
+ if (missingIndex >= 0) {
16358
+ missing.splice(missingIndex, 1);
16359
+ }
16133
16360
  }
16134
16361
  }
16135
16362
  if (missing.length) {
@@ -16154,7 +16381,7 @@
16154
16381
  var all = false;
16155
16382
  var childRoles = required.one;
16156
16383
  if (!childRoles) {
16157
- var all = true;
16384
+ all = true;
16158
16385
  childRoles = required.all;
16159
16386
  }
16160
16387
  var missing = missingRequiredChildren(node, childRoles, all, role);
@@ -16272,7 +16499,8 @@
16272
16499
  id: 'aria-valid-attr-value',
16273
16500
  evaluate: function evaluate(node, options, virtualNode, context) {
16274
16501
  options = Array.isArray(options) ? options : [];
16275
- var needsReview = [];
16502
+ var needsReview = '';
16503
+ var messageKey = '';
16276
16504
  var invalid = [];
16277
16505
  var aria = /^aria-/;
16278
16506
  var attrs = axe.utils.getNodeAttributes(node);
@@ -16281,12 +16509,20 @@
16281
16509
  'aria-controls': function ariaControls() {
16282
16510
  return node.getAttribute('aria-expanded') !== 'false' && node.getAttribute('aria-selected') !== 'false';
16283
16511
  },
16512
+ 'aria-current': function ariaCurrent() {
16513
+ if (!axe.commons.aria.validateAttrValue(node, 'aria-current')) {
16514
+ needsReview = 'aria-current="'.concat(node.getAttribute('aria-current'), '"');
16515
+ messageKey = 'ariaCurrent';
16516
+ }
16517
+ return;
16518
+ },
16284
16519
  'aria-owns': function ariaOwns() {
16285
16520
  return node.getAttribute('aria-expanded') !== 'false';
16286
16521
  },
16287
16522
  'aria-describedby': function ariaDescribedby() {
16288
16523
  if (!axe.commons.aria.validateAttrValue(node, 'aria-describedby')) {
16289
- needsReview.push('aria-describedby="'.concat(node.getAttribute('aria-describedby'), '"'));
16524
+ needsReview = 'aria-describedby="'.concat(node.getAttribute('aria-describedby'), '"');
16525
+ messageKey = 'noId';
16290
16526
  }
16291
16527
  return;
16292
16528
  }
@@ -16298,8 +16534,11 @@
16298
16534
  invalid.push(''.concat(attrName, '="').concat(attr.nodeValue, '"'));
16299
16535
  }
16300
16536
  }
16301
- if (needsReview.length) {
16302
- this.data(needsReview);
16537
+ if (needsReview) {
16538
+ this.data({
16539
+ messageKey: messageKey,
16540
+ needsReview: needsReview
16541
+ });
16303
16542
  return undefined;
16304
16543
  }
16305
16544
  if (invalid.length) {
@@ -16368,18 +16607,31 @@
16368
16607
  }, {
16369
16608
  id: 'color-contrast',
16370
16609
  evaluate: function evaluate(node, options, virtualNode, context) {
16371
- var _axe$commons7 = axe.commons, dom = _axe$commons7.dom, color = _axe$commons7.color, text = _axe$commons7.text;
16610
+ var _axe$commons8 = axe.commons, dom = _axe$commons8.dom, color = _axe$commons8.color, text = _axe$commons8.text;
16372
16611
  if (!dom.isVisible(node, false)) {
16373
16612
  return true;
16374
16613
  }
16614
+ var visibleText = text.visibleVirtual(virtualNode, false, true);
16615
+ var ignoreUnicode = !!(options || {}).ignoreUnicode;
16616
+ var textContainsOnlyUnicode = text.hasUnicode(visibleText, {
16617
+ nonBmp: true
16618
+ }) && text.sanitize(text.removeUnicode(visibleText, {
16619
+ nonBmp: true
16620
+ })) === '';
16621
+ if (textContainsOnlyUnicode && ignoreUnicode) {
16622
+ this.data({
16623
+ messageKey: 'nonBmp'
16624
+ });
16625
+ return undefined;
16626
+ }
16375
16627
  var noScroll = !!(options || {}).noScroll;
16376
16628
  var bgNodes = [];
16377
16629
  var bgColor = color.getBackgroundColor(node, bgNodes, noScroll);
16378
16630
  var fgColor = color.getForegroundColor(node, noScroll, bgColor);
16379
16631
  var nodeStyle = window.getComputedStyle(node);
16380
16632
  var fontSize = parseFloat(nodeStyle.getPropertyValue('font-size'));
16381
- var fontWeight = nodeStyle.getPropertyValue('font-weight');
16382
- var bold = [ 'bold', 'bolder', '600', '700', '800', '900' ].indexOf(fontWeight) !== -1;
16633
+ var fontWeight = parseFloat(nodeStyle.getPropertyValue('font-weight'));
16634
+ var bold = !isNaN(fontWeight) && fontWeight >= 700;
16383
16635
  var cr = color.hasValidContrastRatio(bgColor, fgColor, fontSize, bold);
16384
16636
  var truncatedResult = Math.floor(cr.contrastRatio * 100) / 100;
16385
16637
  var missing;
@@ -16387,10 +16639,11 @@
16387
16639
  missing = color.incompleteData.get('bgColor');
16388
16640
  }
16389
16641
  var equalRatio = truncatedResult === 1;
16390
- var shortTextContent = text.visibleVirtual(virtualNode, false, true).length === 1;
16642
+ var shortTextContent = visibleText.length === 1;
16643
+ var ignoreLength = !!(options || {}).ignoreLength;
16391
16644
  if (equalRatio) {
16392
16645
  missing = color.incompleteData.set('bgColor', 'equalRatio');
16393
- } else if (shortTextContent) {
16646
+ } else if (shortTextContent && !ignoreLength) {
16394
16647
  missing = 'shortTextContent';
16395
16648
  }
16396
16649
  var data = {
@@ -16403,7 +16656,7 @@
16403
16656
  expectedContrastRatio: cr.expectedContrastRatio + ':1'
16404
16657
  };
16405
16658
  this.data(data);
16406
- if (fgColor === null || bgColor === null || equalRatio || shortTextContent && !cr.isValid) {
16659
+ if (fgColor === null || bgColor === null || equalRatio || shortTextContent && !ignoreLength && !cr.isValid) {
16407
16660
  missing = null;
16408
16661
  color.incompleteData.clear();
16409
16662
  this.relatedNodes(bgNodes);
@@ -16413,11 +16666,16 @@
16413
16666
  this.relatedNodes(bgNodes);
16414
16667
  }
16415
16668
  return cr.isValid;
16669
+ },
16670
+ options: {
16671
+ noScroll: false,
16672
+ ignoreUnicode: true,
16673
+ ignoreLength: false
16416
16674
  }
16417
16675
  }, {
16418
16676
  id: 'link-in-text-block',
16419
16677
  evaluate: function evaluate(node, options, virtualNode, context) {
16420
- var _axe$commons8 = axe.commons, color = _axe$commons8.color, dom = _axe$commons8.dom;
16678
+ var _axe$commons9 = axe.commons, color = _axe$commons9.color, dom = _axe$commons9.dom;
16421
16679
  function getContrast(color1, color2) {
16422
16680
  var c1lum = color1.getRelativeLuminance();
16423
16681
  var c2lum = color2.getRelativeLuminance();
@@ -16639,7 +16897,7 @@
16639
16897
  }, {
16640
16898
  id: 'group-labelledby',
16641
16899
  evaluate: function evaluate(node, options, virtualNode, context) {
16642
- var _axe$commons9 = axe.commons, dom = _axe$commons9.dom, text = _axe$commons9.text;
16900
+ var _axe$commons10 = axe.commons, dom = _axe$commons10.dom, text = _axe$commons10.text;
16643
16901
  var type = axe.utils.escapeSelector(node.type);
16644
16902
  var name = axe.utils.escapeSelector(node.name);
16645
16903
  var doc = dom.getRootNode(node);
@@ -16763,6 +17021,9 @@
16763
17021
  return out;
16764
17022
  }, []);
16765
17023
  this.relatedNodes(relatedNodes);
17024
+ if (relatedNodes.length && axe.commons.dom.isModalOpen()) {
17025
+ return true;
17026
+ }
16766
17027
  return relatedNodes.length === 0;
16767
17028
  }
16768
17029
  }, {
@@ -16773,6 +17034,22 @@
16773
17034
  tabIndex = !isNaN(tabIndex) ? tabIndex : null;
16774
17035
  return tabIndex ? isFocusable && tabIndex >= 0 : isFocusable;
16775
17036
  }
17037
+ }, {
17038
+ id: 'focusable-modal-open',
17039
+ evaluate: function evaluate(node, options, virtualNode, context) {
17040
+ var tabbableElements = virtualNode.tabbableElements.map(function(_ref4) {
17041
+ var actualNode = _ref4.actualNode;
17042
+ return actualNode;
17043
+ });
17044
+ if (!tabbableElements || !tabbableElements.length) {
17045
+ return true;
17046
+ }
17047
+ if (axe.commons.dom.isModalOpen()) {
17048
+ this.relatedNodes(tabbableElements);
17049
+ return undefined;
17050
+ }
17051
+ return true;
17052
+ }
16776
17053
  }, {
16777
17054
  id: 'focusable-no-name',
16778
17055
  evaluate: function evaluate(node, options, virtualNode, context) {
@@ -16790,8 +17067,8 @@
16790
17067
  if (!tabbableElements || !tabbableElements.length) {
16791
17068
  return true;
16792
17069
  }
16793
- var relatedNodes = tabbableElements.reduce(function(out, _ref4) {
16794
- var el = _ref4.actualNode;
17070
+ var relatedNodes = tabbableElements.reduce(function(out, _ref5) {
17071
+ var el = _ref5.actualNode;
16795
17072
  var nodeName = el.nodeName.toUpperCase();
16796
17073
  if (!elementsThatCanBeDisabled.includes(nodeName)) {
16797
17074
  out.push(el);
@@ -16799,6 +17076,9 @@
16799
17076
  return out;
16800
17077
  }, []);
16801
17078
  this.relatedNodes(relatedNodes);
17079
+ if (relatedNodes.length > 0 && axe.commons.dom.isModalOpen()) {
17080
+ return true;
17081
+ }
16802
17082
  return relatedNodes.length === 0;
16803
17083
  }
16804
17084
  }, {
@@ -16827,7 +17107,9 @@
16827
17107
  if (!options || !options.selector || typeof options.selector !== 'string') {
16828
17108
  throw new TypeError('visible-in-page requires options.selector to be a string');
16829
17109
  }
16830
- var matchingElms = axe.utils.querySelectorAll(virtualNode, options.selector);
17110
+ var matchingElms = axe.utils.querySelectorAllFilter(virtualNode, options.selector, function(vNode) {
17111
+ return axe.commons.dom.isVisible(vNode.actualNode);
17112
+ });
16831
17113
  this.relatedNodes(matchingElms.map(function(vNode) {
16832
17114
  return vNode.actualNode;
16833
17115
  }));
@@ -16853,7 +17135,9 @@
16853
17135
  if (!options || !options.selector || typeof options.selector !== 'string') {
16854
17136
  throw new TypeError('visible-in-page requires options.selector to be a string');
16855
17137
  }
16856
- var matchingElms = axe.utils.querySelectorAll(virtualNode, options.selector);
17138
+ var matchingElms = axe.utils.querySelectorAllFilter(virtualNode, options.selector, function(vNode) {
17139
+ return axe.commons.dom.isVisible(vNode.actualNode);
17140
+ });
16857
17141
  this.relatedNodes(matchingElms.map(function(vNode) {
16858
17142
  return vNode.actualNode;
16859
17143
  }));
@@ -16879,7 +17163,15 @@
16879
17163
  if (!options || !options.selector || typeof options.selector !== 'string') {
16880
17164
  throw new TypeError('visible-in-page requires options.selector to be a string');
16881
17165
  }
16882
- var elms = axe.utils.querySelectorAll(virtualNode, options.selector);
17166
+ var key = 'page-no-duplicate;' + options.selector;
17167
+ if (axe._cache.get(key)) {
17168
+ this.data('ignored');
17169
+ return;
17170
+ }
17171
+ axe._cache.set(key, true);
17172
+ var elms = axe.utils.querySelectorAllFilter(axe._tree[0], options.selector, function(elm) {
17173
+ return elm !== virtualNode && axe.commons.dom.isVisible(elm.actualNode);
17174
+ });
16883
17175
  if (typeof options.nativeScopeFilter === 'string') {
16884
17176
  elms = elms.filter(function(elm) {
16885
17177
  return elm.actualNode.hasAttribute('role') || !axe.commons.dom.findUpVirtual(elm, options.nativeScopeFilter);
@@ -16888,7 +17180,12 @@
16888
17180
  this.relatedNodes(elms.map(function(elm) {
16889
17181
  return elm.actualNode;
16890
17182
  }));
16891
- return elms.length <= 1;
17183
+ return elms.length === 0;
17184
+ },
17185
+ after: function after(results, options) {
17186
+ return results.filter(function(checkResult) {
17187
+ return checkResult.data !== 'ignored';
17188
+ });
16892
17189
  },
16893
17190
  options: {
16894
17191
  selector: 'header:not([role]), [role=banner]',
@@ -16900,7 +17197,15 @@
16900
17197
  if (!options || !options.selector || typeof options.selector !== 'string') {
16901
17198
  throw new TypeError('visible-in-page requires options.selector to be a string');
16902
17199
  }
16903
- var elms = axe.utils.querySelectorAll(virtualNode, options.selector);
17200
+ var key = 'page-no-duplicate;' + options.selector;
17201
+ if (axe._cache.get(key)) {
17202
+ this.data('ignored');
17203
+ return;
17204
+ }
17205
+ axe._cache.set(key, true);
17206
+ var elms = axe.utils.querySelectorAllFilter(axe._tree[0], options.selector, function(elm) {
17207
+ return elm !== virtualNode && axe.commons.dom.isVisible(elm.actualNode);
17208
+ });
16904
17209
  if (typeof options.nativeScopeFilter === 'string') {
16905
17210
  elms = elms.filter(function(elm) {
16906
17211
  return elm.actualNode.hasAttribute('role') || !axe.commons.dom.findUpVirtual(elm, options.nativeScopeFilter);
@@ -16909,7 +17214,12 @@
16909
17214
  this.relatedNodes(elms.map(function(elm) {
16910
17215
  return elm.actualNode;
16911
17216
  }));
16912
- return elms.length <= 1;
17217
+ return elms.length === 0;
17218
+ },
17219
+ after: function after(results, options) {
17220
+ return results.filter(function(checkResult) {
17221
+ return checkResult.data !== 'ignored';
17222
+ });
16913
17223
  },
16914
17224
  options: {
16915
17225
  selector: 'footer:not([role]), [role=contentinfo]',
@@ -16921,7 +17231,15 @@
16921
17231
  if (!options || !options.selector || typeof options.selector !== 'string') {
16922
17232
  throw new TypeError('visible-in-page requires options.selector to be a string');
16923
17233
  }
16924
- var elms = axe.utils.querySelectorAll(virtualNode, options.selector);
17234
+ var key = 'page-no-duplicate;' + options.selector;
17235
+ if (axe._cache.get(key)) {
17236
+ this.data('ignored');
17237
+ return;
17238
+ }
17239
+ axe._cache.set(key, true);
17240
+ var elms = axe.utils.querySelectorAllFilter(axe._tree[0], options.selector, function(elm) {
17241
+ return elm !== virtualNode && axe.commons.dom.isVisible(elm.actualNode);
17242
+ });
16925
17243
  if (typeof options.nativeScopeFilter === 'string') {
16926
17244
  elms = elms.filter(function(elm) {
16927
17245
  return elm.actualNode.hasAttribute('role') || !axe.commons.dom.findUpVirtual(elm, options.nativeScopeFilter);
@@ -16930,7 +17248,12 @@
16930
17248
  this.relatedNodes(elms.map(function(elm) {
16931
17249
  return elm.actualNode;
16932
17250
  }));
16933
- return elms.length <= 1;
17251
+ return elms.length === 0;
17252
+ },
17253
+ after: function after(results, options) {
17254
+ return results.filter(function(checkResult) {
17255
+ return checkResult.data !== 'ignored';
17256
+ });
16934
17257
  },
16935
17258
  options: {
16936
17259
  selector: 'main:not([role]), [role=\'main\']'
@@ -16951,7 +17274,7 @@
16951
17274
  }, {
16952
17275
  id: 'duplicate-img-label',
16953
17276
  evaluate: function evaluate(node, options, virtualNode, context) {
16954
- var _axe$commons10 = axe.commons, aria = _axe$commons10.aria, text = _axe$commons10.text, dom = _axe$commons10.dom;
17277
+ var _axe$commons11 = axe.commons, aria = _axe$commons11.aria, text = _axe$commons11.text, dom = _axe$commons11.dom;
16955
17278
  if ([ 'none', 'presentation' ].includes(aria.getRole(node))) {
16956
17279
  return false;
16957
17280
  }
@@ -17020,7 +17343,7 @@
17020
17343
  }, {
17021
17344
  id: 'implicit-label',
17022
17345
  evaluate: function evaluate(node, options, virtualNode, context) {
17023
- var _axe$commons11 = axe.commons, dom = _axe$commons11.dom, text = _axe$commons11.text;
17346
+ var _axe$commons12 = axe.commons, dom = _axe$commons12.dom, text = _axe$commons12.text;
17024
17347
  var label = dom.findUpVirtual(virtualNode, 'label');
17025
17348
  if (label) {
17026
17349
  return !!text.accessibleText(label, {
@@ -17033,7 +17356,7 @@
17033
17356
  id: 'label-content-name-mismatch',
17034
17357
  evaluate: function evaluate(node, options, virtualNode, context) {
17035
17358
  var text = axe.commons.text;
17036
- var _ref5 = options || {}, pixelThreshold = _ref5.pixelThreshold, occuranceThreshold = _ref5.occuranceThreshold;
17359
+ var _ref6 = options || {}, pixelThreshold = _ref6.pixelThreshold, occuranceThreshold = _ref6.occuranceThreshold;
17037
17360
  var accText = text.accessibleText(node).toLowerCase();
17038
17361
  if (text.isHumanInterpretable(accText) < 1) {
17039
17362
  return undefined;
@@ -17225,7 +17548,7 @@
17225
17548
  }, {
17226
17549
  id: 'only-dlitems',
17227
17550
  evaluate: function evaluate(node, options, virtualNode, context) {
17228
- var _axe$commons12 = axe.commons, dom = _axe$commons12.dom, aria = _axe$commons12.aria;
17551
+ var _axe$commons13 = axe.commons, dom = _axe$commons13.dom, aria = _axe$commons13.aria;
17229
17552
  var ALLOWED_ROLES = [ 'definition', 'term', 'list' ];
17230
17553
  var base = {
17231
17554
  badNodes: [],
@@ -17263,54 +17586,52 @@
17263
17586
  }, {
17264
17587
  id: 'only-listitems',
17265
17588
  evaluate: function evaluate(node, options, virtualNode, context) {
17266
- var dom = axe.commons.dom;
17267
- var getIsListItemRole = function getIsListItemRole(role, tagName) {
17268
- return role === 'listitem' || tagName === 'LI' && !role;
17269
- };
17270
- var getHasListItem = function getHasListItem(hasListItem, tagName, isListItemRole) {
17271
- return hasListItem || tagName === 'LI' && isListItemRole || isListItemRole;
17272
- };
17273
- var base = {
17274
- badNodes: [],
17275
- isEmpty: true,
17276
- hasNonEmptyTextNode: false,
17277
- hasListItem: false,
17278
- liItemsWithRole: 0
17279
- };
17280
- var out = virtualNode.children.reduce(function(out, _ref6) {
17281
- var actualNode = _ref6.actualNode;
17282
- var tagName = actualNode.nodeName.toUpperCase();
17283
- if (actualNode.nodeType === 1 && dom.isVisible(actualNode, true, false)) {
17284
- var role = (actualNode.getAttribute('role') || '').toLowerCase();
17285
- var isListItemRole = getIsListItemRole(role, tagName);
17286
- out.hasListItem = getHasListItem(out.hasListItem, tagName, isListItemRole);
17287
- if (isListItemRole) {
17288
- out.isEmpty = false;
17289
- }
17290
- if (tagName === 'LI' && !isListItemRole) {
17291
- out.liItemsWithRole++;
17292
- }
17293
- if (tagName !== 'LI' && !isListItemRole) {
17294
- out.badNodes.push(actualNode);
17295
- }
17589
+ var _axe$commons14 = axe.commons, dom = _axe$commons14.dom, aria = _axe$commons14.aria;
17590
+ var hasNonEmptyTextNode = false;
17591
+ var atLeastOneListitem = false;
17592
+ var isEmpty = true;
17593
+ var badNodes = [];
17594
+ var badRoleNodes = [];
17595
+ var badRoles = [];
17596
+ virtualNode.children.forEach(function(vNode) {
17597
+ var actualNode = vNode.actualNode;
17598
+ if (actualNode.nodeType === 3 && actualNode.nodeValue.trim() !== '') {
17599
+ hasNonEmptyTextNode = true;
17600
+ return;
17601
+ }
17602
+ if (actualNode.nodeType !== 1 || !dom.isVisible(actualNode, true, false)) {
17603
+ return;
17604
+ }
17605
+ isEmpty = false;
17606
+ var isLi = actualNode.nodeName.toUpperCase() === 'LI';
17607
+ var role = aria.getRole(vNode);
17608
+ var isListItemRole = role === 'listitem';
17609
+ if (!isLi && !isListItemRole) {
17610
+ badNodes.push(actualNode);
17296
17611
  }
17297
- if (actualNode.nodeType === 3) {
17298
- if (actualNode.nodeValue.trim() !== '') {
17299
- out.hasNonEmptyTextNode = true;
17612
+ if (isLi && !isListItemRole) {
17613
+ badRoleNodes.push(actualNode);
17614
+ if (!badRoles.includes(role)) {
17615
+ badRoles.push(role);
17300
17616
  }
17301
17617
  }
17302
- return out;
17303
- }, base);
17304
- var virtualNodeChildrenOfTypeLi = virtualNode.children.filter(function(_ref7) {
17305
- var actualNode = _ref7.actualNode;
17306
- return actualNode.nodeName.toUpperCase() === 'LI';
17618
+ if (isListItemRole) {
17619
+ atLeastOneListitem = true;
17620
+ }
17307
17621
  });
17308
- var allLiItemsHaveRole = out.liItemsWithRole > 0 && virtualNodeChildrenOfTypeLi.length === out.liItemsWithRole;
17309
- if (out.badNodes.length) {
17310
- this.relatedNodes(out.badNodes);
17622
+ if (hasNonEmptyTextNode || badNodes.length) {
17623
+ this.relatedNodes(badNodes);
17624
+ return true;
17625
+ }
17626
+ if (isEmpty || atLeastOneListitem) {
17627
+ return false;
17311
17628
  }
17312
- var isInvalidListItem = !(out.hasListItem || out.isEmpty && !allLiItemsHaveRole);
17313
- return isInvalidListItem || !!out.badNodes.length || out.hasNonEmptyTextNode;
17629
+ this.relatedNodes(badRoleNodes);
17630
+ this.data({
17631
+ messageKey: 'roleNotValid',
17632
+ roles: badRoles.join(', ')
17633
+ });
17634
+ return true;
17314
17635
  }
17315
17636
  }, {
17316
17637
  id: 'structured-dlitems',
@@ -17338,8 +17659,8 @@
17338
17659
  id: 'caption',
17339
17660
  evaluate: function evaluate(node, options, virtualNode, context) {
17340
17661
  var tracks = axe.utils.querySelectorAll(virtualNode, 'track');
17341
- var hasCaptions = tracks.some(function(_ref8) {
17342
- var actualNode = _ref8.actualNode;
17662
+ var hasCaptions = tracks.some(function(_ref7) {
17663
+ var actualNode = _ref7.actualNode;
17343
17664
  return (actualNode.getAttribute('kind') || '').toLowerCase() === 'captions';
17344
17665
  });
17345
17666
  return hasCaptions ? false : undefined;
@@ -17348,8 +17669,8 @@
17348
17669
  id: 'description',
17349
17670
  evaluate: function evaluate(node, options, virtualNode, context) {
17350
17671
  var tracks = axe.utils.querySelectorAll(virtualNode, 'track');
17351
- var hasDescriptions = tracks.some(function(_ref9) {
17352
- var actualNode = _ref9.actualNode;
17672
+ var hasDescriptions = tracks.some(function(_ref8) {
17673
+ var actualNode = _ref8.actualNode;
17353
17674
  return (actualNode.getAttribute('kind') || '').toLowerCase() === 'descriptions';
17354
17675
  });
17355
17676
  return hasDescriptions ? false : undefined;
@@ -17378,11 +17699,68 @@
17378
17699
  options: {
17379
17700
  isViolation: false
17380
17701
  }
17702
+ }, {
17703
+ id: 'no-autoplay-audio',
17704
+ evaluate: function evaluate(node, options, virtualNode, context) {
17705
+ if (!node.duration) {
17706
+ console.warn('axe.utils.preloadMedia did not load metadata');
17707
+ return undefined;
17708
+ }
17709
+ var _options$allowedDurat = options.allowedDuration, allowedDuration = _options$allowedDurat === void 0 ? 3 : _options$allowedDurat;
17710
+ var playableDuration = getPlayableDuration(node);
17711
+ if (playableDuration <= allowedDuration && !node.hasAttribute('loop')) {
17712
+ return true;
17713
+ }
17714
+ if (!node.hasAttribute('controls')) {
17715
+ return false;
17716
+ }
17717
+ return true;
17718
+ function getPlayableDuration(elm) {
17719
+ if (!elm.currentSrc) {
17720
+ return 0;
17721
+ }
17722
+ var playbackRange = getPlaybackRange(elm.currentSrc);
17723
+ if (!playbackRange) {
17724
+ return Math.abs(elm.duration - (elm.currentTime || 0));
17725
+ }
17726
+ if (playbackRange.length === 1) {
17727
+ return Math.abs(elm.duration - playbackRange[0]);
17728
+ }
17729
+ return Math.abs(playbackRange[1] - playbackRange[0]);
17730
+ }
17731
+ function getPlaybackRange(src) {
17732
+ var match = src.match(/#t=(.*)/);
17733
+ if (!match) {
17734
+ return;
17735
+ }
17736
+ var _match = _slicedToArray(match, 2), value = _match[1];
17737
+ var ranges = value.split(',');
17738
+ return ranges.map(function(range) {
17739
+ if (/:/.test(range)) {
17740
+ return convertHourMinSecToSeconds(range);
17741
+ }
17742
+ return parseFloat(range);
17743
+ });
17744
+ }
17745
+ function convertHourMinSecToSeconds(hhMmSs) {
17746
+ var parts = hhMmSs.split(':');
17747
+ var secs = 0;
17748
+ var mins = 1;
17749
+ while (parts.length > 0) {
17750
+ secs += mins * parseInt(parts.pop(), 10);
17751
+ mins *= 60;
17752
+ }
17753
+ return parseFloat(secs);
17754
+ }
17755
+ },
17756
+ options: {
17757
+ allowedDuration: 3
17758
+ }
17381
17759
  }, {
17382
17760
  id: 'css-orientation-lock',
17383
17761
  evaluate: function evaluate(node, options, virtualNode, context) {
17384
- var _ref10 = context || {}, _ref10$cssom = _ref10.cssom, cssom = _ref10$cssom === void 0 ? undefined : _ref10$cssom;
17385
- var _ref11 = options || {}, _ref11$degreeThreshol = _ref11.degreeThreshold, degreeThreshold = _ref11$degreeThreshol === void 0 ? 0 : _ref11$degreeThreshol;
17762
+ var _ref9 = context || {}, _ref9$cssom = _ref9.cssom, cssom = _ref9$cssom === void 0 ? undefined : _ref9$cssom;
17763
+ var _ref10 = options || {}, _ref10$degreeThreshol = _ref10.degreeThreshold, degreeThreshold = _ref10$degreeThreshol === void 0 ? 0 : _ref10$degreeThreshol;
17386
17764
  if (!cssom || !cssom.length) {
17387
17765
  return undefined;
17388
17766
  }
@@ -17390,14 +17768,14 @@
17390
17768
  var relatedElements = [];
17391
17769
  var rulesGroupByDocumentFragment = groupCssomByDocument(cssom);
17392
17770
  var _loop = function _loop() {
17393
- var key = _Object$keys[_i];
17771
+ var key = _Object$keys[_i2];
17394
17772
  var _rulesGroupByDocument = rulesGroupByDocumentFragment[key], root = _rulesGroupByDocument.root, rules = _rulesGroupByDocument.rules;
17395
17773
  var orientationRules = rules.filter(isMediaRuleWithOrientation);
17396
17774
  if (!orientationRules.length) {
17397
17775
  return 'continue';
17398
17776
  }
17399
- orientationRules.forEach(function(_ref17) {
17400
- var cssRules = _ref17.cssRules;
17777
+ orientationRules.forEach(function(_ref16) {
17778
+ var cssRules = _ref16.cssRules;
17401
17779
  Array.from(cssRules).forEach(function(cssRule) {
17402
17780
  var locked = getIsOrientationLocked(cssRule);
17403
17781
  if (locked && cssRule.selectorText.toUpperCase() !== 'HTML') {
@@ -17408,7 +17786,7 @@
17408
17786
  });
17409
17787
  });
17410
17788
  };
17411
- for (var _i = 0, _Object$keys = Object.keys(rulesGroupByDocumentFragment); _i < _Object$keys.length; _i++) {
17789
+ for (var _i2 = 0, _Object$keys = Object.keys(rulesGroupByDocumentFragment); _i2 < _Object$keys.length; _i2++) {
17412
17790
  var _ret = _loop();
17413
17791
  if (_ret === 'continue') {
17414
17792
  continue;
@@ -17422,8 +17800,8 @@
17422
17800
  }
17423
17801
  return false;
17424
17802
  function groupCssomByDocument(cssObjectModel) {
17425
- return cssObjectModel.reduce(function(out, _ref12) {
17426
- var sheet = _ref12.sheet, root = _ref12.root, shadowId = _ref12.shadowId;
17803
+ return cssObjectModel.reduce(function(out, _ref11) {
17804
+ var sheet = _ref11.sheet, root = _ref11.root, shadowId = _ref11.shadowId;
17427
17805
  var key = shadowId ? shadowId : 'topDocument';
17428
17806
  if (!out[key]) {
17429
17807
  out[key] = {
@@ -17439,15 +17817,15 @@
17439
17817
  return out;
17440
17818
  }, {});
17441
17819
  }
17442
- function isMediaRuleWithOrientation(_ref13) {
17443
- var type = _ref13.type, cssText = _ref13.cssText;
17820
+ function isMediaRuleWithOrientation(_ref12) {
17821
+ var type = _ref12.type, cssText = _ref12.cssText;
17444
17822
  if (type !== 4) {
17445
17823
  return false;
17446
17824
  }
17447
17825
  return /orientation:\s*landscape/i.test(cssText) || /orientation:\s*portrait/i.test(cssText);
17448
17826
  }
17449
- function getIsOrientationLocked(_ref14) {
17450
- var selectorText = _ref14.selectorText, style = _ref14.style;
17827
+ function getIsOrientationLocked(_ref13) {
17828
+ var selectorText = _ref13.selectorText, style = _ref13.style;
17451
17829
  if (!selectorText || style.length <= 0) {
17452
17830
  return false;
17453
17831
  }
@@ -17494,7 +17872,7 @@
17494
17872
  }
17495
17873
  }
17496
17874
  function getAngleInDegrees(angleWithUnit) {
17497
- var _ref15 = angleWithUnit.match(/(deg|grad|rad|turn)/) || [], _ref16 = _slicedToArray(_ref15, 1), unit = _ref16[0];
17875
+ var _ref14 = angleWithUnit.match(/(deg|grad|rad|turn)/) || [], _ref15 = _slicedToArray(_ref14, 1), unit = _ref15[0];
17498
17876
  if (!unit) {
17499
17877
  return;
17500
17878
  }
@@ -17634,6 +18012,92 @@
17634
18012
  }
17635
18013
  return results;
17636
18014
  }
18015
+ }, {
18016
+ id: 'identical-links-same-purpose',
18017
+ evaluate: function evaluate(node, options, virtualNode, context) {
18018
+ var _axe$commons15 = axe.commons, dom = _axe$commons15.dom, text = _axe$commons15.text;
18019
+ var accText = text.accessibleTextVirtual(virtualNode);
18020
+ var name = text.sanitize(text.removeUnicode(accText, {
18021
+ emoji: true,
18022
+ nonBmp: true,
18023
+ punctuations: true
18024
+ })).toLowerCase();
18025
+ if (!name) {
18026
+ return undefined;
18027
+ }
18028
+ var afterData = {
18029
+ name: name,
18030
+ urlProps: dom.urlPropsFromAttribute(node, 'href')
18031
+ };
18032
+ this.data(afterData);
18033
+ this.relatedNodes([ node ]);
18034
+ return true;
18035
+ },
18036
+ after: function after(results, options) {
18037
+ if (results.length < 2) {
18038
+ return results;
18039
+ }
18040
+ var incompleteResults = results.filter(function(_ref17) {
18041
+ var result = _ref17.result;
18042
+ return result !== undefined;
18043
+ });
18044
+ var uniqueResults = [];
18045
+ var nameMap = {};
18046
+ var _loop2 = function _loop2(index) {
18047
+ var _currentResult$relate;
18048
+ var currentResult = incompleteResults[index];
18049
+ var _currentResult$data = currentResult.data, name = _currentResult$data.name, urlProps = _currentResult$data.urlProps;
18050
+ if (nameMap[name]) {
18051
+ return 'continue';
18052
+ }
18053
+ var sameNameResults = incompleteResults.filter(function(_ref18, resultNum) {
18054
+ var data = _ref18.data;
18055
+ return data.name === name && resultNum !== index;
18056
+ });
18057
+ var isSameUrl = sameNameResults.every(function(_ref19) {
18058
+ var data = _ref19.data;
18059
+ return isIdenticalObject(data.urlProps, urlProps);
18060
+ });
18061
+ if (sameNameResults.length && !isSameUrl) {
18062
+ currentResult.result = undefined;
18063
+ }
18064
+ currentResult.relatedNodes = [];
18065
+ (_currentResult$relate = currentResult.relatedNodes).push.apply(_currentResult$relate, _toConsumableArray(sameNameResults.map(function(node) {
18066
+ return node.relatedNodes[0];
18067
+ })));
18068
+ nameMap[name] = sameNameResults;
18069
+ uniqueResults.push(currentResult);
18070
+ };
18071
+ for (var index = 0; index < incompleteResults.length; index++) {
18072
+ var _ret2 = _loop2(index);
18073
+ if (_ret2 === 'continue') {
18074
+ continue;
18075
+ }
18076
+ }
18077
+ return uniqueResults;
18078
+ function isIdenticalObject(a, b) {
18079
+ if (!a || !b) {
18080
+ return false;
18081
+ }
18082
+ var aProps = Object.getOwnPropertyNames(a);
18083
+ var bProps = Object.getOwnPropertyNames(b);
18084
+ if (aProps.length !== bProps.length) {
18085
+ return false;
18086
+ }
18087
+ var result = aProps.every(function(propName) {
18088
+ var aValue = a[propName];
18089
+ var bValue = b[propName];
18090
+ if (_typeof(aValue) !== _typeof(bValue)) {
18091
+ return false;
18092
+ }
18093
+ if (typeof aValue === 'object' || typeof bValue === 'object') {
18094
+ return isIdenticalObject(aValue, bValue);
18095
+ }
18096
+ return aValue === bValue;
18097
+ });
18098
+ return result;
18099
+ }
18100
+ }
17637
18101
  }, {
17638
18102
  id: 'internal-link-present',
17639
18103
  evaluate: function evaluate(node, options, virtualNode, context) {
@@ -17746,8 +18210,13 @@
17746
18210
  }, {
17747
18211
  id: 'region',
17748
18212
  evaluate: function evaluate(node, options, virtualNode, context) {
17749
- var _axe$commons13 = axe.commons, dom = _axe$commons13.dom, aria = _axe$commons13.aria;
18213
+ var _axe$commons16 = axe.commons, dom = _axe$commons16.dom, aria = _axe$commons16.aria;
17750
18214
  var landmarkRoles = aria.getRolesByType('landmark');
18215
+ var implicitAriaLiveRoles = [ 'alert', 'log', 'status' ];
18216
+ var regionlessNodes = axe._cache.get('regionlessNodes');
18217
+ if (regionlessNodes) {
18218
+ return !regionlessNodes.includes(virtualNode);
18219
+ }
17751
18220
  var implicitLandmarks = landmarkRoles.reduce(function(arr, role) {
17752
18221
  return arr.concat(aria.implicitNodes(role));
17753
18222
  }, []).filter(function(r) {
@@ -17759,12 +18228,12 @@
17759
18228
  noImplicit: true
17760
18229
  });
17761
18230
  var ariaLive = (node.getAttribute('aria-live') || '').toLowerCase().trim();
18231
+ if ([ 'assertive', 'polite' ].includes(ariaLive) || implicitAriaLiveRoles.includes(explicitRole)) {
18232
+ return true;
18233
+ }
17762
18234
  if (explicitRole) {
17763
18235
  return explicitRole === 'dialog' || landmarkRoles.includes(explicitRole);
17764
18236
  }
17765
- if ([ 'assertive', 'polite' ].includes(ariaLive)) {
17766
- return true;
17767
- }
17768
18237
  return implicitLandmarks.some(function(implicitSelector) {
17769
18238
  var matches = axe.utils.matchesSelector(node, implicitSelector);
17770
18239
  if (node.nodeName.toUpperCase() === 'FORM') {
@@ -17778,24 +18247,33 @@
17778
18247
  function findRegionlessElms(virtualNode) {
17779
18248
  var node = virtualNode.actualNode;
17780
18249
  if (isRegion(virtualNode) || dom.isSkipLink(virtualNode.actualNode) && dom.getElementByReference(virtualNode.actualNode, 'href') || !dom.isVisible(node, true)) {
18250
+ var vNode = virtualNode;
18251
+ while (vNode) {
18252
+ vNode._hasRegionDescendant = true;
18253
+ vNode = vNode.parent;
18254
+ }
17781
18255
  return [];
17782
18256
  } else if (dom.hasContent(node, true)) {
17783
- return [ node ];
18257
+ return [ virtualNode ];
17784
18258
  } else {
17785
- return virtualNode.children.filter(function(_ref18) {
17786
- var actualNode = _ref18.actualNode;
18259
+ return virtualNode.children.filter(function(_ref20) {
18260
+ var actualNode = _ref20.actualNode;
17787
18261
  return actualNode.nodeType === 1;
17788
18262
  }).map(findRegionlessElms).reduce(function(a, b) {
17789
18263
  return a.concat(b);
17790
18264
  }, []);
17791
18265
  }
17792
18266
  }
17793
- var regionlessNodes = findRegionlessElms(virtualNode);
17794
- this.relatedNodes(regionlessNodes);
17795
- return regionlessNodes.length === 0;
17796
- },
17797
- after: function after(results, options) {
17798
- return [ results[0] ];
18267
+ regionlessNodes = findRegionlessElms(axe._tree[0]).map(function(vNode) {
18268
+ while (vNode.parent && !vNode.parent._hasRegionDescendant && vNode.parent.actualNode !== document.body) {
18269
+ vNode = vNode.parent;
18270
+ }
18271
+ return vNode;
18272
+ }).filter(function(vNode, index, array) {
18273
+ return array.indexOf(vNode) === index;
18274
+ });
18275
+ axe._cache.set('regionlessNodes', regionlessNodes);
18276
+ return !regionlessNodes.includes(virtualNode);
17799
18277
  }
17800
18278
  }, {
17801
18279
  id: 'skip-link',
@@ -17907,13 +18385,13 @@
17907
18385
  }, {
17908
18386
  id: 'aria-label',
17909
18387
  evaluate: function evaluate(node, options, virtualNode, context) {
17910
- var _axe$commons14 = axe.commons, text = _axe$commons14.text, aria = _axe$commons14.aria;
18388
+ var _axe$commons17 = axe.commons, text = _axe$commons17.text, aria = _axe$commons17.aria;
17911
18389
  return !!text.sanitize(aria.arialabelText(virtualNode));
17912
18390
  }
17913
18391
  }, {
17914
18392
  id: 'aria-labelledby',
17915
18393
  evaluate: function evaluate(node, options, virtualNode, context) {
17916
- var _axe$commons15 = axe.commons, text = _axe$commons15.text, aria = _axe$commons15.aria;
18394
+ var _axe$commons18 = axe.commons, text = _axe$commons18.text, aria = _axe$commons18.aria;
17917
18395
  return !!text.sanitize(aria.arialabelledbyText(node));
17918
18396
  }
17919
18397
  }, {
@@ -18019,6 +18497,15 @@
18019
18497
  evaluate: function evaluate(node, options, virtualNode, context) {
18020
18498
  return node.getAttribute('role') === 'presentation';
18021
18499
  }
18500
+ }, {
18501
+ id: 'svg-non-empty-title',
18502
+ evaluate: function evaluate(node, options, virtualNode, context) {
18503
+ var titleNode = virtualNode.children.find(function(_ref21) {
18504
+ var props = _ref21.props;
18505
+ return props.nodeName === 'title';
18506
+ });
18507
+ return !!titleNode && titleNode.actualNode.textContent.trim() !== '';
18508
+ }
18022
18509
  }, {
18023
18510
  id: 'caption-faked',
18024
18511
  evaluate: function evaluate(node, options, virtualNode, context) {
@@ -18288,7 +18775,9 @@
18288
18775
  unstandardized: true
18289
18776
  },
18290
18777
  'aria-details': {
18291
- unsupported: true
18778
+ type: 'idref',
18779
+ allowEmpty: true,
18780
+ unsupported: false
18292
18781
  },
18293
18782
  'aria-disabled': {
18294
18783
  type: 'boolean',
@@ -18463,7 +18952,7 @@
18463
18952
  unsupported: false
18464
18953
  }
18465
18954
  };
18466
- lookupTable.globalAttributes = [ 'aria-atomic', 'aria-busy', 'aria-controls', 'aria-current', 'aria-describedby', 'aria-disabled', 'aria-dropeffect', 'aria-flowto', 'aria-grabbed', 'aria-haspopup', 'aria-hidden', 'aria-invalid', 'aria-keyshortcuts', 'aria-label', 'aria-labelledby', 'aria-live', 'aria-owns', 'aria-relevant', 'aria-roledescription' ];
18955
+ lookupTable.globalAttributes = [ 'aria-atomic', 'aria-busy', 'aria-controls', 'aria-current', 'aria-describedby', 'aria-details', 'aria-disabled', 'aria-dropeffect', 'aria-flowto', 'aria-grabbed', 'aria-haspopup', 'aria-hidden', 'aria-invalid', 'aria-keyshortcuts', 'aria-label', 'aria-labelledby', 'aria-live', 'aria-owns', 'aria-relevant', 'aria-roledescription' ];
18467
18956
  lookupTable.role = {
18468
18957
  alert: {
18469
18958
  type: 'widget',
@@ -18579,7 +19068,7 @@
18579
19068
  required: [ 'aria-expanded' ]
18580
19069
  },
18581
19070
  owned: {
18582
- all: [ 'listbox', 'textbox' ]
19071
+ all: [ 'listbox', 'tree', 'grid', 'dialog', 'textbox' ]
18583
19072
  },
18584
19073
  nameFrom: [ 'author' ],
18585
19074
  context: null,
@@ -19933,8 +20422,11 @@
19933
20422
  }
19934
20423
  }, {
19935
20424
  nodeName: 'select',
19936
- condition: function condition(node) {
19937
- return Number(node.getAttribute('size')) > 1;
20425
+ condition: function condition(vNode) {
20426
+ if (!(vNode instanceof axe.AbstractVirtualNode)) {
20427
+ vNode = axe.utils.getNodeFromTree(vNode);
20428
+ }
20429
+ return Number(vNode.attr('size')) > 1;
19938
20430
  },
19939
20431
  properties: {
19940
20432
  multiple: true
@@ -19956,8 +20448,8 @@
19956
20448
  nodeName: [ 'abbr', 'address', 'canvas', 'div', 'p', 'pre', 'blockquote', 'ins', 'del', 'output', 'span', 'table', 'tbody', 'thead', 'tfoot', 'td', 'em', 'strong', 'small', 's', 'cite', 'q', 'dfn', 'abbr', 'time', 'code', 'var', 'samp', 'kbd', 'sub', 'sup', 'i', 'b', 'u', 'mark', 'ruby', 'rt', 'rp', 'bdi', 'bdo', 'br', 'wbr', 'th', 'tr' ]
19957
20449
  } ];
19958
20450
  lookupTable.evaluateRoleForElement = {
19959
- A: function A(_ref19) {
19960
- var node = _ref19.node, out = _ref19.out;
20451
+ A: function A(_ref22) {
20452
+ var node = _ref22.node, out = _ref22.out;
19961
20453
  if (node.namespaceURI === 'http://www.w3.org/2000/svg') {
19962
20454
  return true;
19963
20455
  }
@@ -19966,19 +20458,19 @@
19966
20458
  }
19967
20459
  return true;
19968
20460
  },
19969
- AREA: function AREA(_ref20) {
19970
- var node = _ref20.node;
20461
+ AREA: function AREA(_ref23) {
20462
+ var node = _ref23.node;
19971
20463
  return !node.href;
19972
20464
  },
19973
- BUTTON: function BUTTON(_ref21) {
19974
- var node = _ref21.node, role = _ref21.role, out = _ref21.out;
20465
+ BUTTON: function BUTTON(_ref24) {
20466
+ var node = _ref24.node, role = _ref24.role, out = _ref24.out;
19975
20467
  if (node.getAttribute('type') === 'menu') {
19976
20468
  return role === 'menuitem';
19977
20469
  }
19978
20470
  return out;
19979
20471
  },
19980
- IMG: function IMG(_ref22) {
19981
- var node = _ref22.node, role = _ref22.role, out = _ref22.out;
20472
+ IMG: function IMG(_ref25) {
20473
+ var node = _ref25.node, role = _ref25.role, out = _ref25.out;
19982
20474
  switch (node.alt) {
19983
20475
  case null:
19984
20476
  return out;
@@ -19990,8 +20482,8 @@
19990
20482
  return role !== 'presentation' && role !== 'none';
19991
20483
  }
19992
20484
  },
19993
- INPUT: function INPUT(_ref23) {
19994
- var node = _ref23.node, role = _ref23.role, out = _ref23.out;
20485
+ INPUT: function INPUT(_ref26) {
20486
+ var node = _ref26.node, role = _ref26.role, out = _ref26.out;
19995
20487
  switch (node.type) {
19996
20488
  case 'button':
19997
20489
  case 'image':
@@ -20019,32 +20511,32 @@
20019
20511
  return false;
20020
20512
  }
20021
20513
  },
20022
- LI: function LI(_ref24) {
20023
- var node = _ref24.node, out = _ref24.out;
20514
+ LI: function LI(_ref27) {
20515
+ var node = _ref27.node, out = _ref27.out;
20024
20516
  var hasImplicitListitemRole = axe.utils.matchesSelector(node, 'ol li, ul li');
20025
20517
  if (hasImplicitListitemRole) {
20026
20518
  return out;
20027
20519
  }
20028
20520
  return true;
20029
20521
  },
20030
- MENU: function MENU(_ref25) {
20031
- var node = _ref25.node;
20522
+ MENU: function MENU(_ref28) {
20523
+ var node = _ref28.node;
20032
20524
  if (node.getAttribute('type') === 'context') {
20033
20525
  return false;
20034
20526
  }
20035
20527
  return true;
20036
20528
  },
20037
- OPTION: function OPTION(_ref26) {
20038
- var node = _ref26.node;
20529
+ OPTION: function OPTION(_ref29) {
20530
+ var node = _ref29.node;
20039
20531
  var withinOptionList = axe.utils.matchesSelector(node, 'select > option, datalist > option, optgroup > option');
20040
20532
  return !withinOptionList;
20041
20533
  },
20042
- SELECT: function SELECT(_ref27) {
20043
- var node = _ref27.node, role = _ref27.role;
20534
+ SELECT: function SELECT(_ref30) {
20535
+ var node = _ref30.node, role = _ref30.role;
20044
20536
  return !node.multiple && node.size <= 1 && role === 'menu';
20045
20537
  },
20046
- SVG: function SVG(_ref28) {
20047
- var node = _ref28.node, out = _ref28.out;
20538
+ SVG: function SVG(_ref31) {
20539
+ var node = _ref31.node, out = _ref31.out;
20048
20540
  if (node.parentNode && node.parentNode.namespaceURI === 'http://www.w3.org/2000/svg') {
20049
20541
  return true;
20050
20542
  }
@@ -20052,15 +20544,15 @@
20052
20544
  }
20053
20545
  };
20054
20546
  lookupTable.rolesOfType = {
20055
- widget: [ 'button', 'checkbox', 'dialog', 'gridcell', 'link', 'log', 'marquee', 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'option', 'progressbar', 'radio', 'scrollbar', 'slider', 'spinbutton', 'status', 'switch', 'tab', 'tabpanel', 'textbox', 'timer', 'tooltip', 'tree', 'treeitem' ]
20547
+ widget: [ 'button', 'checkbox', 'dialog', 'gridcell', 'link', 'log', 'marquee', 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'option', 'progressbar', 'radio', 'scrollbar', 'searchbox', 'slider', 'spinbutton', 'status', 'switch', 'tab', 'tabpanel', 'textbox', 'timer', 'tooltip', 'tree', 'treeitem' ]
20056
20548
  };
20057
20549
  var color = {};
20058
20550
  commons.color = color;
20059
20551
  var dom = commons.dom = {};
20060
20552
  var forms = {};
20061
20553
  commons.forms = forms;
20062
- function matches(node, definition) {
20063
- return matches.fromDefinition(node, definition);
20554
+ function matches(vNode, definition) {
20555
+ return matches.fromDefinition(vNode, definition);
20064
20556
  }
20065
20557
  commons.matches = matches;
20066
20558
  var table = commons.table = {};
@@ -20156,8 +20648,8 @@
20156
20648
  });
20157
20649
  return unallowedRoles;
20158
20650
  };
20159
- aria.getOwnedVirtual = function getOwned(_ref29) {
20160
- var actualNode = _ref29.actualNode, children = _ref29.children;
20651
+ aria.getOwnedVirtual = function getOwned(_ref32) {
20652
+ var actualNode = _ref32.actualNode, children = _ref32.children;
20161
20653
  if (!actualNode || !children) {
20162
20654
  throw new Error('getOwnedVirtual requires a virtual node');
20163
20655
  }
@@ -20170,7 +20662,7 @@
20170
20662
  }, children);
20171
20663
  };
20172
20664
  aria.getRole = function getRole(node) {
20173
- var _ref30 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, noImplicit = _ref30.noImplicit, fallback = _ref30.fallback, abstracts = _ref30.abstracts, dpub = _ref30.dpub;
20665
+ var _ref33 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, noImplicit = _ref33.noImplicit, fallback = _ref33.fallback, abstracts = _ref33.abstracts, dpub = _ref33.dpub;
20174
20666
  node = node.actualNode || node;
20175
20667
  if (node.nodeType !== 1) {
20176
20668
  return null;
@@ -20210,8 +20702,8 @@
20210
20702
  }
20211
20703
  }
20212
20704
  }
20213
- for (var _i2 = 0; _i2 < node.children.length; _i2++) {
20214
- cacheIdRefs(node.children[_i2], refAttrs);
20705
+ for (var _i3 = 0; _i3 < node.children.length; _i3++) {
20706
+ cacheIdRefs(node.children[_i3], refAttrs);
20215
20707
  }
20216
20708
  }
20217
20709
  aria.isAccessibleRef = function isAccessibleRef(node) {
@@ -20256,8 +20748,8 @@
20256
20748
  var roleDefinition = aria.lookupTable.role[role];
20257
20749
  return roleDefinition ? roleDefinition.unsupported : false;
20258
20750
  };
20259
- aria.labelVirtual = function(_ref31) {
20260
- var actualNode = _ref31.actualNode;
20751
+ aria.labelVirtual = function(_ref34) {
20752
+ var actualNode = _ref34.actualNode;
20261
20753
  var ref, candidate;
20262
20754
  if (actualNode.getAttribute('aria-labelledby')) {
20263
20755
  ref = dom.idrefs(actualNode, 'aria-labelledby');
@@ -20283,7 +20775,7 @@
20283
20775
  return aria.labelVirtual(node);
20284
20776
  };
20285
20777
  aria.namedFromContents = function namedFromContents(node) {
20286
- var _ref32 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, strict = _ref32.strict;
20778
+ var _ref35 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, strict = _ref35.strict;
20287
20779
  node = node.actualNode || node;
20288
20780
  if (node.nodeType !== 1) {
20289
20781
  return false;
@@ -20299,7 +20791,7 @@
20299
20791
  return !roleDef || [ 'presentation', 'none' ].includes(role);
20300
20792
  };
20301
20793
  aria.isValidRole = function(role) {
20302
- var _ref33 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, allowAbstract = _ref33.allowAbstract, _ref33$flagUnsupporte = _ref33.flagUnsupported, flagUnsupported = _ref33$flagUnsupporte === void 0 ? false : _ref33$flagUnsupporte;
20794
+ var _ref36 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, allowAbstract = _ref36.allowAbstract, _ref36$flagUnsupporte = _ref36.flagUnsupported, flagUnsupported = _ref36$flagUnsupporte === void 0 ? false : _ref36$flagUnsupporte;
20303
20795
  var roleDefinition = aria.lookupTable.role[role];
20304
20796
  var isRoleUnsupported = roleDefinition ? roleDefinition.unsupported : false;
20305
20797
  if (!roleDefinition || flagUnsupported && isRoleUnsupported) {
@@ -20579,22 +21071,6 @@
20579
21071
  color.elementIsDistinct = elementIsDistinct;
20580
21072
  color.getBackgroundColor = function getBackgroundColor(elm) {
20581
21073
  var bgElms = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
20582
- var noScroll = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
20583
- if (noScroll !== true) {
20584
- var clientHeight = elm.getBoundingClientRect().height;
20585
- var alignToTop = clientHeight - 2 >= window.innerHeight * 2;
20586
- elm.scrollIntoView(alignToTop);
20587
- var center, scrollParent;
20588
- do {
20589
- var rect = elm.getBoundingClientRect();
20590
- var x = 'x' in rect ? rect.x : rect.left;
20591
- center = x + rect.width / 2;
20592
- if (center < 0) {
20593
- scrollParent = getScrollParent(elm);
20594
- scrollParent.scrollLeft = 0;
20595
- }
20596
- } while (center < 0 && scrollParent !== document.documentElement);
20597
- }
20598
21074
  var bgColors = [];
20599
21075
  var elmStack = color.getBackgroundStack(elm);
20600
21076
  (elmStack || []).some(function(bgElm) {
@@ -20625,7 +21101,6 @@
20625
21101
  if (elmStack === null) {
20626
21102
  return null;
20627
21103
  }
20628
- elmStack = includeMissingElements(elmStack, elm);
20629
21104
  elmStack = dom.reduceToElementsBelowFloating(elmStack, elm);
20630
21105
  elmStack = sortPageBackground(elmStack);
20631
21106
  var elmIndex = elmStack.indexOf(elm);
@@ -20643,7 +21118,6 @@
20643
21118
  if (rectStack && rectStack.length > 1) {
20644
21119
  var boundingStack = rectStack.shift();
20645
21120
  var isSame;
20646
- includeMissingElements(boundingStack, elm);
20647
21121
  rectStack.forEach(function(rectList, index) {
20648
21122
  if (index === 0) {
20649
21123
  return;
@@ -20663,23 +21137,11 @@
20663
21137
  return null;
20664
21138
  };
20665
21139
  color.getRectStack = function(elm) {
20666
- var boundingCoords = axe.commons.color.centerPointOfRect(elm.getBoundingClientRect());
20667
- if (!boundingCoords) {
20668
- return null;
20669
- }
20670
- var boundingStack = dom.shadowElementsFromPoint(boundingCoords.x, boundingCoords.y);
20671
- var rects = Array.from(elm.getClientRects());
20672
- if (!rects || rects.length <= 1) {
21140
+ var boundingStack = axe.commons.dom.getElementStack(elm);
21141
+ var filteredArr = axe.commons.dom.getTextElementStack(elm);
21142
+ if (!filteredArr || filteredArr.length <= 1) {
20673
21143
  return [ boundingStack ];
20674
21144
  }
20675
- var filteredArr = rects.filter(function(rect) {
20676
- return rect.width && rect.width > 0;
20677
- }).map(function(rect) {
20678
- var coords = axe.commons.color.centerPointOfRect(rect);
20679
- if (coords) {
20680
- return dom.shadowElementsFromPoint(coords.x, coords.y);
20681
- }
20682
- });
20683
21145
  if (filteredArr.some(function(stack) {
20684
21146
  return stack === undefined;
20685
21147
  })) {
@@ -20701,35 +21163,6 @@
20701
21163
  }
20702
21164
  return bgNodes;
20703
21165
  }
20704
- function includeMissingElements(elmStack, elm) {
20705
- var nodeName = elm.nodeName.toUpperCase();
20706
- var elementMap = {
20707
- TD: [ 'TR', 'THEAD', 'TBODY', 'TFOOT' ],
20708
- TH: [ 'TR', 'THEAD', 'TBODY', 'TFOOT' ],
20709
- INPUT: [ 'LABEL' ]
20710
- };
20711
- var tagArray = elmStack.map(function(elm) {
20712
- return elm.nodeName.toUpperCase();
20713
- });
20714
- var bgNodes = elmStack;
20715
- for (var candidate in elementMap) {
20716
- if (tagArray.includes(candidate)) {
20717
- for (var candidateIndex = 0; candidateIndex < elementMap[candidate].length; candidateIndex++) {
20718
- var ancestorMatch = axe.commons.dom.findUp(elm, elementMap[candidate][candidateIndex]);
20719
- if (ancestorMatch && elmStack.indexOf(ancestorMatch) === -1) {
20720
- var overlaps = axe.commons.dom.visuallyOverlaps(elm.getBoundingClientRect(), ancestorMatch);
20721
- if (overlaps) {
20722
- bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, ancestorMatch);
20723
- }
20724
- }
20725
- if (nodeName === elementMap[candidate][candidateIndex] && tagArray.indexOf(nodeName) === -1) {
20726
- bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, elm);
20727
- }
20728
- }
20729
- }
20730
- }
20731
- return bgNodes;
20732
- }
20733
21166
  function elmPartiallyObscured(elm, bgElm, bgColor) {
20734
21167
  var obscured = elm !== bgElm && !dom.visuallyContains(elm, bgElm) && bgColor.alpha !== 0;
20735
21168
  if (obscured) {
@@ -20762,24 +21195,6 @@
20762
21195
  }
20763
21196
  return false;
20764
21197
  }
20765
- function getScrollParent(element, includeHidden) {
20766
- var style = getComputedStyle(element);
20767
- var excludeStaticParent = style.position === 'absolute';
20768
- var overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/;
20769
- if (style.position === 'fixed') {
20770
- return document.documentElement;
20771
- }
20772
- for (var parent = element; parent = parent.parentElement; ) {
20773
- style = getComputedStyle(parent);
20774
- if (excludeStaticParent && style.position === 'static') {
20775
- continue;
20776
- }
20777
- if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) {
20778
- return parent;
20779
- }
20780
- }
20781
- return document.documentElement;
20782
- }
20783
21198
  dom.isOpaque = function(node) {
20784
21199
  var style = window.getComputedStyle(node);
20785
21200
  return color.elementHasImage(node, style) || color.getOwnBackgroundColor(style).alpha === 1;
@@ -20864,8 +21279,8 @@
20864
21279
  }
20865
21280
  return finalElements;
20866
21281
  };
20867
- dom.findElmsInContext = function(_ref34) {
20868
- var context = _ref34.context, value = _ref34.value, attr = _ref34.attr, _ref34$elm = _ref34.elm, elm = _ref34$elm === void 0 ? '' : _ref34$elm;
21282
+ dom.findElmsInContext = function(_ref37) {
21283
+ var context = _ref37.context, value = _ref37.value, attr = _ref37.attr, _ref37$elm = _ref37.elm, elm = _ref37$elm === void 0 ? '' : _ref37$elm;
20869
21284
  var root;
20870
21285
  var escapedValue = axe.utils.escapeSelector(value);
20871
21286
  if (context.nodeType === 9 || context.nodeType === 11) {
@@ -20948,15 +21363,13 @@
20948
21363
  };
20949
21364
  };
20950
21365
  var gridSize = 200;
20951
- function isStackingContext(vNode) {
20952
- var node = vNode.actualNode;
20953
- if (!node || node.nodeName === 'HTML' || node.nodeName === '#document-fragment') {
21366
+ function isStackingContext(vNode, parentVNode) {
21367
+ var position = vNode.getComputedStylePropertyValue('position');
21368
+ var zIndex = vNode.getComputedStylePropertyValue('z-index');
21369
+ if (position === 'fixed' || position === 'sticky') {
20954
21370
  return true;
20955
21371
  }
20956
- if (vNode.getComputedStylePropertyValue('position') === 'fixed' || vNode.getComputedStylePropertyValue('position') === 'sticky') {
20957
- return true;
20958
- }
20959
- if (vNode.getComputedStylePropertyValue('z-index') !== 'auto' && vNode.getComputedStylePropertyValue('position') !== 'static') {
21372
+ if (zIndex !== 'auto' && position !== 'static') {
20960
21373
  return true;
20961
21374
  }
20962
21375
  if (vNode.getComputedStylePropertyValue('opacity') !== '1') {
@@ -20966,16 +21379,20 @@
20966
21379
  if (transform !== 'none') {
20967
21380
  return true;
20968
21381
  }
20969
- if (vNode.getComputedStylePropertyValue('mix-blend-mode') && vNode.getComputedStylePropertyValue('mix-blend-mode') !== 'normal') {
21382
+ var mixBlendMode = vNode.getComputedStylePropertyValue('mix-blend-mode');
21383
+ if (mixBlendMode && mixBlendMode !== 'normal') {
20970
21384
  return true;
20971
21385
  }
20972
- if (vNode.getComputedStylePropertyValue('filter') && vNode.getComputedStylePropertyValue('filter') !== 'none') {
21386
+ var filter = vNode.getComputedStylePropertyValue('filter');
21387
+ if (filter && filter !== 'none') {
20973
21388
  return true;
20974
21389
  }
20975
- if (vNode.getComputedStylePropertyValue('perspective') && vNode.getComputedStylePropertyValue('perspective') !== 'none') {
21390
+ var perspective = vNode.getComputedStylePropertyValue('perspective');
21391
+ if (perspective && perspective !== 'none') {
20976
21392
  return true;
20977
21393
  }
20978
- if (vNode.getComputedStylePropertyValue('clip-path') && vNode.getComputedStylePropertyValue('clip-path') !== 'none') {
21394
+ var clipPath = vNode.getComputedStylePropertyValue('clip-path');
21395
+ if (clipPath && clipPath !== 'none') {
20979
21396
  return true;
20980
21397
  }
20981
21398
  var mask = vNode.getComputedStylePropertyValue('-webkit-mask') || vNode.getComputedStylePropertyValue('mask') || 'none';
@@ -20993,7 +21410,8 @@
20993
21410
  if (vNode.getComputedStylePropertyValue('isolation') === 'isolate') {
20994
21411
  return true;
20995
21412
  }
20996
- if (vNode.getComputedStylePropertyValue('will-change') === 'transform' || vNode.getComputedStylePropertyValue('will-change') === 'opacity') {
21413
+ var willChange = vNode.getComputedStylePropertyValue('will-change');
21414
+ if (willChange === 'transform' || willChange === 'opacity') {
20997
21415
  return true;
20998
21416
  }
20999
21417
  if (vNode.getComputedStylePropertyValue('-webkit-overflow-scrolling') === 'touch') {
@@ -21003,8 +21421,8 @@
21003
21421
  if ([ 'layout', 'paint', 'strict', 'content' ].includes(contain)) {
21004
21422
  return true;
21005
21423
  }
21006
- if (vNode.getComputedStylePropertyValue('z-index') !== 'auto' && vNode.parent) {
21007
- var parentDsiplay = vNode.parent.getComputedStylePropertyValue('display');
21424
+ if (zIndex !== 'auto' && parentVNode) {
21425
+ var parentDsiplay = parentVNode.getComputedStylePropertyValue('display');
21008
21426
  if ([ 'flex', 'inline-flex', 'inline flex', 'grid', 'inline-grid', 'inline grid' ].includes(parentDsiplay)) {
21009
21427
  return true;
21010
21428
  }
@@ -21019,19 +21437,11 @@
21019
21437
  if (vNode.getComputedStylePropertyValue('float') !== 'none') {
21020
21438
  return 1;
21021
21439
  }
21022
- if (vNode.getComputedStylePropertyValue('position') === 'static') {
21023
- return 0;
21024
- }
21440
+ return 0;
21025
21441
  }
21026
21442
  return 3;
21027
21443
  }
21028
21444
  function visuallySort(a, b) {
21029
- if (a.actualNode.nodeName.toLowerCase() === 'html') {
21030
- return 1;
21031
- }
21032
- if (b.actualNode.nodeName.toLowerCase() === 'html') {
21033
- return -1;
21034
- }
21035
21445
  for (var i = 0; i < a._stackingOrder.length; i++) {
21036
21446
  if (typeof b._stackingOrder[i] === 'undefined') {
21037
21447
  return -1;
@@ -21043,9 +21453,33 @@
21043
21453
  return -1;
21044
21454
  }
21045
21455
  }
21046
- var docPosition = a.actualNode.compareDocumentPosition(b.actualNode);
21047
- var DOMOrder = docPosition & 4 ? 1 : -1;
21048
- var isDescendant = docPosition & 8 || docPosition & 16;
21456
+ var aNode = a.actualNode;
21457
+ var bNode = b.actualNode;
21458
+ if (aNode.getRootNode && aNode.getRootNode() !== bNode.getRootNode()) {
21459
+ var boundaries = [];
21460
+ while (aNode) {
21461
+ boundaries.push({
21462
+ root: aNode.getRootNode(),
21463
+ node: aNode
21464
+ });
21465
+ aNode = aNode.getRootNode().host;
21466
+ }
21467
+ while (bNode && !boundaries.find(function(boundary) {
21468
+ return boundary.root === bNode.getRootNode();
21469
+ })) {
21470
+ bNode = bNode.getRootNode().host;
21471
+ }
21472
+ aNode = boundaries.find(function(boundary) {
21473
+ return boundary.root === bNode.getRootNode();
21474
+ }).node;
21475
+ if (aNode === bNode) {
21476
+ return a.actualNode.getRootNode() !== aNode.getRootNode() ? -1 : 1;
21477
+ }
21478
+ }
21479
+ var _window$Node = window.Node, DOCUMENT_POSITION_FOLLOWING = _window$Node.DOCUMENT_POSITION_FOLLOWING, DOCUMENT_POSITION_CONTAINS = _window$Node.DOCUMENT_POSITION_CONTAINS, DOCUMENT_POSITION_CONTAINED_BY = _window$Node.DOCUMENT_POSITION_CONTAINED_BY;
21480
+ var docPosition = aNode.compareDocumentPosition(bNode);
21481
+ var DOMOrder = docPosition & DOCUMENT_POSITION_FOLLOWING ? 1 : -1;
21482
+ var isDescendant = docPosition & DOCUMENT_POSITION_CONTAINS || docPosition & DOCUMENT_POSITION_CONTAINED_BY;
21049
21483
  var aPosition = getPositionOrder(a);
21050
21484
  var bPosition = getPositionOrder(b);
21051
21485
  if (aPosition === bPosition || isDescendant) {
@@ -21053,50 +21487,46 @@
21053
21487
  }
21054
21488
  return bPosition - aPosition;
21055
21489
  }
21056
- function getStackingOrder(vNode) {
21057
- var stackingOrder = vNode.parent ? vNode.parent._stackingOrder.slice() : [ 0 ];
21058
- if (vNode.getComputedStylePropertyValue('z-index') !== 'auto') {
21059
- stackingOrder[stackingOrder.length - 1] = parseInt(vNode.getComputedStylePropertyValue('z-index'));
21490
+ function getStackingOrder(vNode, parentVNode) {
21491
+ var stackingOrder = parentVNode._stackingOrder.slice();
21492
+ var zIndex = vNode.getComputedStylePropertyValue('z-index');
21493
+ if (zIndex !== 'auto') {
21494
+ stackingOrder[stackingOrder.length - 1] = parseInt(zIndex);
21060
21495
  }
21061
- if (isStackingContext(vNode)) {
21496
+ if (isStackingContext(vNode, parentVNode)) {
21062
21497
  stackingOrder.push(0);
21063
21498
  }
21064
21499
  return stackingOrder;
21065
21500
  }
21066
- function findScrollRegionParent(vNode) {
21501
+ function findScrollRegionParent(vNode, parentVNode) {
21067
21502
  var scrollRegionParent = null;
21068
- var vNodeParent = vNode.parent;
21069
21503
  var checkedNodes = [ vNode ];
21070
- while (vNodeParent) {
21071
- if (vNodeParent._scrollRegionParent) {
21072
- scrollRegionParent = vNodeParent._scrollRegionParent;
21504
+ while (parentVNode) {
21505
+ if (parentVNode._scrollRegionParent) {
21506
+ scrollRegionParent = parentVNode._scrollRegionParent;
21073
21507
  break;
21074
21508
  }
21075
- if (axe.utils.getScroll(vNodeParent.actualNode)) {
21076
- scrollRegionParent = vNodeParent;
21509
+ if (axe.utils.getScroll(parentVNode.actualNode)) {
21510
+ scrollRegionParent = parentVNode;
21077
21511
  break;
21078
21512
  }
21079
- checkedNodes.push(vNodeParent);
21080
- vNodeParent = vNodeParent.parent;
21513
+ checkedNodes.push(parentVNode);
21514
+ parentVNode = axe.utils.getNodeFromTree(parentVNode.actualNode.parentElement || parentVNode.actualNode.parentNode);
21081
21515
  }
21082
21516
  checkedNodes.forEach(function(vNode) {
21083
21517
  return vNode._scrollRegionParent = scrollRegionParent;
21084
21518
  });
21085
21519
  return scrollRegionParent;
21086
21520
  }
21087
- function getDomPosition(rect, pos) {
21088
- if (pos === 'x') {
21089
- return 'x' in rect ? rect.x : rect.left;
21090
- }
21091
- return 'y' in rect ? rect.y : rect.top;
21092
- }
21093
21521
  function addNodeToGrid(grid, vNode) {
21094
21522
  vNode._grid = grid;
21095
21523
  vNode.clientRects.forEach(function(rect) {
21096
- var startRow = Math.floor(getDomPosition(rect, 'y') / gridSize);
21097
- var startCol = Math.floor(getDomPosition(rect, 'x') / gridSize);
21098
- var endRow = Math.floor((getDomPosition(rect, 'y') + rect.height) / gridSize);
21099
- var endCol = Math.floor((getDomPosition(rect, 'x') + rect.width) / gridSize);
21524
+ var x = rect.left;
21525
+ var y = rect.top;
21526
+ var startRow = y / gridSize | 0;
21527
+ var startCol = x / gridSize | 0;
21528
+ var endRow = (y + rect.height) / gridSize | 0;
21529
+ var endCol = (x + rect.width) / gridSize | 0;
21100
21530
  for (var row = startRow; row <= endRow; row++) {
21101
21531
  grid.cells[row] = grid.cells[row] || [];
21102
21532
  for (var col = startCol; col <= endCol; col++) {
@@ -21109,23 +21539,19 @@
21109
21539
  });
21110
21540
  }
21111
21541
  function createGrid() {
21112
- var rootGrid = {
21542
+ var root = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document.body;
21543
+ var rootGrid = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
21113
21544
  container: null,
21114
21545
  cells: []
21115
21546
  };
21116
- axe.utils.querySelectorAll(axe._tree[0], '*').filter(function(vNode) {
21117
- return vNode.actualNode.parentElement !== document.head;
21118
- }).forEach(function(vNode) {
21119
- if (vNode.actualNode.nodeType !== window.Node.ELEMENT_NODE) {
21120
- return;
21121
- }
21122
- vNode._stackingOrder = getStackingOrder(vNode);
21123
- var rect = vNode.boundingClientRect;
21124
- if (rect.width === 0 || rect.height === 0) {
21125
- return;
21126
- }
21127
- var scrollRegionParent = findScrollRegionParent(vNode);
21128
- var grid = scrollRegionParent ? scrollRegionParent._subGrid : rootGrid;
21547
+ var parentVNode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
21548
+ if (!parentVNode) {
21549
+ var vNode = axe.utils.getNodeFromTree(document.documentElement);
21550
+ if (!vNode) {
21551
+ vNode = new VirtualNode(document.documentElement);
21552
+ }
21553
+ vNode._stackingOrder = [ 0 ];
21554
+ addNodeToGrid(rootGrid, vNode);
21129
21555
  if (axe.utils.getScroll(vNode.actualNode)) {
21130
21556
  var subGrid = {
21131
21557
  container: vNode,
@@ -21133,42 +21559,104 @@
21133
21559
  };
21134
21560
  vNode._subGrid = subGrid;
21135
21561
  }
21136
- addNodeToGrid(grid, vNode);
21562
+ }
21563
+ var treeWalker = document.createTreeWalker(root, window.NodeFilter.SHOW_ELEMENT, null, false);
21564
+ var node = parentVNode ? treeWalker.nextNode() : treeWalker.currentNode;
21565
+ while (node) {
21566
+ var _vNode = axe.utils.getNodeFromTree(node);
21567
+ if (node.parentElement) {
21568
+ parentVNode = axe.utils.getNodeFromTree(node.parentElement);
21569
+ } else if (node.parentNode && axe.utils.getNodeFromTree(node.parentNode)) {
21570
+ parentVNode = axe.utils.getNodeFromTree(node.parentNode);
21571
+ }
21572
+ if (!_vNode) {
21573
+ _vNode = new VirtualNode(node, parentVNode);
21574
+ }
21575
+ _vNode._stackingOrder = getStackingOrder(_vNode, parentVNode);
21576
+ var scrollRegionParent = findScrollRegionParent(_vNode, parentVNode);
21577
+ var grid = scrollRegionParent ? scrollRegionParent._subGrid : rootGrid;
21578
+ if (axe.utils.getScroll(_vNode.actualNode)) {
21579
+ var _subGrid = {
21580
+ container: _vNode,
21581
+ cells: []
21582
+ };
21583
+ _vNode._subGrid = _subGrid;
21584
+ }
21585
+ var rect = _vNode.boundingClientRect;
21586
+ if (rect.width !== 0 && rect.height !== 0 && dom.isVisible(node)) {
21587
+ addNodeToGrid(grid, _vNode);
21588
+ }
21589
+ if (axe.utils.isShadowRoot(node)) {
21590
+ createGrid(node.shadowRoot, grid, _vNode);
21591
+ }
21592
+ node = treeWalker.nextNode();
21593
+ }
21594
+ }
21595
+ function getRectStack(grid, rect) {
21596
+ var recursed = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
21597
+ var x = rect.left + rect.width / 2;
21598
+ var y = rect.top + rect.height / 2;
21599
+ var row = y / gridSize | 0;
21600
+ var col = x / gridSize | 0;
21601
+ var stack = grid.cells[row][col].filter(function(gridCellNode) {
21602
+ return gridCellNode.clientRects.find(function(clientRect) {
21603
+ var rectX = clientRect.left;
21604
+ var rectY = clientRect.top;
21605
+ return x <= rectX + clientRect.width && x >= rectX && y <= rectY + clientRect.height && y >= rectY;
21606
+ });
21137
21607
  });
21608
+ var gridContainer = grid.container;
21609
+ if (gridContainer) {
21610
+ stack = getRectStack(gridContainer._grid, gridContainer.boundingClientRect, true).concat(stack);
21611
+ }
21612
+ if (!recursed) {
21613
+ stack = stack.sort(visuallySort).map(function(vNode) {
21614
+ return vNode.actualNode;
21615
+ }).concat(document.documentElement).filter(function(node, index, array) {
21616
+ return array.indexOf(node) === index;
21617
+ });
21618
+ }
21619
+ return stack;
21138
21620
  }
21139
- dom.getElementStack = function(vNode) {
21140
- var recursed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
21621
+ dom.getElementStack = function(node) {
21141
21622
  if (!axe._cache.get('gridCreated')) {
21142
21623
  createGrid();
21143
21624
  axe._cache.set('gridCreated', true);
21144
21625
  }
21626
+ var vNode = axe.utils.getNodeFromTree(node);
21145
21627
  var grid = vNode._grid;
21146
21628
  if (!grid) {
21147
21629
  return [];
21148
21630
  }
21149
- var boundingRect = vNode.boundingClientRect;
21150
- var x = getDomPosition(boundingRect, 'x') + boundingRect.width / 2;
21151
- var y = getDomPosition(boundingRect, 'y') + boundingRect.height / 2;
21152
- var row = Math.floor(y / gridSize);
21153
- var col = Math.floor(x / gridSize);
21154
- var stack = grid.cells[row][col].filter(function(gridCellNode) {
21155
- return gridCellNode.clientRects.find(function(rect) {
21156
- var pointX = x;
21157
- var pointY = y;
21158
- var rectWidth = rect.width;
21159
- var rectHeight = rect.height;
21160
- var rectX = getDomPosition(rect, 'x');
21161
- var rectY = getDomPosition(rect, 'y');
21162
- return pointX < rectX + rectWidth && pointX > rectX && pointY < rectY + rectHeight && pointY > rectY;
21163
- });
21164
- });
21165
- if (grid.container) {
21166
- stack = dom.getElementStack(grid.container, true).concat(stack);
21631
+ return getRectStack(grid, vNode.boundingClientRect);
21632
+ };
21633
+ dom.getTextElementStack = function(node) {
21634
+ if (!axe._cache.get('gridCreated')) {
21635
+ createGrid();
21636
+ axe._cache.set('gridCreated', true);
21167
21637
  }
21168
- if (!recursed) {
21169
- stack.sort(visuallySort);
21638
+ var vNode = axe.utils.getNodeFromTree(node);
21639
+ var grid = vNode._grid;
21640
+ if (!grid) {
21641
+ return [];
21170
21642
  }
21171
- return stack;
21643
+ var clientRects = [];
21644
+ Array.from(node.childNodes).forEach(function(elm) {
21645
+ if (elm.nodeType === 3 && axe.commons.text.sanitize(elm.textContent) !== '') {
21646
+ var range = document.createRange();
21647
+ range.selectNodeContents(elm);
21648
+ var rects = range.getClientRects();
21649
+ for (var i = 0; i < rects.length; i++) {
21650
+ var rect = rects[i];
21651
+ if (rect.width >= 1 && rect.height >= 1) {
21652
+ clientRects.push(rect);
21653
+ }
21654
+ }
21655
+ }
21656
+ });
21657
+ return clientRects.map(function(rect) {
21658
+ return getRectStack(grid, rect);
21659
+ });
21172
21660
  };
21173
21661
  dom.getRootNode = axe.utils.getRootNode;
21174
21662
  dom.getScrollOffset = function(element) {
@@ -21222,8 +21710,8 @@
21222
21710
  var hiddenTextElms = [ 'HEAD', 'TITLE', 'TEMPLATE', 'SCRIPT', 'STYLE', 'IFRAME', 'OBJECT', 'VIDEO', 'AUDIO', 'NOSCRIPT' ];
21223
21711
  function hasChildTextNodes(elm) {
21224
21712
  if (!hiddenTextElms.includes(elm.actualNode.nodeName.toUpperCase())) {
21225
- return elm.children.some(function(_ref35) {
21226
- var actualNode = _ref35.actualNode;
21713
+ return elm.children.some(function(_ref38) {
21714
+ var actualNode = _ref38.actualNode;
21227
21715
  return actualNode.nodeType === 3 && actualNode.nodeValue.trim();
21228
21716
  });
21229
21717
  }
@@ -21282,9 +21770,12 @@
21282
21770
 
21283
21771
  case 'TEXTAREA':
21284
21772
  case 'SELECT':
21285
- case 'DETAILS':
21773
+ case 'SUMMARY':
21286
21774
  case 'BUTTON':
21287
21775
  return true;
21776
+
21777
+ case 'DETAILS':
21778
+ return !el.querySelector('summary');
21288
21779
  }
21289
21780
  return false;
21290
21781
  };
@@ -21400,6 +21891,66 @@
21400
21891
  linkText = axe.commons.text.sanitize(linkText);
21401
21892
  return parentText.length > linkText.length;
21402
21893
  };
21894
+ dom.isModalOpen = function isModalOpen(options) {
21895
+ options = options || {};
21896
+ var modalPercent = options.modalPercent || .75;
21897
+ if (axe._cache.get('isModalOpen')) {
21898
+ return axe._cache.get('isModalOpen');
21899
+ }
21900
+ var definiteModals = axe.utils.querySelectorAllFilter(axe._tree[0], 'dialog, [role=dialog], [aria-modal=true]', function(vNode) {
21901
+ return dom.isVisible(vNode.actualNode);
21902
+ });
21903
+ if (definiteModals.length) {
21904
+ axe._cache.set('isModalOpen', true);
21905
+ return true;
21906
+ }
21907
+ var viewport = dom.getViewportSize(window);
21908
+ var percentWidth = viewport.width * modalPercent;
21909
+ var percentHeight = viewport.height * modalPercent;
21910
+ var x = (viewport.width - percentWidth) / 2;
21911
+ var y = (viewport.height - percentHeight) / 2;
21912
+ var points = [ {
21913
+ x: x,
21914
+ y: y
21915
+ }, {
21916
+ x: viewport.width - x,
21917
+ y: y
21918
+ }, {
21919
+ x: viewport.width / 2,
21920
+ y: viewport.height / 2
21921
+ }, {
21922
+ x: x,
21923
+ y: viewport.height - y
21924
+ }, {
21925
+ x: viewport.width - x,
21926
+ y: viewport.height - y
21927
+ } ];
21928
+ var stacks = points.map(function(point) {
21929
+ return Array.from(document.elementsFromPoint(point.x, point.y));
21930
+ });
21931
+ var _loop3 = function _loop3(i) {
21932
+ var modalElement = stacks[i].find(function(elm) {
21933
+ var style = window.getComputedStyle(elm);
21934
+ return parseInt(style.width, 10) >= percentWidth && parseInt(style.height, 10) >= percentHeight && style.getPropertyValue('pointer-events') !== 'none' && (style.position === 'absolute' || style.position === 'fixed');
21935
+ });
21936
+ if (modalElement && stacks.every(function(stack) {
21937
+ return stack.includes(modalElement);
21938
+ })) {
21939
+ axe._cache.set('isModalOpen', true);
21940
+ return {
21941
+ v: true
21942
+ };
21943
+ }
21944
+ };
21945
+ for (var i = 0; i < stacks.length; i++) {
21946
+ var _ret3 = _loop3(i);
21947
+ if (_typeof(_ret3) === 'object') {
21948
+ return _ret3.v;
21949
+ }
21950
+ }
21951
+ axe._cache.set('isModalOpen', undefined);
21952
+ return undefined;
21953
+ };
21403
21954
  dom.isNode = function(element) {
21404
21955
  'use strict';
21405
21956
  return element instanceof Node;
@@ -21482,6 +22033,28 @@
21482
22033
  }
21483
22034
  return false;
21484
22035
  }
22036
+ function isAreaVisible(el, screenReader, recursed) {
22037
+ var mapEl = dom.findUp(el, 'map');
22038
+ if (!mapEl) {
22039
+ return false;
22040
+ }
22041
+ var mapElName = mapEl.getAttribute('name');
22042
+ if (!mapElName) {
22043
+ return false;
22044
+ }
22045
+ var mapElRootNode = dom.getRootNode(el);
22046
+ if (!mapElRootNode || mapElRootNode.nodeType !== 9) {
22047
+ return false;
22048
+ }
22049
+ var refs = axe.utils.querySelectorAll(axe._tree, 'img[usemap="#'.concat(axe.utils.escapeSelector(mapElName), '"]'));
22050
+ if (!refs || !refs.length) {
22051
+ return false;
22052
+ }
22053
+ return refs.some(function(_ref39) {
22054
+ var actualNode = _ref39.actualNode;
22055
+ return dom.isVisible(actualNode, screenReader, recursed);
22056
+ });
22057
+ }
21485
22058
  dom.isVisible = function(el, screenReader, recursed) {
21486
22059
  'use strict';
21487
22060
  var node = axe.utils.getNodeFromTree(el);
@@ -21500,9 +22073,12 @@
21500
22073
  return false;
21501
22074
  }
21502
22075
  var nodeName = el.nodeName.toUpperCase();
21503
- if (style.getPropertyValue('display') === 'none' || [ 'STYLE', 'SCRIPT', 'NOSCRIPT', 'TEMPLATE' ].includes(nodeName) || !screenReader && isClipped(style) || !recursed && (style.getPropertyValue('visibility') === 'hidden' || !screenReader && dom.isOffscreen(el)) || screenReader && el.getAttribute('aria-hidden') === 'true') {
22076
+ if (nodeName !== 'AREA' && style.getPropertyValue('display') === 'none' || [ 'STYLE', 'SCRIPT', 'NOSCRIPT', 'TEMPLATE' ].includes(nodeName) || !screenReader && isClipped(style) || !recursed && (style.getPropertyValue('visibility') === 'hidden' || !screenReader && dom.isOffscreen(el)) || screenReader && el.getAttribute('aria-hidden') === 'true') {
21504
22077
  return false;
21505
22078
  }
22079
+ if (nodeName === 'AREA') {
22080
+ return isAreaVisible(el, screenReader, recursed);
22081
+ }
21506
22082
  var parent = el.assignedSlot ? el.assignedSlot : el.parentNode;
21507
22083
  var isVisible = false;
21508
22084
  if (parent) {
@@ -21564,7 +22140,88 @@
21564
22140
  return stack;
21565
22141
  }, []);
21566
22142
  };
21567
- dom.visuallyContains = function(node, parent) {
22143
+ dom.urlPropsFromAttribute = function urlPropsFromAttribute(node, attribute) {
22144
+ var value = node[attribute];
22145
+ if (!value) {
22146
+ return undefined;
22147
+ }
22148
+ var nodeName = node.nodeName.toUpperCase();
22149
+ var parser = node;
22150
+ if (![ 'A', 'AREA' ].includes(nodeName)) {
22151
+ parser = document.createElement('a');
22152
+ parser.href = value;
22153
+ }
22154
+ var protocol = [ 'https:', 'ftps:' ].includes(parser.protocol) ? parser.protocol.replace(/s:$/, ':') : parser.protocol;
22155
+ var _getPathnameOrFilenam = getPathnameOrFilename(parser.pathname), pathname = _getPathnameOrFilenam.pathname, filename = _getPathnameOrFilenam.filename;
22156
+ return {
22157
+ protocol: protocol,
22158
+ hostname: parser.hostname,
22159
+ port: getPort(parser.port),
22160
+ pathname: /\/$/.test(pathname) ? pathname : ''.concat(pathname, '/'),
22161
+ search: getSearchPairs(parser.search),
22162
+ hash: getHashRoute(parser.hash),
22163
+ filename: filename
22164
+ };
22165
+ };
22166
+ function getPort(port) {
22167
+ var excludePorts = [ '443', '80' ];
22168
+ return !excludePorts.includes(port) ? port : '';
22169
+ }
22170
+ function getPathnameOrFilename(pathname) {
22171
+ var filename = pathname.split('/').pop();
22172
+ if (!filename || filename.indexOf('.') === -1) {
22173
+ return {
22174
+ pathname: pathname,
22175
+ filename: ''
22176
+ };
22177
+ }
22178
+ return {
22179
+ pathname: pathname.replace(filename, ''),
22180
+ filename: /index./.test(filename) ? '' : filename
22181
+ };
22182
+ }
22183
+ function getSearchPairs(searchStr) {
22184
+ var query = {};
22185
+ if (!searchStr || !searchStr.length) {
22186
+ return query;
22187
+ }
22188
+ var pairs = searchStr.substring(1).split('&');
22189
+ if (!pairs || !pairs.length) {
22190
+ return query;
22191
+ }
22192
+ for (var index = 0; index < pairs.length; index++) {
22193
+ var pair = pairs[index];
22194
+ var _pair$split = pair.split('='), _pair$split2 = _slicedToArray(_pair$split, 2), key = _pair$split2[0], _pair$split2$ = _pair$split2[1], value = _pair$split2$ === void 0 ? '' : _pair$split2$;
22195
+ query[decodeURIComponent(key)] = decodeURIComponent(value);
22196
+ }
22197
+ return query;
22198
+ }
22199
+ function getHashRoute(hash) {
22200
+ if (!hash) {
22201
+ return '';
22202
+ }
22203
+ var hashRegex = /#!?\/?/g;
22204
+ var hasMatch = hash.match(hashRegex);
22205
+ if (!hasMatch) {
22206
+ return '';
22207
+ }
22208
+ var _hasMatch = _slicedToArray(hasMatch, 1), matchedStr = _hasMatch[0];
22209
+ if (matchedStr === '#') {
22210
+ return '';
22211
+ }
22212
+ return hash;
22213
+ }
22214
+ function getScrollAncestor(node) {
22215
+ var vNode = axe.utils.getNodeFromTree(node);
22216
+ var ancestor = vNode.parent;
22217
+ while (ancestor) {
22218
+ if (axe.utils.getScroll(ancestor.actualNode)) {
22219
+ return ancestor.actualNode;
22220
+ }
22221
+ ancestor = ancestor.parent;
22222
+ }
22223
+ }
22224
+ function contains(node, parent) {
21568
22225
  var rectBound = node.getBoundingClientRect();
21569
22226
  var margin = .01;
21570
22227
  var rect = {
@@ -21593,6 +22250,17 @@
21593
22250
  return style.overflow === 'scroll' || style.overflow === 'auto' || style.overflow === 'hidden' || parent instanceof HTMLBodyElement || parent instanceof HTMLHtmlElement;
21594
22251
  }
21595
22252
  return true;
22253
+ }
22254
+ dom.visuallyContains = function visuallyContains(node, parent) {
22255
+ var parentScrollAncestor = getScrollAncestor(parent);
22256
+ do {
22257
+ var nextScrollAncestor = getScrollAncestor(node);
22258
+ if (nextScrollAncestor === parentScrollAncestor || nextScrollAncestor === parent) {
22259
+ return contains(node, parent);
22260
+ }
22261
+ node = nextScrollAncestor;
22262
+ } while (node);
22263
+ return false;
21596
22264
  };
21597
22265
  dom.visuallyOverlaps = function(rect, parent) {
21598
22266
  var parentRect = parent.getBoundingClientRect();
@@ -21647,25 +22315,29 @@
21647
22315
  var nodeName = node.nodeName.toUpperCase();
21648
22316
  return nodeName === 'TEXTAREA' || nodeName === 'INPUT' && !nonTextInputTypes.includes(node.type);
21649
22317
  };
21650
- matches.attributes = function matchesAttributes(node, matcher) {
21651
- node = node.actualNode || node;
22318
+ matches.attributes = function matchesAttributes(vNode, matcher) {
22319
+ if (!(vNode instanceof axe.AbstractVirtualNode)) {
22320
+ vNode = axe.utils.getNodeFromTree(vNode);
22321
+ }
21652
22322
  return matches.fromFunction(function(attrName) {
21653
- return node.getAttribute(attrName);
22323
+ return vNode.attr(attrName);
21654
22324
  }, matcher);
21655
22325
  };
21656
22326
  matches.condition = function(arg, condition) {
21657
22327
  return !!condition(arg);
21658
22328
  };
21659
22329
  var matchers = [ 'nodeName', 'attributes', 'properties', 'condition' ];
21660
- matches.fromDefinition = function matchFromDefinition(node, definition) {
21661
- node = node.actualNode || node;
22330
+ matches.fromDefinition = function matchFromDefinition(vNode, definition) {
22331
+ if (!(vNode instanceof axe.AbstractVirtualNode)) {
22332
+ vNode = axe.utils.getNodeFromTree(vNode);
22333
+ }
21662
22334
  if (Array.isArray(definition)) {
21663
22335
  return definition.some(function(definitionItem) {
21664
- return matches(node, definitionItem);
22336
+ return matches(vNode, definitionItem);
21665
22337
  });
21666
22338
  }
21667
22339
  if (typeof definition === 'string') {
21668
- return axe.utils.matchesSelector(node, definition);
22340
+ return axe.utils.matches(vNode, definition);
21669
22341
  }
21670
22342
  return Object.keys(definition).every(function(matcherName) {
21671
22343
  if (!matchers.includes(matcherName)) {
@@ -21673,7 +22345,7 @@
21673
22345
  }
21674
22346
  var matchMethod = matches[matcherName];
21675
22347
  var matcher = definition[matcherName];
21676
- return matchMethod(node, matcher);
22348
+ return matchMethod(vNode, matcher);
21677
22349
  });
21678
22350
  };
21679
22351
  matches.fromFunction = function matchFromFunction(getValue, matcher) {
@@ -21698,28 +22370,19 @@
21698
22370
  }
21699
22371
  return matcher === someString;
21700
22372
  };
21701
- var isXHTMLGlobal;
21702
- matches.nodeName = function matchNodeName(node, matcher) {
21703
- var _ref36 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, isXHTML = _ref36.isXHTML;
21704
- node = node.actualNode || node;
21705
- if (typeof isXHTML === 'undefined') {
21706
- if (typeof matcher === 'string') {
21707
- return axe.utils.matchesSelector(node, matcher);
21708
- }
21709
- if (typeof isXHTMLGlobal === 'undefined') {
21710
- isXHTMLGlobal = axe.utils.isXHTML(node.ownerDocument);
21711
- }
21712
- isXHTML = isXHTMLGlobal;
22373
+ matches.nodeName = function matchNodeName(vNode, matcher) {
22374
+ if (!(vNode instanceof axe.AbstractVirtualNode)) {
22375
+ vNode = axe.utils.getNodeFromTree(vNode);
21713
22376
  }
21714
- var nodeName = isXHTML ? node.nodeName : node.nodeName.toLowerCase();
21715
- return matches.fromPrimative(nodeName, matcher);
22377
+ return matches.fromPrimative(vNode.props.nodeName, matcher);
21716
22378
  };
21717
- matches.properties = function matchesProperties(node, matcher) {
21718
- node = node.actualNode || node;
21719
- var out = matches.fromFunction(function(propName) {
21720
- return node[propName];
22379
+ matches.properties = function matchesProperties(vNode, matcher) {
22380
+ if (!(vNode instanceof axe.AbstractVirtualNode)) {
22381
+ vNode = axe.utils.getNodeFromTree(vNode);
22382
+ }
22383
+ return matches.fromFunction(function(propName) {
22384
+ return vNode.props[propName];
21721
22385
  }, matcher);
21722
- return out;
21723
22386
  };
21724
22387
  table.getAllCells = function(tableElm) {
21725
22388
  var rowIndex, cellIndex, rowLength, cellLength;
@@ -22061,15 +22724,15 @@
22061
22724
  }
22062
22725
  return accName;
22063
22726
  };
22064
- function textNodeContent(_ref37) {
22065
- var actualNode = _ref37.actualNode;
22727
+ function textNodeContent(_ref40) {
22728
+ var actualNode = _ref40.actualNode;
22066
22729
  if (actualNode.nodeType !== 3) {
22067
22730
  return '';
22068
22731
  }
22069
22732
  return actualNode.textContent;
22070
22733
  }
22071
- function shouldIgnoreHidden(_ref38, context) {
22072
- var actualNode = _ref38.actualNode;
22734
+ function shouldIgnoreHidden(_ref41, context) {
22735
+ var actualNode = _ref41.actualNode;
22073
22736
  if (actualNode.nodeType !== 1 || context.includeHidden) {
22074
22737
  return false;
22075
22738
  }
@@ -22297,7 +22960,7 @@
22297
22960
  };
22298
22961
  text.autocomplete = autocomplete;
22299
22962
  text.isValidAutocomplete = function isValidAutocomplete(autocomplete) {
22300
- var _ref39 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref39$looseTyped = _ref39.looseTyped, looseTyped = _ref39$looseTyped === void 0 ? false : _ref39$looseTyped, _ref39$stateTerms = _ref39.stateTerms, stateTerms = _ref39$stateTerms === void 0 ? [] : _ref39$stateTerms, _ref39$locations = _ref39.locations, locations = _ref39$locations === void 0 ? [] : _ref39$locations, _ref39$qualifiers = _ref39.qualifiers, qualifiers = _ref39$qualifiers === void 0 ? [] : _ref39$qualifiers, _ref39$standaloneTerm = _ref39.standaloneTerms, standaloneTerms = _ref39$standaloneTerm === void 0 ? [] : _ref39$standaloneTerm, _ref39$qualifiedTerms = _ref39.qualifiedTerms, qualifiedTerms = _ref39$qualifiedTerms === void 0 ? [] : _ref39$qualifiedTerms;
22963
+ var _ref42 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref42$looseTyped = _ref42.looseTyped, looseTyped = _ref42$looseTyped === void 0 ? false : _ref42$looseTyped, _ref42$stateTerms = _ref42.stateTerms, stateTerms = _ref42$stateTerms === void 0 ? [] : _ref42$stateTerms, _ref42$locations = _ref42.locations, locations = _ref42$locations === void 0 ? [] : _ref42$locations, _ref42$qualifiers = _ref42.qualifiers, qualifiers = _ref42$qualifiers === void 0 ? [] : _ref42$qualifiers, _ref42$standaloneTerm = _ref42.standaloneTerms, standaloneTerms = _ref42$standaloneTerm === void 0 ? [] : _ref42$standaloneTerm, _ref42$qualifiedTerms = _ref42.qualifiedTerms, qualifiedTerms = _ref42$qualifiedTerms === void 0 ? [] : _ref42$qualifiedTerms;
22301
22964
  autocomplete = autocomplete.toLowerCase().trim();
22302
22965
  stateTerms = stateTerms.concat(text.autocomplete.stateTerms);
22303
22966
  if (stateTerms.includes(autocomplete) || autocomplete === '') {
@@ -22353,8 +23016,8 @@
22353
23016
  return text !== '';
22354
23017
  }).join(' ');
22355
23018
  };
22356
- function getExplicitLabels(_ref40) {
22357
- var actualNode = _ref40.actualNode;
23019
+ function getExplicitLabels(_ref43) {
23020
+ var actualNode = _ref43.actualNode;
22358
23021
  if (!actualNode.id) {
22359
23022
  return [];
22360
23023
  }
@@ -22469,8 +23132,8 @@
22469
23132
  };
22470
23133
  function findTextMethods(virtualNode) {
22471
23134
  var nativeElementType = text.nativeElementType, nativeTextMethods = text.nativeTextMethods;
22472
- var nativeType = nativeElementType.find(function(_ref41) {
22473
- var matches = _ref41.matches;
23135
+ var nativeType = nativeElementType.find(function(_ref44) {
23136
+ var matches = _ref44.matches;
22474
23137
  return axe.commons.matches(virtualNode, matches);
22475
23138
  });
22476
23139
  var methods = nativeType ? [].concat(nativeType.namingMethods) : [];
@@ -22485,12 +23148,12 @@
22485
23148
  button: ''
22486
23149
  };
22487
23150
  text.nativeTextMethods = {
22488
- valueText: function valueText(_ref42) {
22489
- var actualNode = _ref42.actualNode;
23151
+ valueText: function valueText(_ref45) {
23152
+ var actualNode = _ref45.actualNode;
22490
23153
  return actualNode.value || '';
22491
23154
  },
22492
- buttonDefaultText: function buttonDefaultText(_ref43) {
22493
- var actualNode = _ref43.actualNode;
23155
+ buttonDefaultText: function buttonDefaultText(_ref46) {
23156
+ var actualNode = _ref46.actualNode;
22494
23157
  return defaultButtonValues[actualNode.type] || '';
22495
23158
  },
22496
23159
  tableCaptionText: descendantText.bind(null, 'caption'),
@@ -22511,12 +23174,12 @@
22511
23174
  return ' ';
22512
23175
  }
22513
23176
  };
22514
- function attrText(attr, _ref44) {
22515
- var actualNode = _ref44.actualNode;
23177
+ function attrText(attr, _ref47) {
23178
+ var actualNode = _ref47.actualNode;
22516
23179
  return actualNode.getAttribute(attr) || '';
22517
23180
  }
22518
- function descendantText(nodeName, _ref45, context) {
22519
- var actualNode = _ref45.actualNode;
23181
+ function descendantText(nodeName, _ref48, context) {
23182
+ var actualNode = _ref48.actualNode;
22520
23183
  nodeName = nodeName.toLowerCase();
22521
23184
  var nodeNames = [ nodeName, actualNode.nodeName.toLowerCase() ].join(',');
22522
23185
  var candidate = actualNode.querySelector(nodeNames);
@@ -22604,7 +23267,7 @@
22604
23267
  return str;
22605
23268
  };
22606
23269
  function getUnicodeNonBmpRegExp() {
22607
- return new RegExp('[' + '\u1d00-\u1d7f' + '\u1d80-\u1dbf' + '\u1dc0-\u1dff' + '\u20a0-\u20cf' + '\u20d0-\u20ff' + '\u2100-\u214f' + '\u2150-\u218f' + '\u2190-\u21ff' + '\u2200-\u22ff' + '\u2300-\u23ff' + '\u2400-\u243f' + '\u2440-\u245f' + '\u2460-\u24ff' + '\u2500-\u257f' + '\u2580-\u259f' + '\u25a0-\u25ff' + '\u2600-\u26ff' + '\u2700-\u27bf' + '\ue000-\uf8ff' + ']');
23270
+ return /[\u1D00-\u1D7F\u1D80-\u1DBF\u1DC0-\u1DFF\u20A0-\u20CF\u20D0-\u20FF\u2100-\u214F\u2150-\u218F\u2190-\u21FF\u2200-\u22FF\u2300-\u23FF\u2400-\u243F\u2440-\u245F\u2460-\u24FF\u2500-\u257F\u2580-\u259F\u25A0-\u25FF\u2600-\u26FF\u2700-\u27BF\uE000-\uF8FF]/g;
22608
23271
  }
22609
23272
  function getPunctuationRegExp() {
22610
23273
  return /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]/g;