govuk_publishing_components 21.16.3 → 21.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (230) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/component_guide/accessibility-test.js +0 -6
  3. data/app/views/govuk_publishing_components/components/docs/machine_readable_metadata.yml +7 -0
  4. data/lib/govuk_publishing_components/presenters/machine_readable/dataset_schema.rb +34 -0
  5. data/lib/govuk_publishing_components/presenters/schema_org.rb +3 -0
  6. data/lib/govuk_publishing_components/version.rb +1 -1
  7. data/node_modules/axe-core/CHANGELOG.md +166 -2
  8. data/node_modules/axe-core/CONTRIBUTING.md +5 -5
  9. data/node_modules/axe-core/README.md +4 -4
  10. data/node_modules/axe-core/axe.d.ts +27 -11
  11. data/node_modules/axe-core/axe.js +9597 -2431
  12. data/node_modules/axe-core/axe.min.js +2 -2
  13. data/node_modules/axe-core/bower.json +1 -1
  14. data/node_modules/axe-core/doc/API.md +211 -128
  15. data/node_modules/axe-core/doc/accessibility-supported.md +1 -1
  16. data/node_modules/axe-core/doc/aria-supported.md +4 -13
  17. data/node_modules/axe-core/doc/backwards-compatibility-doc.md +93 -0
  18. data/node_modules/axe-core/doc/code-submission-guidelines.md +4 -4
  19. data/node_modules/axe-core/doc/developer-guide.md +27 -13
  20. data/node_modules/axe-core/doc/examples/chrome-debugging-protocol/package.json +5 -2
  21. data/node_modules/axe-core/doc/examples/jasmine/README.md +3 -5
  22. data/node_modules/axe-core/doc/examples/jasmine/karma.conf.js +29 -0
  23. data/node_modules/axe-core/doc/examples/jasmine/package.json +6 -5
  24. data/node_modules/axe-core/doc/examples/jest_react/README.md +1 -1
  25. data/node_modules/axe-core/doc/examples/jest_react/link.test.js +3 -3
  26. data/node_modules/axe-core/doc/examples/jest_react/package.json +9 -9
  27. data/node_modules/axe-core/doc/examples/jsdom/package.json +15 -0
  28. data/node_modules/axe-core/doc/examples/mocha/README.md +5 -7
  29. data/node_modules/axe-core/doc/examples/mocha/karma.conf.js +29 -0
  30. data/node_modules/axe-core/doc/examples/mocha/package.json +7 -6
  31. data/node_modules/axe-core/doc/examples/phantomjs/README.md +3 -3
  32. data/node_modules/axe-core/doc/examples/phantomjs/axe-phantom.js +4 -2
  33. data/node_modules/axe-core/doc/examples/phantomjs/package.json +3 -3
  34. data/node_modules/axe-core/doc/examples/puppeteer/package.json +5 -2
  35. data/node_modules/axe-core/doc/examples/qunit/README.md +2 -2
  36. data/node_modules/axe-core/doc/examples/qunit/package.json +2 -2
  37. data/node_modules/axe-core/doc/examples/test-examples.js +32 -0
  38. data/node_modules/axe-core/doc/plugins.md +10 -10
  39. data/node_modules/axe-core/doc/projects.md +12 -8
  40. data/node_modules/axe-core/doc/rule-descriptions.md +87 -79
  41. data/node_modules/axe-core/doc/rule-development.md +30 -2
  42. data/node_modules/axe-core/lib/checks/aria/allowed-attr.js +1 -1
  43. data/node_modules/axe-core/lib/checks/aria/aria-roledescription.js +14 -0
  44. data/node_modules/axe-core/lib/checks/aria/aria-roledescription.json +23 -0
  45. data/node_modules/axe-core/lib/checks/aria/no-implicit-explicit-label.js +21 -0
  46. data/node_modules/axe-core/lib/checks/aria/no-implicit-explicit-label.json +11 -0
  47. data/node_modules/axe-core/lib/checks/aria/required-attr.js +32 -7
  48. data/node_modules/axe-core/lib/checks/aria/required-children.js +40 -14
  49. data/node_modules/axe-core/lib/checks/aria/required-children.json +12 -1
  50. data/node_modules/axe-core/lib/checks/aria/required-parent.js +1 -1
  51. data/node_modules/axe-core/lib/checks/aria/unsupportedattr.js +1 -1
  52. data/node_modules/axe-core/lib/checks/aria/valid-attr-value.js +50 -17
  53. data/node_modules/axe-core/lib/checks/aria/valid-attr-value.json +2 -1
  54. data/node_modules/axe-core/lib/checks/aria/valid-attr.js +1 -1
  55. data/node_modules/axe-core/lib/checks/color/color-contrast.js +2 -2
  56. data/node_modules/axe-core/lib/checks/forms/autocomplete-appropriate.js +4 -4
  57. data/node_modules/axe-core/lib/checks/forms/autocomplete-valid.js +1 -1
  58. data/node_modules/axe-core/lib/checks/forms/fieldset.json +1 -0
  59. data/node_modules/axe-core/lib/checks/forms/group-labelledby.json +1 -0
  60. data/node_modules/axe-core/lib/checks/keyboard/focusable-content.js +16 -0
  61. data/node_modules/axe-core/lib/checks/keyboard/focusable-content.json +11 -0
  62. data/node_modules/axe-core/lib/checks/keyboard/focusable-element.js +12 -0
  63. data/node_modules/axe-core/lib/checks/keyboard/focusable-element.json +11 -0
  64. data/node_modules/axe-core/lib/checks/keyboard/tabindex.js +6 -1
  65. data/node_modules/axe-core/lib/checks/label/alt-space-value.js +3 -2
  66. data/node_modules/axe-core/lib/checks/label/duplicate-img-label.js +18 -15
  67. data/node_modules/axe-core/lib/checks/label/label-content-name-mismatch.js +13 -3
  68. data/node_modules/axe-core/lib/checks/label/label-content-name-mismatch.json +4 -0
  69. data/node_modules/axe-core/lib/checks/label/multiple-label.js +22 -12
  70. data/node_modules/axe-core/lib/checks/label/multiple-label.json +1 -1
  71. data/node_modules/axe-core/lib/checks/landmarks/landmark-is-unique-after.js +23 -0
  72. data/node_modules/axe-core/lib/checks/landmarks/landmark-is-unique.js +7 -0
  73. data/node_modules/axe-core/lib/checks/landmarks/landmark-is-unique.json +12 -0
  74. data/node_modules/axe-core/lib/checks/lists/listitem.js +1 -0
  75. data/node_modules/axe-core/lib/checks/lists/listitem.json +1 -1
  76. data/node_modules/axe-core/lib/checks/lists/only-listitems.js +0 -4
  77. data/node_modules/axe-core/lib/checks/mobile/css-orientation-lock.js +8 -6
  78. data/node_modules/axe-core/lib/checks/navigation/region.js +2 -19
  79. data/node_modules/axe-core/lib/checks/shared/avoid-inline-spacing.js +18 -0
  80. data/node_modules/axe-core/lib/checks/shared/avoid-inline-spacing.json +11 -0
  81. data/node_modules/axe-core/lib/checks/shared/exists.js +1 -1
  82. data/node_modules/axe-core/lib/checks/shared/exists.json +1 -1
  83. data/node_modules/axe-core/lib/checks/shared/has-alt.js +6 -4
  84. data/node_modules/axe-core/lib/checks/shared/non-empty-alt.js +1 -1
  85. data/node_modules/axe-core/lib/checks/tables/caption-faked.json +1 -1
  86. data/node_modules/axe-core/lib/checks/tables/td-has-header.js +5 -4
  87. data/node_modules/axe-core/lib/checks/tables/th-has-data-cells.js +19 -29
  88. data/node_modules/axe-core/lib/commons/aria/get-owned-virtual.js +1 -1
  89. data/node_modules/axe-core/lib/commons/aria/index.js +50 -46
  90. data/node_modules/axe-core/lib/commons/aria/is-accessible-ref.js +41 -37
  91. data/node_modules/axe-core/lib/commons/aria/label-virtual.js +2 -2
  92. data/node_modules/axe-core/lib/commons/aria/roles.js +1 -1
  93. data/node_modules/axe-core/lib/commons/aria/validate-attr-value.js +0 -1
  94. data/node_modules/axe-core/lib/commons/color/center-point-of-rect.js +30 -0
  95. data/node_modules/axe-core/lib/commons/color/contrast.js +7 -1
  96. data/node_modules/axe-core/lib/commons/color/element-has-image.js +36 -0
  97. data/node_modules/axe-core/lib/commons/color/get-background-color.js +332 -306
  98. data/node_modules/axe-core/lib/commons/color/get-foreground-color.js +35 -6
  99. data/node_modules/axe-core/lib/commons/color/get-own-background-color.js +22 -0
  100. data/node_modules/axe-core/lib/commons/dom/find-up.js +5 -5
  101. data/node_modules/axe-core/lib/commons/dom/get-scroll-offset.js +0 -1
  102. data/node_modules/axe-core/lib/commons/dom/get-tabbable-elements.js +1 -1
  103. data/node_modules/axe-core/lib/commons/dom/has-content-virtual.js +7 -5
  104. data/node_modules/axe-core/lib/commons/dom/is-focusable.js +8 -5
  105. data/node_modules/axe-core/lib/commons/dom/is-hidden-with-css.js +15 -2
  106. data/node_modules/axe-core/lib/commons/dom/is-in-text-block.js +1 -2
  107. data/node_modules/axe-core/lib/commons/dom/is-skip-link.js +45 -0
  108. data/node_modules/axe-core/lib/commons/dom/is-visible.js +43 -17
  109. data/node_modules/axe-core/lib/commons/dom/is-visual-content.js +0 -1
  110. data/node_modules/axe-core/lib/commons/dom/visually-contains.js +0 -1
  111. data/node_modules/axe-core/lib/commons/dom/visually-overlaps.js +0 -1
  112. data/node_modules/axe-core/lib/commons/forms/index.js +8 -0
  113. data/node_modules/axe-core/lib/commons/forms/is-aria-combobox.js +13 -0
  114. data/node_modules/axe-core/lib/commons/forms/is-aria-listbox.js +13 -0
  115. data/node_modules/axe-core/lib/commons/forms/is-aria-range.js +14 -0
  116. data/node_modules/axe-core/lib/commons/forms/is-aria-textbox.js +13 -0
  117. data/node_modules/axe-core/lib/commons/forms/is-native-select.js +13 -0
  118. data/node_modules/axe-core/lib/commons/forms/is-native-textbox.js +28 -0
  119. data/node_modules/axe-core/lib/commons/table/get-cell-position.js +2 -2
  120. data/node_modules/axe-core/lib/commons/table/get-headers.js +55 -11
  121. data/node_modules/axe-core/lib/commons/table/get-scope.js +1 -1
  122. data/node_modules/axe-core/lib/commons/table/is-data-table.js +0 -1
  123. data/node_modules/axe-core/lib/commons/table/to-grid.js +2 -2
  124. data/node_modules/axe-core/lib/commons/text/accessible-text-virtual.js +5 -5
  125. data/node_modules/axe-core/lib/commons/text/form-control-value.js +18 -30
  126. data/node_modules/axe-core/lib/commons/text/is-icon-ligature.js +210 -0
  127. data/node_modules/axe-core/lib/commons/text/is-valid-autocomplete.js +0 -1
  128. data/node_modules/axe-core/lib/commons/text/label-text.js +1 -1
  129. data/node_modules/axe-core/lib/commons/text/label-virtual.js +1 -1
  130. data/node_modules/axe-core/lib/commons/text/native-text-methods.js +1 -1
  131. data/node_modules/axe-core/lib/commons/text/subtree-text.js +3 -3
  132. data/node_modules/axe-core/lib/commons/text/unicode.js +15 -0
  133. data/node_modules/axe-core/lib/commons/text/visible-text-nodes.js +25 -0
  134. data/node_modules/axe-core/lib/commons/text/visible-virtual.js +1 -1
  135. data/node_modules/axe-core/lib/core/base/audit.js +90 -15
  136. data/node_modules/axe-core/lib/core/base/cache.js +33 -0
  137. data/node_modules/axe-core/lib/core/base/check.js +48 -1
  138. data/node_modules/axe-core/lib/core/base/context.js +15 -14
  139. data/node_modules/axe-core/lib/core/base/rule.js +223 -46
  140. data/node_modules/axe-core/lib/core/base/virtual-node/abstract-virtual-node.js +40 -0
  141. data/node_modules/axe-core/lib/core/base/virtual-node/serial-virtual-node.js +86 -0
  142. data/node_modules/axe-core/lib/core/base/virtual-node/virtual-node.js +85 -0
  143. data/node_modules/axe-core/lib/core/constants.js +10 -2
  144. data/node_modules/axe-core/lib/core/imports/index.js +28 -3
  145. data/node_modules/axe-core/lib/core/index.js +2 -4
  146. data/node_modules/axe-core/lib/core/public/configure.js +28 -1
  147. data/node_modules/axe-core/lib/core/public/run-rules.js +2 -0
  148. data/node_modules/axe-core/lib/core/public/run-virtual-rule.js +50 -0
  149. data/node_modules/axe-core/lib/core/public/run.js +13 -2
  150. data/node_modules/axe-core/lib/core/reporters/helpers/process-aggregate.js +1 -1
  151. data/node_modules/axe-core/lib/core/reporters/na.js +4 -0
  152. data/node_modules/axe-core/lib/core/reporters/raw-env.js +12 -0
  153. data/node_modules/axe-core/lib/core/reporters/raw.js +25 -1
  154. data/node_modules/axe-core/lib/core/utils/are-styles-set.js +4 -7
  155. data/node_modules/axe-core/lib/core/utils/assert.js +12 -0
  156. data/node_modules/axe-core/lib/core/utils/collect-results-from-frames.js +2 -2
  157. data/node_modules/axe-core/lib/core/utils/contains.js +27 -13
  158. data/node_modules/axe-core/lib/core/utils/css-parser.js +2 -0
  159. data/node_modules/axe-core/lib/core/utils/element-matches.js +5 -1
  160. data/node_modules/axe-core/lib/core/utils/escape-selector.js +1 -2
  161. data/node_modules/axe-core/lib/core/utils/flattened-tree.js +47 -61
  162. data/node_modules/axe-core/lib/core/utils/get-check-option.js +0 -1
  163. data/node_modules/axe-core/lib/core/utils/get-friendly-uri-end.js +1 -1
  164. data/node_modules/axe-core/lib/core/utils/get-node-attributes.js +21 -0
  165. data/node_modules/axe-core/lib/core/utils/get-scroll.js +39 -0
  166. data/node_modules/axe-core/lib/core/utils/get-selector.js +9 -6
  167. data/node_modules/axe-core/lib/core/utils/get-stylesheet-factory.js +51 -0
  168. data/node_modules/axe-core/lib/core/utils/get-xpath.js +0 -1
  169. data/node_modules/axe-core/lib/core/utils/is-hidden.js +16 -4
  170. data/node_modules/axe-core/lib/core/utils/is-html-element.js +5 -5
  171. data/node_modules/axe-core/lib/core/utils/is-shadow-root.js +3 -3
  172. data/node_modules/axe-core/lib/core/utils/memoize.js +17 -0
  173. data/node_modules/axe-core/lib/core/utils/parse-crossorigin-stylesheet.js +53 -0
  174. data/node_modules/axe-core/lib/core/utils/parse-sameorigin-stylesheet.js +96 -0
  175. data/node_modules/axe-core/lib/core/utils/parse-stylesheet.js +70 -0
  176. data/node_modules/axe-core/lib/core/utils/performance-timer.js +7 -2
  177. data/node_modules/axe-core/lib/core/utils/preload-cssom.js +77 -281
  178. data/node_modules/axe-core/lib/core/utils/preload.js +49 -23
  179. data/node_modules/axe-core/lib/core/utils/qsa.js +39 -50
  180. data/node_modules/axe-core/lib/core/utils/respondable.js +20 -3
  181. data/node_modules/axe-core/lib/core/utils/rule-should-run.js +0 -1
  182. data/node_modules/axe-core/lib/core/utils/scroll-state.js +12 -25
  183. data/node_modules/axe-core/lib/core/utils/select.js +12 -23
  184. data/node_modules/axe-core/lib/core/utils/uuid.js +1 -2
  185. data/node_modules/axe-core/lib/intro.stub +1 -1
  186. data/node_modules/axe-core/lib/misc/incomplete-fallback.json +1 -1
  187. data/node_modules/axe-core/lib/rules/aria-allowed-attr-matches.js +1 -1
  188. data/node_modules/axe-core/lib/rules/aria-form-field-name-matches.js +50 -0
  189. data/node_modules/axe-core/lib/rules/aria-has-attr-matches.js +1 -1
  190. data/node_modules/axe-core/lib/rules/aria-hidden-focus.json +1 -1
  191. data/node_modules/axe-core/lib/rules/aria-input-field-name.json +13 -0
  192. data/node_modules/axe-core/lib/rules/aria-roledescription.json +12 -0
  193. data/node_modules/axe-core/lib/rules/aria-toggle-field-name.json +18 -0
  194. data/node_modules/axe-core/lib/rules/autocomplete-matches.js +14 -10
  195. data/node_modules/axe-core/lib/rules/avoid-inline-spacing.json +12 -0
  196. data/node_modules/axe-core/lib/rules/button-name.json +3 -5
  197. data/node_modules/axe-core/lib/rules/checkboxgroup.json +2 -1
  198. data/node_modules/axe-core/lib/rules/color-contrast-matches.js +37 -22
  199. data/node_modules/axe-core/lib/rules/duplicate-id-active-matches.js +1 -1
  200. data/node_modules/axe-core/lib/rules/duplicate-id-misc-matches.js +2 -2
  201. data/node_modules/axe-core/lib/rules/form-field-multiple-labels.json +1 -1
  202. data/node_modules/axe-core/lib/rules/html-has-lang.json +1 -0
  203. data/node_modules/axe-core/lib/rules/image-alt.json +1 -1
  204. data/node_modules/axe-core/lib/rules/img-redundant-alt.json +3 -3
  205. data/node_modules/axe-core/lib/rules/input-button-name.json +26 -0
  206. data/node_modules/axe-core/lib/rules/landmark-unique-matches.js +41 -0
  207. data/node_modules/axe-core/lib/rules/landmark-unique.json +13 -0
  208. data/node_modules/axe-core/lib/rules/link-name.json +5 -4
  209. data/node_modules/axe-core/lib/rules/meta-refresh.json +8 -1
  210. data/node_modules/axe-core/lib/rules/radiogroup.json +2 -1
  211. data/node_modules/axe-core/lib/rules/role-img-alt.json +18 -0
  212. data/node_modules/axe-core/lib/rules/scrollable-region-focusable-matches.js +30 -0
  213. data/node_modules/axe-core/lib/rules/scrollable-region-focusable.json +12 -0
  214. data/node_modules/axe-core/lib/rules/skip-link-matches.js +1 -1
  215. data/node_modules/axe-core/lib/rules/skip-link.json +1 -1
  216. data/node_modules/axe-core/lib/rules/video-description.json +3 -1
  217. data/node_modules/axe-core/locales/de.json +1 -5
  218. data/node_modules/axe-core/locales/es.json +773 -0
  219. data/node_modules/axe-core/locales/fr.json +15 -19
  220. data/node_modules/axe-core/locales/ja.json +65 -11
  221. data/node_modules/axe-core/locales/ko.json +777 -0
  222. data/node_modules/axe-core/locales/nl.json +35 -35
  223. data/node_modules/axe-core/locales/pt_BR.json +773 -0
  224. data/node_modules/axe-core/package.json +56 -52
  225. data/node_modules/axe-core/sri-history.json +20 -0
  226. data/node_modules/axe-core/typings/axe-core/axe-core-tests.ts +5 -15
  227. data/node_modules/govuk-frontend/package.json +10 -10
  228. metadata +62 -4
  229. data/node_modules/axe-core/doc/axelogo2018.png +0 -0
  230. data/node_modules/axe-core/lib/rules/role-not-button-matches.js +0 -1
