Skip to content

Commit

Permalink
fix: Allow live-region and dialog in region rule (#1073)
Browse files Browse the repository at this point in the history
  • Loading branch information
WilcoFiers authored Aug 21, 2018
1 parent 4ae4ea0 commit fb6438b
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 20 deletions.
45 changes: 25 additions & 20 deletions lib/checks/navigation/region.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,32 @@ function isSkipLink(vNode) {
}

// Check if the current element is a landmark
function isLandmark(virtualNode) {
var node = virtualNode.actualNode;
var explictRole = (node.getAttribute('role') || '').trim().toLowerCase();
function isRegion(virtualNode) {
const node = virtualNode.actualNode;
const explicitRole = axe.commons.aria.getRole(node, { noImplicit: true });
const ariaLive = (node.getAttribute('aria-live') || '').toLowerCase().trim();

if (explictRole) {
return landmarkRoles.includes(explictRole);
} else {
// Check if the node matches any of the CSS selectors of implicit landmarks
return implicitLandmarks.some(implicitSelector => {
let matches = axe.utils.matchesSelector(node, implicitSelector);
if (node.tagName.toLowerCase() === 'form') {
let titleAttr = node.getAttribute('title');
let title =
titleAttr && titleAttr.trim() !== ''
? axe.commons.text.sanitize(titleAttr)
: null;
return matches && (!!aria.labelVirtual(virtualNode) || !!title);
}
return matches;
});
if (explicitRole) {
return explicitRole === 'dialog' || landmarkRoles.includes(explicitRole);
}
// Ignore content inside of aria-live
if (['assertive', 'polite'].includes(ariaLive)) {
return true;
}

// Check if the node matches any of the CSS selectors of implicit landmarks
return implicitLandmarks.some(implicitSelector => {
let matches = axe.utils.matchesSelector(node, implicitSelector);
if (node.tagName.toLowerCase() === 'form') {
let titleAttr = node.getAttribute('title');
let title =
titleAttr && titleAttr.trim() !== ''
? axe.commons.text.sanitize(titleAttr)
: null;
return matches && (!!aria.labelVirtual(virtualNode) || !!title);
}
return matches;
});
}

/**
Expand All @@ -55,7 +60,7 @@ function findRegionlessElms(virtualNode) {
const node = virtualNode.actualNode;
// End recursion if the element is a landmark, skiplink, or hidden content
if (
isLandmark(virtualNode) ||
isRegion(virtualNode) ||
isSkipLink(virtualNode) ||
!dom.isVisible(node, true)
) {
Expand Down
29 changes: 29 additions & 0 deletions test/checks/navigation/region.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,35 @@ describe('region', function() {
assert.isTrue(checks.region.evaluate.apply(checkContext, checkArgs));
});

it('allows content in aria-live=assertive', function() {
var checkArgs = checkSetup(
'<div aria-live="assertive" id="target"><p>This is random content.</p></div>'
);
assert.isTrue(checks.region.evaluate.apply(checkContext, checkArgs));
});

it('allows content in aria-live=polite', function() {
var checkArgs = checkSetup(
'<div aria-live="polite" id="target"><p>This is random content.</p></div>'
);
assert.isTrue(checks.region.evaluate.apply(checkContext, checkArgs));
});

it('does not allow content in aria-live=off', function() {
var checkArgs = checkSetup(
'<div aria-live="off" id="target"><p>This is random content.</p></div>'
);
assert.isFalse(checks.region.evaluate.apply(checkContext, checkArgs));
});

it('treats role=dialog elements as regions', function() {
var checkArgs = checkSetup(
'<div role="dialog" id="target"><p>This is random content.</p></div>'
);

assert.isTrue(checks.region.evaluate.apply(checkContext, checkArgs));
});

(shadowSupport.v1 ? it : xit)('should test Shadow tree content', function() {
var div = document.createElement('div');
var shadow = div.attachShadow({ mode: 'open' });
Expand Down

0 comments on commit fb6438b

Please sign in to comment.