diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index 05536cd4ec..766f2b50de 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -4,7 +4,7 @@ | area-alt | Ensures <area> elements of image maps have alternate text | Critical | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a | true | true | false | | aria-allowed-attr | Ensures ARIA attributes are allowed for an element's role | Critical | cat.aria, wcag2a, wcag412 | true | true | false | | aria-allowed-role | Ensures role attribute has an appropriate value for the element | Minor | cat.aria, best-practice | true | true | true | -| aria-dpub-role-fallback | Ensures unsupported DPUB roles are only used on elements with implicit fallback roles | Moderate | cat.aria, wcag2a, wcag131 | true | true | false | +| aria-dpub-role-fallback | Ensures unsupported DPUB roles are only used on elements with implicit fallback roles | Moderate | cat.aria, wcag2a, wcag131, deprecated | false | true | false | | aria-hidden-body | Ensures aria-hidden='true' is not present on the document body. | Critical | cat.aria, wcag2a, wcag412 | true | true | false | | aria-hidden-focus | Ensures aria-hidden elements do not contain focusable elements | Serious | cat.name-role-value, wcag2a, wcag412, wcag131 | true | true | false | | aria-input-field-name | Ensures every ARIA input field has an accessible name | Moderate, Serious | wcag2a, wcag412 | true | true | true | diff --git a/lib/checks/aria/implicit-role-fallback.json b/lib/checks/aria/implicit-role-fallback.json index b35a48df2b..0834dc9259 100644 --- a/lib/checks/aria/implicit-role-fallback.json +++ b/lib/checks/aria/implicit-role-fallback.json @@ -1,6 +1,7 @@ { "id": "implicit-role-fallback", "evaluate": "implicit-role-fallback.js", + "deprecated": true, "metadata": { "impact": "moderate", "messages": { diff --git a/lib/commons/aria/get-element-unallowed-roles.js b/lib/commons/aria/get-element-unallowed-roles.js index b746ff2e53..17cb83a455 100644 --- a/lib/commons/aria/get-element-unallowed-roles.js +++ b/lib/commons/aria/get-element-unallowed-roles.js @@ -1,5 +1,17 @@ /* global aria */ +// dpub roles which are subclassing roles that are implicit on some native +// HTML elements (img, link, etc.) +const dpubRoles = [ + 'doc-backlink', + 'doc-biblioentry', + 'doc-biblioref', + 'doc-cover', + 'doc-endnote', + 'doc-glossref', + 'doc-noteref' +]; + /** * Returns all roles applicable to element in a list * @@ -71,6 +83,15 @@ aria.getElementUnallowedRoles = function getElementUnallowedRoles( return false; } + // if role is a dpub role make sure it's used on an element with a valid + // implicit role fallback + if (allowImplicit && dpubRoles.includes(role)) { + const roleType = axe.commons.aria.getRoleType(role); + if (implicitRole !== roleType) { + return true; + } + } + // Edge case: // setting implicit role row on tr element is allowed when child of table[role='grid'] if ( diff --git a/lib/rules/aria-dpub-role-fallback.json b/lib/rules/aria-dpub-role-fallback.json index e5146ab0f8..1260049009 100644 --- a/lib/rules/aria-dpub-role-fallback.json +++ b/lib/rules/aria-dpub-role-fallback.json @@ -2,11 +2,12 @@ "id": "aria-dpub-role-fallback", "selector": "[role]", "matches": "aria-dpub-role-fallback-matches.js", - "tags": ["cat.aria", "wcag2a", "wcag131"], + "tags": ["cat.aria", "wcag2a", "wcag131", "deprecated"], "metadata": { "description": "Ensures unsupported DPUB roles are only used on elements with implicit fallback roles", "help": "Unsupported DPUB ARIA roles should be used on elements with implicit fallback roles" }, + "enabled": false, "all": ["implicit-role-fallback"], "any": [], "none": [] diff --git a/test/checks/aria/aria-allowed-role.js b/test/checks/aria/aria-allowed-role.js index 4d2cae5670..e01d545ae3 100644 --- a/test/checks/aria/aria-allowed-role.js +++ b/test/checks/aria/aria-allowed-role.js @@ -299,4 +299,20 @@ describe('aria-allowed-role', function() { assert.isTrue(actual); assert.isNull(checkContext._data, null); }); + + it('returns false if a dpub role’s type is not the element’s implicit role', function() { + fixture.innerHTML = '
'; + var target = fixture.children[0]; + assert.isFalse( + checks['aria-allowed-role'].evaluate.call(checkContext, target) + ); + }); + + it('returns true if a dpub role’s type is the element’s implicit role', function() { + fixture.innerHTML = ''; + var target = fixture.children[0]; + assert.isTrue( + checks['aria-allowed-role'].evaluate.call(checkContext, target) + ); + }); }); diff --git a/test/integration/rules/aria-allowed-role/aria-allowed-role.html b/test/integration/rules/aria-allowed-role/aria-allowed-role.html index f920c92b52..877ad4a737 100644 --- a/test/integration/rules/aria-allowed-role/aria-allowed-role.html +++ b/test/integration/rules/aria-allowed-role/aria-allowed-role.html @@ -135,6 +135,21 @@

id="pass-custom-element-any-role" role="navigation" > + +ok +ok +ok +ok + + + + + +
@@ -167,3 +182,13 @@

aria-hidden="true" role="presentation" > + +
ok
+
ok
+
ok
+
ok
+ +
ok
+ +
ok
+
ok
diff --git a/test/integration/rules/aria-allowed-role/aria-allowed-role.json b/test/integration/rules/aria-allowed-role/aria-allowed-role.json index b674ef9997..499e6a6217 100644 --- a/test/integration/rules/aria-allowed-role/aria-allowed-role.json +++ b/test/integration/rules/aria-allowed-role/aria-allowed-role.json @@ -55,7 +55,14 @@ ["#pass-ul-role-presentation"], ["#pass-ol-role-none"], ["#pass-ol-role-presentation"], - ["#pass-custom-element-any-role"] + ["#pass-custom-element-any-role"], + ["#pass-dpub-1"], + ["#pass-dpub-2"], + ["#pass-dpub-3"], + ["#pass-dpub-4"], + ["#pass-dpub-5"], + ["#pass-dpub-6"], + ["#pass-dpub-7"] ], "violations": [ ["#fail-dd-no-role"], @@ -70,7 +77,14 @@ ["#fail-aside-doc-foreword"], ["#fail-aside-role-tab"], ["#fail-button-role-gridcell"], - ["#fail-input-role-gridcell-multiple-role"] + ["#fail-input-role-gridcell-multiple-role"], + ["#fail-dpub-1"], + ["#fail-dpub-2"], + ["#fail-dpub-3"], + ["#fail-dpub-4"], + ["#fail-dpub-5"], + ["#fail-dpub-6"], + ["#fail-dpub-7"] ], "incomplete": [["#incomplete1"], ["#incomplete2"]] }