Skip to content

Commit 524f0be

Browse files
committed
add suggested isShallowlyHidden instead of presentational
1 parent 70b6ddb commit 524f0be

2 files changed

Lines changed: 31 additions & 9 deletions

File tree

lib/checks/navigation/region-evaluate.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as dom from '../../commons/dom';
2+
import { hasChildTextNodes } from '../../commons/dom/has-content-virtual';
23
import { getRole } from '../../commons/aria';
34
import * as standards from '../../commons/standards';
45
import matches from '../../commons/matches';
@@ -56,8 +57,7 @@ function findRegionlessElms(virtualNode, options) {
5657
['iframe', 'frame'].includes(virtualNode.props.nodeName) ||
5758
(dom.isSkipLink(virtualNode.actualNode) &&
5859
dom.getElementByReference(virtualNode.actualNode, 'href')) ||
59-
!dom.isVisibleToScreenReaders(node) ||
60-
isPresentationGraphic(virtualNode)
60+
!dom.isVisibleToScreenReaders(node)
6161
) {
6262
// Mark each parent node as having region descendant
6363
let vNode = virtualNode;
@@ -78,7 +78,8 @@ function findRegionlessElms(virtualNode, options) {
7878
// @see https://github.com/dequelabs/axe-core/issues/2049
7979
} else if (
8080
node !== document.body &&
81-
dom.hasContent(node, /* noRecursion: */ true)
81+
dom.hasContent(node, /* noRecursion: */ true) &&
82+
!isShallowlyHidden(virtualNode)
8283
) {
8384
return [virtualNode];
8485

@@ -91,8 +92,11 @@ function findRegionlessElms(virtualNode, options) {
9192
}
9293
}
9394

94-
function isPresentationGraphic(virtualNode) {
95-
return virtualNode.props.nodeName === 'img' && virtualNode.attr('alt') === '';
95+
function isShallowlyHidden(virtualNode) {
96+
const role = getRole(virtualNode, { noPresentational: true });
97+
const isPresentational = role === null;
98+
// The element itself is not visible to screen readers, but its descendants might be
99+
return isPresentational && !hasChildTextNodes(virtualNode);
96100
}
97101

98102
// Check if the current element is a landmark

test/checks/navigation/region.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe('region', function () {
4646
assert.isTrue(checkEvaluate.apply(checkContext, checkArgs));
4747
});
4848

49-
it('should return false when img content is outside the region', function () {
49+
it('should return false when img content is outside the region, no alt attribute at all', function () {
5050
var checkArgs = checkSetup(`
5151
<img id="target" src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7">
5252
<div role="main">Content</div>
@@ -57,22 +57,40 @@ describe('region', function () {
5757

5858
it('should return true when img content outside of the region is decorative, via an empty alt attr', function () {
5959
var checkArgs = checkSetup(`
60-
<img id="target" src="#" width="1" height="1" alt="" />
60+
<img id="target" src="#" alt="" />
6161
<div role="main">Content</div>
6262
`);
6363

6464
assert.isTrue(checkEvaluate.apply(checkContext, checkArgs));
6565
});
6666

67-
it('should return true when img content outside of the region is decorative, via a presentation role', function () {
67+
it('should return true when img content outside of the region is explicitly decorative, via a presentation role', function () {
6868
var checkArgs = checkSetup(`
69-
<img id="target" src="#" width="1" height="1" role="presentation />
69+
<img id="target" src="#" role="presentation" />
7070
<div role="main">Content</div>
7171
`);
7272

7373
assert.isTrue(checkEvaluate.apply(checkContext, checkArgs));
7474
});
7575

76+
it('should return false when img content outside of the region is focusable (implicit role=img)', function () {
77+
var checkArgs = checkSetup(`
78+
<img id="target" src="#" tabindex="0" />
79+
<div role="main">Content</div>
80+
`);
81+
82+
assert.isFalse(checkEvaluate.apply(checkContext, checkArgs));
83+
});
84+
85+
it('should return false when img content outside of the region has a global aria attribute (implicit role=img)', function () {
86+
var checkArgs = checkSetup(`
87+
<img id="target" src="#" aria-level="2" />
88+
<div role="main">Content</div>
89+
`);
90+
91+
assert.isFalse(checkEvaluate.apply(checkContext, checkArgs));
92+
});
93+
7694
it('should return true when textless text content is outside the region', function () {
7795
var checkArgs = checkSetup(
7896
'<p id="target"></p><div role="main"><h1 id="mainheader" tabindex="0">Introduction</h1></div>'

0 commit comments

Comments
 (0)