-
Notifications
You must be signed in to change notification settings - Fork 795
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rules): add new rule aria-dpub-role-fallback
Ensures that DPUB ARIA roles that are unsupported and may have a negative impact are only used on elements which have a compatible implicit ARIA role fallback.
- Loading branch information
Showing
9 changed files
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
var role = node.getAttribute('role'); | ||
if (role === null || !axe.commons.aria.isValidRole(role)) { | ||
return true; | ||
} | ||
var roleType = axe.commons.aria.getRoleType(role); | ||
return axe.commons.aria.implicitRole(node) === roleType; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"id": "implicit-role-fallback", | ||
"evaluate": "implicit-role-fallback.js", | ||
"metadata": { | ||
"impact": "moderate", | ||
"messages": { | ||
"pass": "Element’s implicit ARIA role is an appropriate fallback", | ||
"fail": "Element’s implicit ARIA role is not a good fallback for the (unsupported) role" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
var role = node.getAttribute('role'); | ||
return [ | ||
'doc-backlink', | ||
'doc-biblioentry', | ||
'doc-biblioref', | ||
'doc-cover', | ||
'doc-endnote', | ||
'doc-glossref', | ||
'doc-noteref' | ||
].includes(role); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"id": "aria-dpub-role-fallback", | ||
"selector": "[role]", | ||
"matches": "aria-dpub-role-fallback-matches.js", | ||
"tags": [ | ||
"cat.aria", | ||
"wcag2a", | ||
"wcag131" | ||
], | ||
"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" | ||
}, | ||
"all": [ | ||
"implicit-role-fallback" | ||
], | ||
"any": [], | ||
"none": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
describe('implicit-role-fallback', function () { | ||
'use strict'; | ||
|
||
var fixture = document.getElementById('fixture'); | ||
var node; | ||
var checkContext = axe.testUtils.MockCheckContext(); | ||
|
||
|
||
afterEach(function () { | ||
node.innerHTML = ''; | ||
checkContext._data = null; | ||
}); | ||
|
||
it('should return true for elements with no role', function() { | ||
node = document.createElement('div'); | ||
fixture.appendChild(node); | ||
assert.isTrue(checks['implicit-role-fallback'].evaluate.call(checkContext, node)); | ||
}); | ||
|
||
it('should return true for elements with nonsensical roles', function() { | ||
fixture.innerHTML = '<a role="awesomelink" id="target" href="#">text</a>'; | ||
var target = fixture.children[0]; | ||
assert.isTrue(checks['implicit-role-fallback'].evaluate.call(checkContext, target)); | ||
}); | ||
|
||
it('should return true if the provided role’s parent is the element’s implicit role', function () { | ||
|
||
axe.commons.aria.lookupTable.role.awesomelink = { | ||
type: 'link', | ||
attributes: { | ||
allowed: ['aria-expanded'] | ||
}, | ||
owned: null, | ||
namefrom: ['author', 'contents'], | ||
context: null, | ||
}; | ||
fixture.innerHTML = '<a role="awesomelink" id="target" href="#">text</a>'; | ||
var target = fixture.children[0]; | ||
assert.isTrue(checks['implicit-role-fallback'].evaluate.call(checkContext, target)); | ||
delete axe.commons.aria.lookupTable.role.awesomelink; | ||
}); | ||
|
||
it('should return false if the provided role’s type is not the element’s implicit role', function () { | ||
|
||
axe.commons.aria.lookupTable.role.awesomelink = { | ||
type: 'link', | ||
attributes: { | ||
allowed: ['aria-expanded'] | ||
}, | ||
owned: null, | ||
namefrom: ['author', 'contents'], | ||
context: null, | ||
}; | ||
fixture.innerHTML = '<article role="awesomelink" id="target"></article>'; | ||
var target = fixture.children[0]; | ||
assert.isFalse(checks['implicit-role-fallback'].evaluate.call(checkContext, target)); | ||
delete axe.commons.aria.lookupTable.role.awesomelink; | ||
}); | ||
|
||
it('should return false if the element has no implicit role', function () { | ||
|
||
axe.commons.aria.lookupTable.role.awesomelink = { | ||
type: 'link', | ||
attributes: { | ||
allowed: ['aria-expanded'] | ||
}, | ||
owned: null, | ||
namefrom: ['author', 'contents'], | ||
context: null, | ||
}; | ||
fixture.innerHTML = '<div role="awesomelink" id="target"></div>'; | ||
var target = fixture.children[0]; | ||
assert.isFalse(checks['implicit-role-fallback'].evaluate.call(checkContext, target)); | ||
delete axe.commons.aria.lookupTable.role.awesomelink; | ||
}); | ||
}); |
25 changes: 25 additions & 0 deletions
25
test/integration/rules/aria-dpub-role-fallback/aria-dpub-role-fallback.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
<div id="ok"> | ||
<!-- links --> | ||
<a id="pass1" role="doc-backlink" href="#">ok</a> | ||
<a id="pass2" role="doc-biblioref" href="#">ok</a> | ||
<a id="pass3" role="doc-glossref" href="#">ok</a> | ||
<a id="pass4" role="doc-noteref" href="#">ok</a> | ||
<!-- images --> | ||
<img id="pass5" role="doc-cover"/> | ||
<!-- listitems --> | ||
<ul><li id="pass6" role="doc-biblioentry">ok</li></ul> | ||
<ul><li id="pass7" role="doc-endnote">ok</li></ul> | ||
</div> | ||
<div id="violation"> | ||
<!-- links --> | ||
<div id="fail1" role="doc-backlink">ok</div> | ||
<div id="fail2" role="doc-biblioref">ok</div> | ||
<div id="fail3" role="doc-glossref">ok</div> | ||
<div id="fail4" role="doc-noteref">ok</div> | ||
<!-- images --> | ||
<div id="fail5" role="doc-cover">ok</div> | ||
<!-- listitems --> | ||
<div id="fail6" role="doc-biblioentry">ok</div> | ||
<div id="fail7" role="doc-endnote">ok</div> | ||
</div> |
10 changes: 10 additions & 0 deletions
10
test/integration/rules/aria-dpub-role-fallback/aria-dpub-role-fallback.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"description": "aria-dpub-role-fallback tests", | ||
"rule": "aria-dpub-role-fallback", | ||
"violations": [ | ||
["#fail1"], ["#fail2"], ["#fail3"], ["#fail4"], ["#fail5"], ["#fail6"], ["#fail7"] | ||
], | ||
"passes": [ | ||
["#pass1"], ["#pass2"], ["#pass3"], ["#pass4"], ["#pass5"], ["#pass6"], ["#pass7"] | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
describe('aria-dpub-role-fallback-matches', function () { | ||
'use strict'; | ||
|
||
var fixture = document.getElementById('fixture'); | ||
var rule; | ||
|
||
beforeEach(function () { | ||
rule = axe._audit.rules.find(function (rule) { | ||
return rule.id === 'aria-dpub-role-fallback'; | ||
}); | ||
}); | ||
|
||
afterEach(function () { | ||
fixture.innerHTML = ''; | ||
}); | ||
|
||
it('is a function', function () { | ||
assert.isFunction(rule.matches); | ||
}); | ||
|
||
it('should not match elements with no role', function () { | ||
fixture.innerHTML = '<div></div>'; | ||
var target = fixture.children[0]; | ||
|
||
assert.isFalse(rule.matches(target)); | ||
}); | ||
|
||
it('should not match elements with a nonsensical role', function () { | ||
fixture.innerHTML = '<div role="yay"></div>'; | ||
var target = fixture.children[0]; | ||
|
||
assert.isFalse(rule.matches(target)); | ||
}); | ||
|
||
it('should not match elements with a non-DPUB role', function () { | ||
fixture.innerHTML = '<div role="main"></div>'; | ||
var target = fixture.children[0]; | ||
|
||
assert.isFalse(rule.matches(target)); | ||
}); | ||
|
||
it('should not match elements with a "harmless" DPUB role', function () { | ||
fixture.innerHTML = '<div role="doc-bibliography"></div>'; | ||
var target = fixture.children[0]; | ||
|
||
assert.isFalse(rule.matches(target)); | ||
}); | ||
|
||
it('should match elements with one of the targeted DPUB roles"', function () { | ||
fixture.innerHTML = '<div role="doc-backlink"></div>'; | ||
var target = fixture.children[0]; | ||
|
||
assert.isTrue(rule.matches(target)); | ||
}); | ||
}); |