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.
- 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);
|