@@ -74,7 +74,6 @@ text.isValidAutocomplete = function isValidAutocomplete(
74
74
  qualifiedTerms = []
75
75
  } = {}
76
76
  ) {
77
- /*eslint max-statements: ["error", 23] */
78
77
  autocomplete = autocomplete.toLowerCase().trim();
79
78
  stateTerms = stateTerms.concat(text.autocomplete.stateTerms);
80
79
  if (stateTerms.includes(autocomplete) || autocomplete === '') {
@@ -9,7 +9,7 @@
9
9
  * @return {String} Label text
10
10
  */
11
11
  text.labelText = function labelText(virtualNode, context = {}) {
12
- const { alreadyProcessed } = text.accessibleTextVirtual
12
+ const { alreadyProcessed } = text.accessibleTextVirtual;
13
13
  if (
14
14
  context.inControlContext ||
15
15
  context.inLabelledByContext ||
@@ -48,6 +48,6 @@ text.labelVirtual = function(node) {
48
48
  * @return {Mixed} String of visible text, or `null` if no label is found
49
49
  */
50
50
  text.label = function(node) {
51
- node = axe.utils.getNodeFromTree(axe._tree[0], node);
51
+ node = axe.utils.getNodeFromTree(node);
52
52
  return text.labelVirtual(node);
53
53
  };
@@ -95,7 +95,7 @@ text.nativeTextMethods = {
95
95
  * @return {String} Returns ` `
96
96
  */
97
97
  singleSpace: function singleSpace() {
98
- return ' '
98
+ return ' ';
99
99
  }
100
100
  };
101
101
 
@@ -8,11 +8,11 @@
8
8
  * @return {String} Accessible text
9
9
  */
10
10
  text.subtreeText = function subtreeText(virtualNode, context = {}) {
11
- const { alreadyProcessed } = text.accessibleTextVirtual
11
+ const { alreadyProcessed } = text.accessibleTextVirtual;
12
12
  context.startNode = context.startNode || virtualNode;
13
13
  const { strict } = context;
14
14
  if (
15
- alreadyProcessed(virtualNode, context ) ||
15
+ alreadyProcessed(virtualNode, context) ||
16
16
  !aria.namedFromContents(virtualNode, { strict })
17
17
  ) {
18
18
  return '';
@@ -72,7 +72,7 @@ function appendAccessibleText(contentText, virtualNode, context) {
72
72
  const nodeName = virtualNode.actualNode.nodeName.toUpperCase();
73
73
  let contentTextAdd = text.accessibleTextVirtual(virtualNode, context);
74
74
  if (!contentTextAdd) {
75
- return contentText
75
+ return contentText;
76
76
  }
77
77
 
78
78
  if (!phrasingElements.includes(nodeName)) {
@@ -48,6 +48,7 @@ text.removeUnicode = function removeUnicode(str, options) {
48
48
  }
49
49
  if (nonBmp) {
50
50
  str = str.replace(getUnicodeNonBmpRegExp(), '');
51
+ str = str.replace(getSupplementaryPrivateUseRegExp(), '');
51
52
  }
52
53
  if (punctuations) {
53
54
  str = str.replace(getPunctuationRegExp(), '');
@@ -91,6 +92,7 @@ function getUnicodeNonBmpRegExp() {
91
92
  '\u25A0-\u25FF' + // Geometric Shapes
92
93
  '\u2600-\u26FF' + // Misc Symbols
93
94
  '\u2700-\u27BF' + // Dingbats
95
+ '\uE000-\uF8FF' + // Private Use
94
96
  ']'
95
97
  );
96
98
  }
@@ -115,3 +117,16 @@ function getPunctuationRegExp() {
115
117
  */
116
118
  return /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]/g;
117
119
  }
120
+
121
+ /**
122
+ * Get regular expression for supplementary private use
123
+ *
124
+ * @returns {RegExp}
125
+ */
126
+ function getSupplementaryPrivateUseRegExp() {
127
+ /**
128
+ * Reference: https://www.unicode.org/charts/PDF/UD800.pdf
129
+ * https://www.unicode.org/charts/PDF/UDC00.pdf
130
+ */
131
+ return /[\uDB80-\uDBBF][\uDC00-\uDFFD]/g;
132
+ }
@@ -0,0 +1,25 @@
1
+ /* global text */
2
+
3
+ /**
4
+ * Returns an array of visible text virtual nodes
5
+
6
+ * @method visibleTextNodes
7
+ * @memberof axe.commons.text
8
+ * @instance
9
+ * @param {VirtualNode} vNode
10
+ * @return {VitrualNode[]}
11
+ */
12
+ text.visibleTextNodes = function(vNode) {
13
+ const parentVisible = axe.commons.dom.isVisible(vNode.actualNode);
14
+ let nodes = [];
15
+ vNode.children.forEach(child => {
16
+ if (child.actualNode.nodeType === 3) {
17
+ if (parentVisible) {
18
+ nodes.push(child);
19
+ }
20
+ } else {
21
+ nodes = nodes.concat(text.visibleTextNodes(child));
22
+ }
23
+ });
24
+ return nodes;
25
+ };
@@ -41,6 +41,6 @@ text.visibleVirtual = function(element, screenReader, noRecursing) {
41
41
  * @return {String}
42
42
  */
43
43
  text.visible = function(element, screenReader, noRecursing) {
44
- element = axe.utils.getNodeFromTree(axe._tree[0], element);
44
+ element = axe.utils.getNodeFromTree(element);
45
45
  return text.visibleVirtual(element, screenReader, noRecursing);
46
46
  };
@@ -37,6 +37,7 @@ function Audit(audit) {
37
37
  this.brand = 'axe';
38
38
  this.application = 'axeAPI';
39
39
  this.tagExclude = ['experimental'];
40
+ this.lang = 'en';
40
41
 
41
42
  this.defaultConfig = audit;
42
43
  this._init();
@@ -60,7 +61,10 @@ Audit.prototype._setDefaultLocale = function() {
60
61
 
61
62
  const locale = {
62
63
  checks: {},
63
- rules: {}
64
+ rules: {},
65
+ failureSummaries: {},
66
+ incompleteFallbackMessage: '',
67
+ lang: this.lang
64
68
  };
65
69
 
66
70
  // XXX: unable to use `for-of` here, as doing so would
@@ -85,6 +89,16 @@ Audit.prototype._setDefaultLocale = function() {
85
89
  locale.rules[id] = { description, help };
86
90
  }
87
91
 
92
+ const failureSummaries = Object.keys(this.data.failureSummaries);
93
+ for (let i = 0; i < failureSummaries.length; i++) {
94
+ const type = failureSummaries[i];
95
+ const failureSummary = this.data.failureSummaries[type];
96
+ const { failureMessage } = failureSummary;
97
+ locale.failureSummaries[type] = { failureMessage };
98
+ }
99
+
100
+ locale.incompleteFallbackMessage = this.data.incompleteFallbackMessage;
101
+
88
102
  this._defaultLocale = locale;
89
103
  };
90
104
 
@@ -176,6 +190,34 @@ const mergeRuleLocale = (a, b) => {
176
190
  };
177
191
  };
178
192
 
193
+ /**
194
+ * Merge two failure messages (a, b), favoring `b`.
195
+ */
196
+
197
+ const mergeFailureMessage = (a, b) => {
198
+ let { failureMessage } = b;
199
+ // If the message(s) are Strings, they have not yet been run
200
+ // thru doT (which will return a Function).
201
+ if (typeof failureMessage === 'string') {
202
+ failureMessage = axe.imports.doT.compile(failureMessage);
203
+ }
204
+ return {
205
+ ...a,
206
+ failureMessage: failureMessage || a.failureMessage
207
+ };
208
+ };
209
+
210
+ /**
211
+ * Merge two incomplete fallback messages (a, b), favoring `b`.
212
+ */
213
+
214
+ const mergeFallbackMessage = (a, b) => {
215
+ if (typeof b === 'string') {
216
+ b = axe.imports.doT.compile(b);
217
+ }
218
+ return b || a;
219
+ };
220
+
179
221
  /**
180
222
  * Apply locale for the given `checks`.
181
223
  */
@@ -207,6 +249,24 @@ Audit.prototype._applyRuleLocale = function(rules) {
207
249
  }
208
250
  };
209
251
 
252
+ /**
253
+ * Apply locale for the given failureMessage
254
+ */
255
+
256
+ Audit.prototype._applyFailureSummaries = function(messages) {
257
+ const keys = Object.keys(messages);
258
+ for (let i = 0; i < keys.length; i++) {
259
+ const key = keys[i];
260
+ if (!this.data.failureSummaries[key]) {
261
+ throw new Error(`Locale provided for unknown failureMessage: "${key}"`);
262
+ }
263
+ this.data.failureSummaries[key] = mergeFailureMessage(
264
+ this.data.failureSummaries[key],
265
+ messages[key]
266
+ );
267
+ }
268
+ };
269
+
210
270
  /**
211
271
  * Apply the given `locale`.
212
272
  *
@@ -223,6 +283,21 @@ Audit.prototype.applyLocale = function(locale) {
223
283
  if (locale.rules) {
224
284
  this._applyRuleLocale(locale.rules);
225
285
  }
286
+
287
+ if (locale.failureSummaries) {
288
+ this._applyFailureSummaries(locale.failureSummaries, 'failureSummaries');
289
+ }
290
+
291
+ if (locale.incompleteFallbackMessage) {
292
+ this.data.incompleteFallbackMessage = mergeFallbackMessage(
293
+ this.data.incompleteFallbackMessage,
294
+ locale.incompleteFallbackMessage
295
+ );
296
+ }
297
+
298
+ if (locale.lang) {
299
+ this.lang = locale.lang;
300
+ }
226
301
  };
227
302
 
228
303
  /**
@@ -233,6 +308,7 @@ Audit.prototype._init = function() {
233
308
 
234
309
  axe.commons = commons = audit.commons;
235
310
 
311
+ this.lang = audit.lang || 'en';
236
312
  this.reporter = audit.reporter;
237
313
  this.commands = {};
238
314
  this.rules = [];
@@ -436,21 +512,20 @@ Audit.prototype.run = function(context, options, resolve, reject) {
436
512
  const preloaderQueue = axe.utils.queue();
437
513
  // defer preload if preload dependent rules exist
438
514
  if (runLaterRules.length) {
439
- preloaderQueue.defer((res, rej) => {
515
+ preloaderQueue.defer(resolve => {
440
516
  // handle both success and fail of preload
441
517
  // and resolve, to allow to run all checks
442
518
  axe.utils
443
519
  .preload(options)
444
- .then(preloadResults => {
445
- // pluck first item in results (because it is a queue - meh!) and resolve
446
- const assets = preloadResults[0];
447
- res(assets);
448
- })
520
+ .then(assets => resolve(assets))
449
521
  .catch(err => {
450
- // resolve as undefined, to allow rule.run to continue
522
+ /**
523
+ * Note:
524
+ * we do not reject, to allow other (non-preload) rules to `run`
525
+ * -> instead we resolve as `undefined`
526
+ */
451
527
  console.warn(`Couldn't load preload assets: `, err);
452
- const assets = undefined;
453
- res(assets);
528
+ resolve(undefined);
454
529
  });
455
530
  });
456
531
  }
@@ -526,9 +601,9 @@ Audit.prototype.after = function(results, options) {
526
601
  return results.map(function(ruleResult) {
527
602
  var rule = axe.utils.findBy(rules, 'id', ruleResult.id);
528
603
  if (!rule) {
529
- // If you see this, you're probably running the Mocha tests with the aXe extension installed
604
+ // If you see this, you're probably running the Mocha tests with the axe extension installed
530
605
  throw new Error(
531
- 'Result for unknown rule. You may be running mismatch aXe-core versions'
606
+ 'Result for unknown rule. You may be running mismatch axe-core versions'
532
607
  );
533
608
  }
534
609
 
@@ -552,7 +627,6 @@ Audit.prototype.getRule = function(ruleId) {
552
627
  * @return {Object} Validated options object
553
628
  */
554
629
  Audit.prototype.normalizeOptions = function(options) {
555
- /* eslint max-statements: ["error", 22] */
556
630
  'use strict';
557
631
  var audit = this;
558
632
 
@@ -644,7 +718,7 @@ Audit.prototype.setBranding = function(branding) {
644
718
  /**
645
719
  * For all the rules, create the helpUrl and add it to the data for that rule
646
720
  */
647
- function getHelpUrl({ brand, application }, ruleId, version) {
721
+ function getHelpUrl({ brand, application, lang }, ruleId, version) {
648
722
  return (
649
723
  axe.constants.helpUrlBase +
650
724
  brand +
@@ -653,7 +727,8 @@ function getHelpUrl({ brand, application }, ruleId, version) {
653
727
  '/' +
654
728
  ruleId +
655
729
  '?application=' +
656
- application
730
+ encodeURIComponent(application) +
731
+ (lang && lang !== 'en' ? '&lang=' + encodeURIComponent(lang) : '')
657
732
  );
658
733
  }
659
734
 
@@ -0,0 +1,33 @@
1
+ (function() {
2
+ 'use strict';
3
+ let _cache = {};
4
+
5
+ const cache = {
6
+ /**
7
+ * Set an item in the cache.
8
+ * @param {String} key - Name of the key.
9
+ * @param {*} value - Value to store.
10
+ */
11
+ set(key, value) {
12
+ _cache[key] = value;
13
+ },
14
+
15
+ /**
16
+ * Retrieve an item from the cache.
17
+ * @param {String} key - Name of the key the value was stored as.
18
+ * @returns {*} The item stored
19
+ */
20
+ get(key) {
21
+ return _cache[key];
22
+ },
23
+
24
+ /**
25
+ * Clear the cache.
26
+ */
27
+ clear() {
28
+ _cache = {};
29
+ }
30
+ };
31
+
32
+ axe._cache = cache;
33
+ })();
@@ -58,7 +58,6 @@ Check.prototype.enabled = true;
58
58
  * @param {Function} callback Function to fire when check is complete
59
59
  */
60
60
  Check.prototype.run = function(node, options, context, resolve, reject) {
61
- /* eslint max-statements: ["error", 17] */
62
61
  'use strict';
63
62
  options = options || {};
64
63
  var enabled = options.hasOwnProperty('enabled')
@@ -105,6 +104,54 @@ Check.prototype.run = function(node, options, context, resolve, reject) {
105
104
  }
106
105
  };
107
106
 
107
+ /**
108
+ * Run the check's evaluate function (call `this.evaluate(node, options)`) synchronously
109
+ * @param {HTMLElement} node The node to test
110
+ * @param {Object} options The options that override the defaults and provide additional
111
+ * information for the check
112
+ */
113
+ Check.prototype.runSync = function(node, options, context) {
114
+ options = options || {};
115
+ const { enabled = this.enabled } = options;
116
+
117
+ if (!enabled) {
118
+ return null;
119
+ }
120
+
121
+ const checkOptions = options.options || this.options;
122
+ const checkResult = new CheckResult(this);
123
+ const checkHelper = axe.utils.checkHelper(checkResult, options);
124
+
125
+ // throw error if a check is run that requires async behavior
126
+ checkHelper.async = function() {
127
+ throw new Error('Cannot run async check while in a synchronous run');
128
+ };
129
+
130
+ let result;
131
+
132
+ try {
133
+ result = this.evaluate.call(
134
+ checkHelper,
135
+ node.actualNode,
136
+ checkOptions,
137
+ node,
138
+ context
139
+ );
140
+ } catch (e) {
141
+ // In the "Audit#run: should run all the rules" test, there is no `node` here. I do
142
+ // not know if this is intentional or not, so to be safe, we guard against the
143
+ // possible reference error.
144
+ if (node && node.actualNode) {
145
+ // Save a reference to the node we errored on for futher debugging.
146
+ e.errorNode = new DqElement(node.actualNode).toJSON();
147
+ }
148
+ throw e;
149
+ }
150
+
151
+ checkResult.result = result;
152
+ return checkResult;
153
+ };
154
+
108
155
  /**
109
156
  * Override a check's settings after construction to allow for changing options
110
157
  * without having to implement the entire check
@@ -68,7 +68,6 @@ function pushUniqueFrameSelector(context, type, selectorArray) {
68
68
  * @return {Object} Normalized context spec to include both `include` and `exclude` arrays
69
69
  */
70
70
  function normalizeContext(context) {
71
- /*eslint complexity: ["error", 13] */
72
71
  'use strict';
73
72
 
74
73
  // typeof NodeList.length in PhantomJS === function
@@ -135,7 +134,7 @@ function parseSelectorArray(context, type) {
135
134
  //eslint no-loop-func:0
136
135
  result = result.concat(
137
136
  nodeList.map(node => {
138
- return axe.utils.getNodeFromTree(context.flatTree[0], node);
137
+ return axe.utils.getNodeFromTree(node);
139
138
  })
140
139
  );
141
140
  break;
@@ -147,7 +146,7 @@ function parseSelectorArray(context, type) {
147
146
  //eslint no-loop-func:0
148
147
  result = result.concat(
149
148
  nodeList.map(node => {
150
- return axe.utils.getNodeFromTree(context.flatTree[0], node);
149
+ return axe.utils.getNodeFromTree(node);
151
150
  })
152
151
  );
153
152
  }
@@ -155,7 +154,7 @@ function parseSelectorArray(context, type) {
155
154
  if (item.documentElement instanceof Node) {
156
155
  result.push(context.flatTree[0]);
157
156
  } else {
158
- result.push(axe.utils.getNodeFromTree(context.flatTree[0], item));
157
+ result.push(axe.utils.getNodeFromTree(item));
159
158
  }
160
159
  }
161
160
  }
@@ -196,17 +195,19 @@ function validateContext(context) {
196
195
  function getRootNode({ include, exclude }) {
197
196
  const selectors = Array.from(include).concat(Array.from(exclude));
198
197
  // Find the first Element.ownerDocument or Document
199
- const localDocument = selectors.reduce((result, item) => {
200
- if (result) {
201
- return result;
202
- } else if (item instanceof Element) {
203
- return item.ownerDocument;
204
- } else if (item instanceof Document) {
205
- return item;
198
+ for (var i = 0; i < selectors.length; ++i) {
199
+ var item = selectors[i];
200
+
201
+ if (item instanceof Element) {
202
+ return item.ownerDocument.documentElement;
203
+ }
204
+
205
+ if (item instanceof Document) {
206
+ return item.documentElement;
206
207
  }
207
- }, null);
208
+ }
208
209
 
209
- return (localDocument || document).documentElement;
210
+ return document.documentElement;
210
211
  }
211
212
 
212
213
  /**
@@ -230,7 +231,7 @@ function getRootNode({ include, exclude }) {
230
231
  * @param {Object} spec Configuration or "specification" object
231
232
  */
232
233
  function Context(spec) {
233
- /* eslint max-statements:["error",22], no-unused-vars:0 */
234
+ /* eslint no-unused-vars:0 */
234
235
  'use strict';
235
236
 
236
237
  this.frames = [];