Skip to content

Commit

Permalink
fix(is-visible): return false for opacity: 0 and 0 height scrollable …
Browse files Browse the repository at this point in the history
…regions
  • Loading branch information
straker committed Jun 16, 2020
1 parent 205b587 commit 86ada3f
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 19 deletions.
56 changes: 37 additions & 19 deletions lib/commons/dom/is-visible.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,30 +118,48 @@ dom.isVisible = function(el, screenReader, recursed) {
}

const nodeName = el.nodeName.toUpperCase();
/**
* check visibility of `AREA` * check visibility of `AREA`
* Note:
* Firefox's user-agent always sets `AREA` element to `display:none`
* hence excluding the edge case, for visibility computation
*/
if (nodeName === 'AREA') {
return isAreaVisible(el, screenReader, recursed);
}

// always hidden
if (
/**
* Note:
* Firefox's user-agent always sets `AREA` element to `display:none`
* hence excluding the edge case, for visibility computation
*/
(nodeName !== 'AREA' && style.getPropertyValue('display') === 'none') ||
['STYLE', 'SCRIPT', 'NOSCRIPT', 'TEMPLATE'].includes(nodeName) ||
(!screenReader && isClipped(style)) ||
(!recursed &&
// visibility is only accurate on the first element
(style.getPropertyValue('visibility') === 'hidden' ||
// position does not matter if it was already calculated
(!screenReader && dom.isOffscreen(el)))) ||
(screenReader && el.getAttribute('aria-hidden') === 'true')
style.getPropertyValue('display') === 'none' ||
['STYLE', 'SCRIPT', 'NOSCRIPT', 'TEMPLATE'].includes(nodeName)
) {
return false;
}

/**
* check visibility of `AREA`
*/
if (nodeName === 'AREA') {
return isAreaVisible(el, screenReader, recursed);
// hidden from screen readers
if (screenReader && el.getAttribute('aria-hidden') === 'true') {
return false;
}

// hidden from visual users
if (
!screenReader &&
(isClipped(style) ||
style.getPropertyValue('opacity') === '0' ||
(axe.utils.getScroll(el) &&
parseInt(style.getPropertyValue('height')) === 0))
) {
return false;
}

// visibility is only accurate on the first element and
// position does not matter if it was already calculated
if (
!recursed &&
(style.getPropertyValue('visibility') === 'hidden' ||
(!screenReader && axe.commons.dom.isOffscreen(el)))
) {
return false;
}

const parent = el.assignedSlot ? el.assignedSlot : el.parentNode;
Expand Down
20 changes: 20 additions & 0 deletions test/checks/color/color-contrast.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,26 @@ describe('color-contrast', function() {
axe._tree = undefined;
});

it('should return true for hidden element', function() {
var params = checkSetup(
'<div style="color: gray; background-color: white; font-size: 14pt; font-weight: 100;">' +
'<span id="target" style="font-weight:bolder; opacity: 0;">My text</span></div>'
);

assert.isTrue(contrastEvaluate.apply(checkContext, params));
assert.deepEqual(checkContext._relatedNodes, []);
});

it('should return true for child of hidden element', function() {
var params = checkSetup(
'<div style="color: gray; background-color: white; font-size: 14pt; font-weight: 100; overflow: scroll; height: 0">' +
'<span id="target" style="font-weight:bolder">My text</span></div>'
);

assert.isTrue(contrastEvaluate.apply(checkContext, params));
assert.deepEqual(checkContext._relatedNodes, []);
});

it('should return the proper values stored in data', function() {
var params = checkSetup(
'<div id="parent" style="color: black; background-color: white; font-size: 14pt">' +
Expand Down
29 changes: 29 additions & 0 deletions test/commons/dom/is-visible.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,35 @@ describe('dom.isVisible', function() {
assert.isFalse(axe.commons.dom.isVisible(el));
});

it('should return false for display: none', function() {
fixture.innerHTML = '<div id="target" style="display: none">Hello!</div>';
var el = document.getElementById('target');

assert.isFalse(axe.commons.dom.isVisible(el));
});

it('should return false for opacity: 0', function() {
fixture.innerHTML = '<div id="target" style="opacity: 0">Hello!</div>';
var el = document.getElementById('target');

assert.isFalse(axe.commons.dom.isVisible(el));
});

it('should return false for opacity: 0', function() {
fixture.innerHTML = '<div id="target" style="opacity: 0">Hello!</div>';
var el = document.getElementById('target');

assert.isFalse(axe.commons.dom.isVisible(el));
});

it('should return false for 0 height scrollable region', function() {
fixture.innerHTML =
'<div style="overflow: scroll; height: 0"><div id="target">Hello!</div></div>';
var el = document.getElementById('target');

assert.isFalse(axe.commons.dom.isVisible(el));
});

it('returns false for `AREA` without closest `MAP` element', function() {
var vNode = queryFixture(
'<area id="target" role="link" shape="circle" coords="130,136,60" aria-label="MDN"/>'
Expand Down

0 comments on commit 86ada3f

Please sign in to comment.