govuk_publishing_components 21.16.3 → 21.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/component_guide/accessibility-test.js +0 -6
- data/app/views/govuk_publishing_components/components/docs/machine_readable_metadata.yml +7 -0
- data/lib/govuk_publishing_components/presenters/machine_readable/dataset_schema.rb +34 -0
- data/lib/govuk_publishing_components/presenters/schema_org.rb +3 -0
- data/lib/govuk_publishing_components/version.rb +1 -1
- data/node_modules/axe-core/CHANGELOG.md +166 -2
- data/node_modules/axe-core/CONTRIBUTING.md +5 -5
- data/node_modules/axe-core/README.md +4 -4
- data/node_modules/axe-core/axe.d.ts +27 -11
- data/node_modules/axe-core/axe.js +9597 -2431
- data/node_modules/axe-core/axe.min.js +2 -2
- data/node_modules/axe-core/bower.json +1 -1
- data/node_modules/axe-core/doc/API.md +211 -128
- data/node_modules/axe-core/doc/accessibility-supported.md +1 -1
- data/node_modules/axe-core/doc/aria-supported.md +4 -13
- data/node_modules/axe-core/doc/backwards-compatibility-doc.md +93 -0
- data/node_modules/axe-core/doc/code-submission-guidelines.md +4 -4
- data/node_modules/axe-core/doc/developer-guide.md +27 -13
- data/node_modules/axe-core/doc/examples/chrome-debugging-protocol/package.json +5 -2
- data/node_modules/axe-core/doc/examples/jasmine/README.md +3 -5
- data/node_modules/axe-core/doc/examples/jasmine/karma.conf.js +29 -0
- data/node_modules/axe-core/doc/examples/jasmine/package.json +6 -5
- data/node_modules/axe-core/doc/examples/jest_react/README.md +1 -1
- data/node_modules/axe-core/doc/examples/jest_react/link.test.js +3 -3
- data/node_modules/axe-core/doc/examples/jest_react/package.json +9 -9
- data/node_modules/axe-core/doc/examples/jsdom/package.json +15 -0
- data/node_modules/axe-core/doc/examples/mocha/README.md +5 -7
- data/node_modules/axe-core/doc/examples/mocha/karma.conf.js +29 -0
- data/node_modules/axe-core/doc/examples/mocha/package.json +7 -6
- data/node_modules/axe-core/doc/examples/phantomjs/README.md +3 -3
- data/node_modules/axe-core/doc/examples/phantomjs/axe-phantom.js +4 -2
- data/node_modules/axe-core/doc/examples/phantomjs/package.json +3 -3
- data/node_modules/axe-core/doc/examples/puppeteer/package.json +5 -2
- data/node_modules/axe-core/doc/examples/qunit/README.md +2 -2
- data/node_modules/axe-core/doc/examples/qunit/package.json +2 -2
- data/node_modules/axe-core/doc/examples/test-examples.js +32 -0
- data/node_modules/axe-core/doc/plugins.md +10 -10
- data/node_modules/axe-core/doc/projects.md +12 -8
- data/node_modules/axe-core/doc/rule-descriptions.md +87 -79
- data/node_modules/axe-core/doc/rule-development.md +30 -2
- data/node_modules/axe-core/lib/checks/aria/allowed-attr.js +1 -1
- data/node_modules/axe-core/lib/checks/aria/aria-roledescription.js +14 -0
- data/node_modules/axe-core/lib/checks/aria/aria-roledescription.json +23 -0
- data/node_modules/axe-core/lib/checks/aria/no-implicit-explicit-label.js +21 -0
- data/node_modules/axe-core/lib/checks/aria/no-implicit-explicit-label.json +11 -0
- data/node_modules/axe-core/lib/checks/aria/required-attr.js +32 -7
- data/node_modules/axe-core/lib/checks/aria/required-children.js +40 -14
- data/node_modules/axe-core/lib/checks/aria/required-children.json +12 -1
- data/node_modules/axe-core/lib/checks/aria/required-parent.js +1 -1
- data/node_modules/axe-core/lib/checks/aria/unsupportedattr.js +1 -1
- data/node_modules/axe-core/lib/checks/aria/valid-attr-value.js +50 -17
- data/node_modules/axe-core/lib/checks/aria/valid-attr-value.json +2 -1
- data/node_modules/axe-core/lib/checks/aria/valid-attr.js +1 -1
- data/node_modules/axe-core/lib/checks/color/color-contrast.js +2 -2
- data/node_modules/axe-core/lib/checks/forms/autocomplete-appropriate.js +4 -4
- data/node_modules/axe-core/lib/checks/forms/autocomplete-valid.js +1 -1
- data/node_modules/axe-core/lib/checks/forms/fieldset.json +1 -0
- data/node_modules/axe-core/lib/checks/forms/group-labelledby.json +1 -0
- data/node_modules/axe-core/lib/checks/keyboard/focusable-content.js +16 -0
- data/node_modules/axe-core/lib/checks/keyboard/focusable-content.json +11 -0
- data/node_modules/axe-core/lib/checks/keyboard/focusable-element.js +12 -0
- data/node_modules/axe-core/lib/checks/keyboard/focusable-element.json +11 -0
- data/node_modules/axe-core/lib/checks/keyboard/tabindex.js +6 -1
- data/node_modules/axe-core/lib/checks/label/alt-space-value.js +3 -2
- data/node_modules/axe-core/lib/checks/label/duplicate-img-label.js +18 -15
- data/node_modules/axe-core/lib/checks/label/label-content-name-mismatch.js +13 -3
- data/node_modules/axe-core/lib/checks/label/label-content-name-mismatch.json +4 -0
- data/node_modules/axe-core/lib/checks/label/multiple-label.js +22 -12
- data/node_modules/axe-core/lib/checks/label/multiple-label.json +1 -1
- data/node_modules/axe-core/lib/checks/landmarks/landmark-is-unique-after.js +23 -0
- data/node_modules/axe-core/lib/checks/landmarks/landmark-is-unique.js +7 -0
- data/node_modules/axe-core/lib/checks/landmarks/landmark-is-unique.json +12 -0
- data/node_modules/axe-core/lib/checks/lists/listitem.js +1 -0
- data/node_modules/axe-core/lib/checks/lists/listitem.json +1 -1
- data/node_modules/axe-core/lib/checks/lists/only-listitems.js +0 -4
- data/node_modules/axe-core/lib/checks/mobile/css-orientation-lock.js +8 -6
- data/node_modules/axe-core/lib/checks/navigation/region.js +2 -19
- data/node_modules/axe-core/lib/checks/shared/avoid-inline-spacing.js +18 -0
- data/node_modules/axe-core/lib/checks/shared/avoid-inline-spacing.json +11 -0
- data/node_modules/axe-core/lib/checks/shared/exists.js +1 -1
- data/node_modules/axe-core/lib/checks/shared/exists.json +1 -1
- data/node_modules/axe-core/lib/checks/shared/has-alt.js +6 -4
- data/node_modules/axe-core/lib/checks/shared/non-empty-alt.js +1 -1
- data/node_modules/axe-core/lib/checks/tables/caption-faked.json +1 -1
- data/node_modules/axe-core/lib/checks/tables/td-has-header.js +5 -4
- data/node_modules/axe-core/lib/checks/tables/th-has-data-cells.js +19 -29
- data/node_modules/axe-core/lib/commons/aria/get-owned-virtual.js +1 -1
- data/node_modules/axe-core/lib/commons/aria/index.js +50 -46
- data/node_modules/axe-core/lib/commons/aria/is-accessible-ref.js +41 -37
- data/node_modules/axe-core/lib/commons/aria/label-virtual.js +2 -2
- data/node_modules/axe-core/lib/commons/aria/roles.js +1 -1
- data/node_modules/axe-core/lib/commons/aria/validate-attr-value.js +0 -1
- data/node_modules/axe-core/lib/commons/color/center-point-of-rect.js +30 -0
- data/node_modules/axe-core/lib/commons/color/contrast.js +7 -1
- data/node_modules/axe-core/lib/commons/color/element-has-image.js +36 -0
- data/node_modules/axe-core/lib/commons/color/get-background-color.js +332 -306
- data/node_modules/axe-core/lib/commons/color/get-foreground-color.js +35 -6
- data/node_modules/axe-core/lib/commons/color/get-own-background-color.js +22 -0
- data/node_modules/axe-core/lib/commons/dom/find-up.js +5 -5
- data/node_modules/axe-core/lib/commons/dom/get-scroll-offset.js +0 -1
- data/node_modules/axe-core/lib/commons/dom/get-tabbable-elements.js +1 -1
- data/node_modules/axe-core/lib/commons/dom/has-content-virtual.js +7 -5
- data/node_modules/axe-core/lib/commons/dom/is-focusable.js +8 -5
- data/node_modules/axe-core/lib/commons/dom/is-hidden-with-css.js +15 -2
- data/node_modules/axe-core/lib/commons/dom/is-in-text-block.js +1 -2
- data/node_modules/axe-core/lib/commons/dom/is-skip-link.js +45 -0
- data/node_modules/axe-core/lib/commons/dom/is-visible.js +43 -17
- data/node_modules/axe-core/lib/commons/dom/is-visual-content.js +0 -1
- data/node_modules/axe-core/lib/commons/dom/visually-contains.js +0 -1
- data/node_modules/axe-core/lib/commons/dom/visually-overlaps.js +0 -1
- data/node_modules/axe-core/lib/commons/forms/index.js +8 -0
- data/node_modules/axe-core/lib/commons/forms/is-aria-combobox.js +13 -0
- data/node_modules/axe-core/lib/commons/forms/is-aria-listbox.js +13 -0
- data/node_modules/axe-core/lib/commons/forms/is-aria-range.js +14 -0
- data/node_modules/axe-core/lib/commons/forms/is-aria-textbox.js +13 -0
- data/node_modules/axe-core/lib/commons/forms/is-native-select.js +13 -0
- data/node_modules/axe-core/lib/commons/forms/is-native-textbox.js +28 -0
- data/node_modules/axe-core/lib/commons/table/get-cell-position.js +2 -2
- data/node_modules/axe-core/lib/commons/table/get-headers.js +55 -11
- data/node_modules/axe-core/lib/commons/table/get-scope.js +1 -1
- data/node_modules/axe-core/lib/commons/table/is-data-table.js +0 -1
- data/node_modules/axe-core/lib/commons/table/to-grid.js +2 -2
- data/node_modules/axe-core/lib/commons/text/accessible-text-virtual.js +5 -5
- data/node_modules/axe-core/lib/commons/text/form-control-value.js +18 -30
- data/node_modules/axe-core/lib/commons/text/is-icon-ligature.js +210 -0
- data/node_modules/axe-core/lib/commons/text/is-valid-autocomplete.js +0 -1
- data/node_modules/axe-core/lib/commons/text/label-text.js +1 -1
- data/node_modules/axe-core/lib/commons/text/label-virtual.js +1 -1
- data/node_modules/axe-core/lib/commons/text/native-text-methods.js +1 -1
- data/node_modules/axe-core/lib/commons/text/subtree-text.js +3 -3
- data/node_modules/axe-core/lib/commons/text/unicode.js +15 -0
- data/node_modules/axe-core/lib/commons/text/visible-text-nodes.js +25 -0
- data/node_modules/axe-core/lib/commons/text/visible-virtual.js +1 -1
- data/node_modules/axe-core/lib/core/base/audit.js +90 -15
- data/node_modules/axe-core/lib/core/base/cache.js +33 -0
- data/node_modules/axe-core/lib/core/base/check.js +48 -1
- data/node_modules/axe-core/lib/core/base/context.js +15 -14
- data/node_modules/axe-core/lib/core/base/rule.js +223 -46
- data/node_modules/axe-core/lib/core/base/virtual-node/abstract-virtual-node.js +40 -0
- data/node_modules/axe-core/lib/core/base/virtual-node/serial-virtual-node.js +86 -0
- data/node_modules/axe-core/lib/core/base/virtual-node/virtual-node.js +85 -0
- data/node_modules/axe-core/lib/core/constants.js +10 -2
- data/node_modules/axe-core/lib/core/imports/index.js +28 -3
- data/node_modules/axe-core/lib/core/index.js +2 -4
- data/node_modules/axe-core/lib/core/public/configure.js +28 -1
- data/node_modules/axe-core/lib/core/public/run-rules.js +2 -0
- data/node_modules/axe-core/lib/core/public/run-virtual-rule.js +50 -0
- data/node_modules/axe-core/lib/core/public/run.js +13 -2
- data/node_modules/axe-core/lib/core/reporters/helpers/process-aggregate.js +1 -1
- data/node_modules/axe-core/lib/core/reporters/na.js +4 -0
- data/node_modules/axe-core/lib/core/reporters/raw-env.js +12 -0
- data/node_modules/axe-core/lib/core/reporters/raw.js +25 -1
- data/node_modules/axe-core/lib/core/utils/are-styles-set.js +4 -7
- data/node_modules/axe-core/lib/core/utils/assert.js +12 -0
- data/node_modules/axe-core/lib/core/utils/collect-results-from-frames.js +2 -2
- data/node_modules/axe-core/lib/core/utils/contains.js +27 -13
- data/node_modules/axe-core/lib/core/utils/css-parser.js +2 -0
- data/node_modules/axe-core/lib/core/utils/element-matches.js +5 -1
- data/node_modules/axe-core/lib/core/utils/escape-selector.js +1 -2
- data/node_modules/axe-core/lib/core/utils/flattened-tree.js +47 -61
- data/node_modules/axe-core/lib/core/utils/get-check-option.js +0 -1
- data/node_modules/axe-core/lib/core/utils/get-friendly-uri-end.js +1 -1
- data/node_modules/axe-core/lib/core/utils/get-node-attributes.js +21 -0
- data/node_modules/axe-core/lib/core/utils/get-scroll.js +39 -0
- data/node_modules/axe-core/lib/core/utils/get-selector.js +9 -6
- data/node_modules/axe-core/lib/core/utils/get-stylesheet-factory.js +51 -0
- data/node_modules/axe-core/lib/core/utils/get-xpath.js +0 -1
- data/node_modules/axe-core/lib/core/utils/is-hidden.js +16 -4
- data/node_modules/axe-core/lib/core/utils/is-html-element.js +5 -5
- data/node_modules/axe-core/lib/core/utils/is-shadow-root.js +3 -3
- data/node_modules/axe-core/lib/core/utils/memoize.js +17 -0
- data/node_modules/axe-core/lib/core/utils/parse-crossorigin-stylesheet.js +53 -0
- data/node_modules/axe-core/lib/core/utils/parse-sameorigin-stylesheet.js +96 -0
- data/node_modules/axe-core/lib/core/utils/parse-stylesheet.js +70 -0
- data/node_modules/axe-core/lib/core/utils/performance-timer.js +7 -2
- data/node_modules/axe-core/lib/core/utils/preload-cssom.js +77 -281
- data/node_modules/axe-core/lib/core/utils/preload.js +49 -23
- data/node_modules/axe-core/lib/core/utils/qsa.js +39 -50
- data/node_modules/axe-core/lib/core/utils/respondable.js +20 -3
- data/node_modules/axe-core/lib/core/utils/rule-should-run.js +0 -1
- data/node_modules/axe-core/lib/core/utils/scroll-state.js +12 -25
- data/node_modules/axe-core/lib/core/utils/select.js +12 -23
- data/node_modules/axe-core/lib/core/utils/uuid.js +1 -2
- data/node_modules/axe-core/lib/intro.stub +1 -1
- data/node_modules/axe-core/lib/misc/incomplete-fallback.json +1 -1
- data/node_modules/axe-core/lib/rules/aria-allowed-attr-matches.js +1 -1
- data/node_modules/axe-core/lib/rules/aria-form-field-name-matches.js +50 -0
- data/node_modules/axe-core/lib/rules/aria-has-attr-matches.js +1 -1
- data/node_modules/axe-core/lib/rules/aria-hidden-focus.json +1 -1
- data/node_modules/axe-core/lib/rules/aria-input-field-name.json +13 -0
- data/node_modules/axe-core/lib/rules/aria-roledescription.json +12 -0
- data/node_modules/axe-core/lib/rules/aria-toggle-field-name.json +18 -0
- data/node_modules/axe-core/lib/rules/autocomplete-matches.js +14 -10
- data/node_modules/axe-core/lib/rules/avoid-inline-spacing.json +12 -0
- data/node_modules/axe-core/lib/rules/button-name.json +3 -5
- data/node_modules/axe-core/lib/rules/checkboxgroup.json +2 -1
- data/node_modules/axe-core/lib/rules/color-contrast-matches.js +37 -22
- data/node_modules/axe-core/lib/rules/duplicate-id-active-matches.js +1 -1
- data/node_modules/axe-core/lib/rules/duplicate-id-misc-matches.js +2 -2
- data/node_modules/axe-core/lib/rules/form-field-multiple-labels.json +1 -1
- data/node_modules/axe-core/lib/rules/html-has-lang.json +1 -0
- data/node_modules/axe-core/lib/rules/image-alt.json +1 -1
- data/node_modules/axe-core/lib/rules/img-redundant-alt.json +3 -3
- data/node_modules/axe-core/lib/rules/input-button-name.json +26 -0
- data/node_modules/axe-core/lib/rules/landmark-unique-matches.js +41 -0
- data/node_modules/axe-core/lib/rules/landmark-unique.json +13 -0
- data/node_modules/axe-core/lib/rules/link-name.json +5 -4
- data/node_modules/axe-core/lib/rules/meta-refresh.json +8 -1
- data/node_modules/axe-core/lib/rules/radiogroup.json +2 -1
- data/node_modules/axe-core/lib/rules/role-img-alt.json +18 -0
- data/node_modules/axe-core/lib/rules/scrollable-region-focusable-matches.js +30 -0
- data/node_modules/axe-core/lib/rules/scrollable-region-focusable.json +12 -0
- data/node_modules/axe-core/lib/rules/skip-link-matches.js +1 -1
- data/node_modules/axe-core/lib/rules/skip-link.json +1 -1
- data/node_modules/axe-core/lib/rules/video-description.json +3 -1
- data/node_modules/axe-core/locales/de.json +1 -5
- data/node_modules/axe-core/locales/es.json +773 -0
- data/node_modules/axe-core/locales/fr.json +15 -19
- data/node_modules/axe-core/locales/ja.json +65 -11
- data/node_modules/axe-core/locales/ko.json +777 -0
- data/node_modules/axe-core/locales/nl.json +35 -35
- data/node_modules/axe-core/locales/pt_BR.json +773 -0
- data/node_modules/axe-core/package.json +56 -52
- data/node_modules/axe-core/sri-history.json +20 -0
- data/node_modules/axe-core/typings/axe-core/axe-core-tests.ts +5 -15
- data/node_modules/govuk-frontend/package.json +10 -10
- metadata +62 -4
- data/node_modules/axe-core/doc/axelogo2018.png +0 -0
- data/node_modules/axe-core/lib/rules/role-not-button-matches.js +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
/*eslint no-bitwise: 0, eqeqeq: 0, curly: 0, strict: 0, no-eq-null: 0,
|
|
2
|
-
max-statements: 0, complexity: 0, no-shadow: 0, no-undef: 0 */
|
|
1
|
+
/*eslint no-bitwise: 0, eqeqeq: 0, curly: 0, strict: 0, no-eq-null: 0, no-shadow: 0, no-undef: 0 */
|
|
3
2
|
// uuid.js
|
|
4
3
|
//
|
|
5
4
|
// Copyright (c) 2010-2012 Robert Kieffer
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Note:
|
|
3
|
+
* This rule filters elements with 'role=*' attribute via 'selector'
|
|
4
|
+
* see relevant rule spec for details of 'role(s)' being filtered.
|
|
5
|
+
*/
|
|
6
|
+
const { aria } = axe.commons;
|
|
7
|
+
|
|
8
|
+
const nodeName = node.nodeName.toUpperCase();
|
|
9
|
+
const role = aria.getRole(node, { noImplicit: true });
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Ignore elements from rule -> 'area-alt'
|
|
13
|
+
*/
|
|
14
|
+
if (nodeName === 'AREA' && !!node.getAttribute('href')) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Ignore elements from rule -> 'label'
|
|
20
|
+
*/
|
|
21
|
+
if (['INPUT', 'SELECT', 'TEXTAREA'].includes(nodeName)) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Ignore elements from rule -> 'image-alt'
|
|
27
|
+
*/
|
|
28
|
+
if (nodeName === 'IMG' || (role === 'img' && nodeName !== 'SVG')) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Ignore elements from rule -> 'button-name'
|
|
34
|
+
*/
|
|
35
|
+
if (nodeName === 'BUTTON' || role === 'button') {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Ignore combobox elements if they have a child input
|
|
41
|
+
* (ARIA 1.1 pattern)
|
|
42
|
+
*/
|
|
43
|
+
if (
|
|
44
|
+
role === 'combobox' &&
|
|
45
|
+
axe.utils.querySelectorAll(virtualNode, 'input:not([type="hidden"])').length
|
|
46
|
+
) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return true;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"selector": "[aria-hidden=\"true\"]",
|
|
4
4
|
"matches": "aria-hidden-focus-matches.js",
|
|
5
5
|
"excludeHidden": false,
|
|
6
|
-
"tags": ["cat.name-role-value", "wcag2a", "wcag412"],
|
|
6
|
+
"tags": ["cat.name-role-value", "wcag2a", "wcag412", "wcag131"],
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Ensures aria-hidden elements do not contain focusable elements",
|
|
9
9
|
"help": "ARIA hidden element must not contain focusable elements"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "aria-input-field-name",
|
|
3
|
+
"selector": "[role=\"combobox\"], [role=\"listbox\"], [role=\"searchbox\"], [role=\"slider\"], [role=\"spinbutton\"], [role=\"textbox\"]",
|
|
4
|
+
"matches": "aria-form-field-name-matches.js",
|
|
5
|
+
"tags": ["wcag2a", "wcag412"],
|
|
6
|
+
"metadata": {
|
|
7
|
+
"description": "Ensures every ARIA input field has an accessible name",
|
|
8
|
+
"help": "ARIA input fields have an accessible name"
|
|
9
|
+
},
|
|
10
|
+
"all": [],
|
|
11
|
+
"any": ["aria-label", "aria-labelledby", "non-empty-title"],
|
|
12
|
+
"none": ["no-implicit-explicit-label"]
|
|
13
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "aria-roledescription",
|
|
3
|
+
"selector": "[aria-roledescription]",
|
|
4
|
+
"tags": ["cat.aria", "wcag2a", "wcag412"],
|
|
5
|
+
"metadata": {
|
|
6
|
+
"description": "Ensure aria-roledescription is only used on elements with an implicit or explicit role",
|
|
7
|
+
"help": "Use aria-roledescription on elements with a semantic role"
|
|
8
|
+
},
|
|
9
|
+
"all": [],
|
|
10
|
+
"any": ["aria-roledescription"],
|
|
11
|
+
"none": []
|
|
12
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "aria-toggle-field-name",
|
|
3
|
+
"selector": "[role=\"checkbox\"], [role=\"menuitemcheckbox\"], [role=\"menuitemradio\"], [role=\"radio\"], [role=\"switch\"]",
|
|
4
|
+
"matches": "aria-form-field-name-matches.js",
|
|
5
|
+
"tags": ["wcag2a", "wcag412"],
|
|
6
|
+
"metadata": {
|
|
7
|
+
"description": "Ensures every ARIA toggle field has an accessible name",
|
|
8
|
+
"help": "ARIA toggle fields have an accessible name"
|
|
9
|
+
},
|
|
10
|
+
"all": [],
|
|
11
|
+
"any": [
|
|
12
|
+
"aria-label",
|
|
13
|
+
"aria-labelledby",
|
|
14
|
+
"non-empty-title",
|
|
15
|
+
"has-visible-text"
|
|
16
|
+
],
|
|
17
|
+
"none": ["no-implicit-explicit-label"]
|
|
18
|
+
}
|
|
@@ -1,31 +1,34 @@
|
|
|
1
1
|
const { text, aria, dom } = axe.commons;
|
|
2
2
|
|
|
3
|
-
const autocomplete =
|
|
3
|
+
const autocomplete = virtualNode.attr('autocomplete');
|
|
4
4
|
if (!autocomplete || text.sanitize(autocomplete) === '') {
|
|
5
5
|
return false;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
const nodeName =
|
|
9
|
-
if (['
|
|
8
|
+
const nodeName = virtualNode.props.nodeName;
|
|
9
|
+
if (['textarea', 'input', 'select'].includes(nodeName) === false) {
|
|
10
10
|
return false;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
// The element is an `input` element a `type` of `hidden`, `button`, `submit` or `reset`
|
|
14
14
|
const excludedInputTypes = ['submit', 'reset', 'button', 'hidden'];
|
|
15
|
-
if (
|
|
15
|
+
if (
|
|
16
|
+
nodeName === 'input' &&
|
|
17
|
+
excludedInputTypes.includes(virtualNode.props.type)
|
|
18
|
+
) {
|
|
16
19
|
return false;
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
// The element has a `disabled` or `aria-disabled="true"` attribute
|
|
20
|
-
const ariaDisabled =
|
|
21
|
-
if (
|
|
23
|
+
const ariaDisabled = virtualNode.attr('aria-disabled') || 'false';
|
|
24
|
+
if (virtualNode.hasAttr('disabled') || ariaDisabled.toLowerCase() === 'true') {
|
|
22
25
|
return false;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
// The element has `tabindex="-1"` and has a [[semantic role]] that is
|
|
26
29
|
// not a [widget](https://www.w3.org/TR/wai-aria-1.1/#widget_roles)
|
|
27
|
-
const role =
|
|
28
|
-
const tabIndex =
|
|
30
|
+
const role = virtualNode.attr('role');
|
|
31
|
+
const tabIndex = virtualNode.attr('tabindex');
|
|
29
32
|
if (tabIndex === '-1' && role) {
|
|
30
33
|
const roleDef = aria.lookupTable.role[role];
|
|
31
34
|
if (roleDef === undefined || roleDef.type !== 'widget') {
|
|
@@ -36,8 +39,9 @@ if (tabIndex === '-1' && role) {
|
|
|
36
39
|
// The element is **not** visible on the page or exposed to assistive technologies
|
|
37
40
|
if (
|
|
38
41
|
tabIndex === '-1' &&
|
|
39
|
-
|
|
40
|
-
!dom.isVisible(
|
|
42
|
+
virtualNode.actualNode &&
|
|
43
|
+
!dom.isVisible(virtualNode.actualNode, false) &&
|
|
44
|
+
!dom.isVisible(virtualNode.actualNode, true)
|
|
41
45
|
) {
|
|
42
46
|
return false;
|
|
43
47
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "avoid-inline-spacing",
|
|
3
|
+
"selector": "[style]",
|
|
4
|
+
"tags": ["wcag21aa", "wcag1412"],
|
|
5
|
+
"metadata": {
|
|
6
|
+
"description": "Ensure that text spacing set through style attributes can be adjusted with custom stylesheets",
|
|
7
|
+
"help": "Inline text spacing must be adjustable with custom stylesheets"
|
|
8
|
+
},
|
|
9
|
+
"all": ["avoid-inline-spacing"],
|
|
10
|
+
"any": [],
|
|
11
|
+
"none": []
|
|
12
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "button-name",
|
|
3
|
-
"selector": "button, [role=\"button\"]
|
|
3
|
+
"selector": "button, [role=\"button\"]:not(input)",
|
|
4
4
|
"tags": [
|
|
5
5
|
"cat.name-role-value",
|
|
6
6
|
"wcag2a",
|
|
@@ -14,8 +14,6 @@
|
|
|
14
14
|
},
|
|
15
15
|
"all": [],
|
|
16
16
|
"any": [
|
|
17
|
-
"non-empty-if-present",
|
|
18
|
-
"non-empty-value",
|
|
19
17
|
"button-has-visible-text",
|
|
20
18
|
"aria-label",
|
|
21
19
|
"aria-labelledby",
|
|
@@ -23,5 +21,5 @@
|
|
|
23
21
|
"role-none",
|
|
24
22
|
"non-empty-title"
|
|
25
23
|
],
|
|
26
|
-
"none": [
|
|
27
|
-
}
|
|
24
|
+
"none": []
|
|
25
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "checkboxgroup",
|
|
3
3
|
"selector": "input[type=checkbox][name]",
|
|
4
|
-
"tags": ["cat.forms", "best-practice"],
|
|
4
|
+
"tags": ["cat.forms", "best-practice", "deprecated"],
|
|
5
5
|
"metadata": {
|
|
6
6
|
"description": "Ensures related <input type=\"checkbox\"> elements have a group and that the group designation is consistent",
|
|
7
7
|
"help": "Checkbox inputs with the same name attribute value must be part of a group"
|
|
8
8
|
},
|
|
9
|
+
"enabled": false,
|
|
9
10
|
"all": [],
|
|
10
11
|
"any": ["group-labelledby", "fieldset"],
|
|
11
12
|
"none": []
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* global document */
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const nodeName = node.nodeName.toUpperCase();
|
|
4
|
+
const nodeType = node.type;
|
|
5
5
|
|
|
6
6
|
if (
|
|
7
7
|
node.getAttribute('aria-disabled') === 'true' ||
|
|
@@ -45,28 +45,35 @@ if (
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// check if the element is a label or label descendant for a disabled control
|
|
48
|
-
|
|
48
|
+
const nodeParentLabel = axe.commons.dom.findUpVirtual(virtualNode, 'label');
|
|
49
49
|
if (nodeName === 'LABEL' || nodeParentLabel) {
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
let relevantNode = node;
|
|
51
|
+
let relevantVirtualNode = virtualNode;
|
|
52
52
|
|
|
53
53
|
if (nodeParentLabel) {
|
|
54
54
|
relevantNode = nodeParentLabel;
|
|
55
55
|
// we need an input candidate from a parent to account for label children
|
|
56
|
-
relevantVirtualNode = axe.utils.getNodeFromTree(
|
|
57
|
-
axe._tree[0],
|
|
58
|
-
nodeParentLabel
|
|
59
|
-
);
|
|
56
|
+
relevantVirtualNode = axe.utils.getNodeFromTree(nodeParentLabel);
|
|
60
57
|
}
|
|
61
58
|
// explicit label of disabled input
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
const doc = axe.commons.dom.getRootNode(relevantNode);
|
|
60
|
+
let candidate =
|
|
64
61
|
relevantNode.htmlFor && doc.getElementById(relevantNode.htmlFor);
|
|
65
|
-
|
|
62
|
+
const candidateVirtualNode = axe.utils.getNodeFromTree(candidate);
|
|
63
|
+
|
|
64
|
+
if (
|
|
65
|
+
candidate &&
|
|
66
|
+
(candidate.disabled ||
|
|
67
|
+
candidate.getAttribute('aria-disabled') === 'true' ||
|
|
68
|
+
axe.commons.dom.findUpVirtual(
|
|
69
|
+
candidateVirtualNode,
|
|
70
|
+
'[aria-disabled="true"]'
|
|
71
|
+
))
|
|
72
|
+
) {
|
|
66
73
|
return false;
|
|
67
74
|
}
|
|
68
75
|
|
|
69
|
-
|
|
76
|
+
candidate = axe.utils.querySelectorAll(
|
|
70
77
|
relevantVirtualNode,
|
|
71
78
|
'input:not([type="hidden"]):not([type="image"])' +
|
|
72
79
|
':not([type="button"]):not([type="submit"]):not([type="reset"]), select, textarea'
|
|
@@ -79,22 +86,30 @@ if (nodeName === 'LABEL' || nodeParentLabel) {
|
|
|
79
86
|
// label of disabled control associated w/ aria-labelledby
|
|
80
87
|
if (node.getAttribute('id')) {
|
|
81
88
|
const id = axe.utils.escapeSelector(node.getAttribute('id'));
|
|
82
|
-
|
|
83
|
-
|
|
89
|
+
const doc = axe.commons.dom.getRootNode(node);
|
|
90
|
+
const candidate = doc.querySelector('[aria-labelledby~=' + id + ']');
|
|
84
91
|
if (candidate && candidate.disabled) {
|
|
85
92
|
return false;
|
|
86
93
|
}
|
|
87
94
|
}
|
|
88
95
|
|
|
89
|
-
|
|
96
|
+
const visibleText = axe.commons.text.visibleVirtual(virtualNode, false, true);
|
|
97
|
+
if (
|
|
98
|
+
visibleText === '' ||
|
|
99
|
+
axe.commons.text.removeUnicode(visibleText, {
|
|
100
|
+
emoji: true,
|
|
101
|
+
nonBmp: true,
|
|
102
|
+
punctuations: true
|
|
103
|
+
}) === ''
|
|
104
|
+
) {
|
|
90
105
|
return false;
|
|
91
106
|
}
|
|
92
107
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
108
|
+
const range = document.createRange();
|
|
109
|
+
const childNodes = virtualNode.children;
|
|
110
|
+
let length = childNodes.length;
|
|
111
|
+
let child = null;
|
|
112
|
+
let index = 0;
|
|
98
113
|
|
|
99
114
|
for (index = 0; index < length; index++) {
|
|
100
115
|
child = childNodes[index];
|
|
@@ -107,7 +122,7 @@ for (index = 0; index < length; index++) {
|
|
|
107
122
|
}
|
|
108
123
|
}
|
|
109
124
|
|
|
110
|
-
|
|
125
|
+
const rects = range.getClientRects();
|
|
111
126
|
length = rects.length;
|
|
112
127
|
|
|
113
128
|
for (index = 0; index < length; index++) {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"tags": ["cat.forms", "wcag2a", "wcag332"],
|
|
6
6
|
"metadata": {
|
|
7
7
|
"description": "Ensures form field does not have multiple label elements",
|
|
8
|
-
"help": "Form field
|
|
8
|
+
"help": "Form field should not have multiple label elements"
|
|
9
9
|
},
|
|
10
10
|
"all": [],
|
|
11
11
|
"any": [],
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "image-redundant-alt",
|
|
3
|
-
"selector": "
|
|
3
|
+
"selector": "img",
|
|
4
4
|
"tags": ["cat.text-alternatives", "best-practice"],
|
|
5
5
|
"metadata": {
|
|
6
|
-
"description": "Ensure
|
|
7
|
-
"help": "
|
|
6
|
+
"description": "Ensure image alternative is not repeated as text",
|
|
7
|
+
"help": "Alternative text of images should not be repeated as text"
|
|
8
8
|
},
|
|
9
9
|
"all": [],
|
|
10
10
|
"any": [],
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "input-button-name",
|
|
3
|
+
"selector": "input[type=\"button\"], input[type=\"submit\"], input[type=\"reset\"]",
|
|
4
|
+
"tags": [
|
|
5
|
+
"cat.name-role-value",
|
|
6
|
+
"wcag2a",
|
|
7
|
+
"wcag412",
|
|
8
|
+
"section508",
|
|
9
|
+
"section508.22.a"
|
|
10
|
+
],
|
|
11
|
+
"metadata": {
|
|
12
|
+
"description": "Ensures input buttons have discernible text",
|
|
13
|
+
"help": "Input buttons must have discernible text"
|
|
14
|
+
},
|
|
15
|
+
"all": [],
|
|
16
|
+
"any": [
|
|
17
|
+
"non-empty-if-present",
|
|
18
|
+
"non-empty-value",
|
|
19
|
+
"aria-label",
|
|
20
|
+
"aria-labelledby",
|
|
21
|
+
"role-presentation",
|
|
22
|
+
"role-none",
|
|
23
|
+
"non-empty-title"
|
|
24
|
+
],
|
|
25
|
+
"none": []
|
|
26
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Since this is a best-practice rule, we are filtering elements as dictated by ARIA 1.1 Practices regardless of treatment by browser/AT combinations.
|
|
3
|
+
*
|
|
4
|
+
* Info: https://www.w3.org/TR/wai-aria-practices-1.1/#aria_landmark
|
|
5
|
+
*/
|
|
6
|
+
var excludedParentsForHeaderFooterLandmarks = [
|
|
7
|
+
'article',
|
|
8
|
+
'aside',
|
|
9
|
+
'main',
|
|
10
|
+
'nav',
|
|
11
|
+
'section'
|
|
12
|
+
].join(',');
|
|
13
|
+
function isHeaderFooterLandmark(headerFooterElement) {
|
|
14
|
+
return !axe.commons.dom.findUpVirtual(
|
|
15
|
+
headerFooterElement,
|
|
16
|
+
excludedParentsForHeaderFooterLandmarks
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function isLandmarkVirtual(virtualNode) {
|
|
21
|
+
var { actualNode } = virtualNode;
|
|
22
|
+
var landmarkRoles = axe.commons.aria.getRolesByType('landmark');
|
|
23
|
+
var role = axe.commons.aria.getRole(actualNode);
|
|
24
|
+
if (!role) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var nodeName = actualNode.nodeName.toUpperCase();
|
|
29
|
+
if (nodeName === 'HEADER' || nodeName === 'FOOTER') {
|
|
30
|
+
return isHeaderFooterLandmark(virtualNode);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (nodeName === 'SECTION' || nodeName === 'FORM') {
|
|
34
|
+
var accessibleText = axe.commons.text.accessibleTextVirtual(virtualNode);
|
|
35
|
+
return !!accessibleText;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return landmarkRoles.indexOf(role) >= 0 || role === 'region';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return isLandmarkVirtual(virtualNode) && axe.commons.dom.isVisible(node, true);
|