Skip to content

Commit

Permalink
feat(is-visible): add support for clip-path techniques (#1706)
Browse files Browse the repository at this point in the history
* feat(is-visible): add support for clip-path techniques

* ignore phantom

* skip test for IE11

* pass style to isCliped function
  • Loading branch information
straker authored Jul 30, 2019
1 parent e4a0081 commit 8ab262a
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 9 deletions.
36 changes: 27 additions & 9 deletions lib/commons/dom/is-visible.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
/* global dom */
const clipRegex = /rect\s*\(([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px\s*\)/;
const clipPathRegex = /(\w+)\((\d+)/;

/**
* Determines if an element is hidden with the clip rect technique
* Determines if an element is hidden with a clip or clip-path technique
* @method isClipped
* @memberof axe.commons.dom
* @private
* @param {String} clip Computed property value of clip
* @param {CSSStyleDeclaration} style Computed style
* @return {Boolean}
*/
function isClipped(clip) {
function isClipped(style) {
'use strict';

var matches = clip.match(
/rect\s*\(([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px\s*\)/
);
if (matches && matches.length === 5) {
return matches[3] - matches[1] <= 0 && matches[2] - matches[4] <= 0;
const matchesClip = style.getPropertyValue('clip').match(clipRegex);
const matchesClipPath = style
.getPropertyValue('clip-path')
.match(clipPathRegex);
if (matchesClip && matchesClip.length === 5) {
return (
matchesClip[3] - matchesClip[1] <= 0 &&
matchesClip[2] - matchesClip[4] <= 0
);
}
if (matchesClipPath) {
const type = matchesClipPath[1];
const value = parseInt(matchesClipPath[2], 10);

switch (type) {
case 'inset':
return value >= 50;
case 'circle':
return value === 0;
default:
}
}

return false;
Expand Down Expand Up @@ -60,7 +78,7 @@ dom.isVisible = function(el, screenReader, recursed) {
if (
style.getPropertyValue('display') === 'none' ||
['STYLE', 'SCRIPT', 'NOSCRIPT', 'TEMPLATE'].includes(nodeName) ||
(!screenReader && isClipped(style.getPropertyValue('clip'))) ||
(!screenReader && isClipped(style)) ||
(!recursed &&
// visibility is only accurate on the first element
(style.getPropertyValue('visibility') === 'hidden' ||
Expand Down
46 changes: 46 additions & 0 deletions test/commons/dom/is-visible.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ describe('dom.isVisible', function() {

var fixture = document.getElementById('fixture');
var fixtureSetup = axe.testUtils.fixtureSetup;
var isIE11 = axe.testUtils.isIE11;
var shadowSupported = axe.testUtils.shadowSupport.v1;
var fakeNode = {
nodeType: Node.ELEMENT_NODE,
Expand Down Expand Up @@ -188,6 +189,33 @@ describe('dom.isVisible', function() {
el = document.getElementById('target');
assert.isFalse(axe.commons.dom.isVisible(el));
});

// IE11 either only supports clip paths defined by url() or not at all,
// MDN and caniuse.com give different results...
(isIE11 || window.PHANTOMJS ? it.skip : it)(
'should detect clip-path hidden text technique',
function() {
fixture.innerHTML =
'<div id="target" style="clip-path: inset(50%);">Hi</div>';

var el = document.getElementById('target');
assert.isFalse(axe.commons.dom.isVisible(el));
}
);

(isIE11 || window.PHANTOMJS ? it.skip : it)(
'should detect clip-path hidden text technique on parent',
function() {
fixture.innerHTML =
'<div style="clip-path: circle(0%);">' +
'<div id="target">Hi</div>' +
'</div>';

var el = document.getElementById('target');
assert.isFalse(axe.commons.dom.isVisible(el));
}
);

(shadowSupported ? it : xit)(
'should correctly handle visible slotted elements',
function() {
Expand Down Expand Up @@ -411,5 +439,23 @@ describe('dom.isVisible', function() {
el = document.getElementById('target');
assert.isTrue(axe.commons.dom.isVisible(el, true));
});

it('should detect clip-path hidden text technique', function() {
fixture.innerHTML =
'<div id="target" style="clip-path: inset(50%);">Hi</div>';

var el = document.getElementById('target');
assert.isTrue(axe.commons.dom.isVisible(el, true));
});

it('should detect clip-path hidden text technique on parent', function() {
fixture.innerHTML =
'<div style="clip-path: circle(0%);">' +
'<div id="target">Hi</div>' +
'</div>';

var el = document.getElementById('target');
assert.isTrue(axe.commons.dom.isVisible(el, true));
});
});
});

0 comments on commit 8ab262a

Please sign in to comment.