Skip to content

Commit 5bb566f

Browse files
authored
fix(color-contrast-matches): don't check aria-disabled explicit label element (#1741)
* fix(color-contrast-matches): don't check aria-disabled explicit label element * typo
1 parent ec9b762 commit 5bb566f

File tree

2 files changed

+43
-17
lines changed

2 files changed

+43
-17
lines changed

lib/rules/color-contrast-matches.js

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* global document */
22

3-
var nodeName = node.nodeName.toUpperCase(),
4-
nodeType = node.type;
3+
const nodeName = node.nodeName.toUpperCase();
4+
const nodeType = node.type;
55

66
if (
77
node.getAttribute('aria-disabled') === 'true' ||
@@ -45,25 +45,35 @@ if (
4545
}
4646

4747
// check if the element is a label or label descendant for a disabled control
48-
var nodeParentLabel = axe.commons.dom.findUpVirtual(virtualNode, 'label');
48+
const nodeParentLabel = axe.commons.dom.findUpVirtual(virtualNode, 'label');
4949
if (nodeName === 'LABEL' || nodeParentLabel) {
50-
var relevantNode = node;
51-
var relevantVirtualNode = virtualNode;
50+
let relevantNode = node;
51+
let relevantVirtualNode = virtualNode;
5252

5353
if (nodeParentLabel) {
5454
relevantNode = nodeParentLabel;
5555
// we need an input candidate from a parent to account for label children
5656
relevantVirtualNode = axe.utils.getNodeFromTree(nodeParentLabel);
5757
}
5858
// explicit label of disabled input
59-
let doc = axe.commons.dom.getRootNode(relevantNode);
60-
var candidate =
59+
const doc = axe.commons.dom.getRootNode(relevantNode);
60+
let candidate =
6161
relevantNode.htmlFor && doc.getElementById(relevantNode.htmlFor);
62-
if (candidate && candidate.disabled) {
62+
const candidateVirtualNode = axe.utils.getNodeFromTree(candidate);
63+
64+
if (
65+
candidate &&
66+
(candidate.disabled ||
67+
candidate.getAttribute('aria-disabled') === 'true' ||
68+
axe.commons.dom.findUpVirtual(
69+
candidateVirtualNode,
70+
'[aria-disabled="true"]'
71+
))
72+
) {
6373
return false;
6474
}
6575

66-
var candidate = axe.utils.querySelectorAll(
76+
candidate = axe.utils.querySelectorAll(
6777
relevantVirtualNode,
6878
'input:not([type="hidden"]):not([type="image"])' +
6979
':not([type="button"]):not([type="submit"]):not([type="reset"]), select, textarea'
@@ -76,8 +86,8 @@ if (nodeName === 'LABEL' || nodeParentLabel) {
7686
// label of disabled control associated w/ aria-labelledby
7787
if (node.getAttribute('id')) {
7888
const id = axe.utils.escapeSelector(node.getAttribute('id'));
79-
let doc = axe.commons.dom.getRootNode(node);
80-
var candidate = doc.querySelector('[aria-labelledby~=' + id + ']');
89+
const doc = axe.commons.dom.getRootNode(node);
90+
const candidate = doc.querySelector('[aria-labelledby~=' + id + ']');
8191
if (candidate && candidate.disabled) {
8292
return false;
8393
}
@@ -87,11 +97,11 @@ if (axe.commons.text.visibleVirtual(virtualNode, false, true) === '') {
8797
return false;
8898
}
8999

90-
var range = document.createRange(),
91-
childNodes = virtualNode.children,
92-
length = childNodes.length,
93-
child,
94-
index;
100+
const range = document.createRange();
101+
const childNodes = virtualNode.children;
102+
let length = childNodes.length;
103+
let child = null;
104+
let index = 0;
95105

96106
for (index = 0; index < length; index++) {
97107
child = childNodes[index];
@@ -104,7 +114,7 @@ for (index = 0; index < length; index++) {
104114
}
105115
}
106116

107-
var rects = range.getClientRects();
117+
const rects = range.getClientRects();
108118
length = rects.length;
109119

110120
for (index = 0; index < length; index++) {

test/rule-matches/color-contrast-matches.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,22 @@ describe('color-contrast-matches', function() {
238238
assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(target)));
239239
});
240240

241+
it("should not match an aria-disabled input's label - explicit label", function() {
242+
fixture.innerHTML =
243+
'<label for="t1">Test</label><input type="text" id="t1" aria-disabled="true">';
244+
var target = fixture.querySelector('label');
245+
axe.testUtils.flatTreeSetup(fixture);
246+
assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(target)));
247+
});
248+
249+
it("should not match a parent aria-disabled input's label - explicit label", function() {
250+
fixture.innerHTML =
251+
'<label for="t1">Test</label><div aria-disabled="true"><input type="text" id="t1"></div>';
252+
var target = fixture.querySelector('label');
253+
axe.testUtils.flatTreeSetup(fixture);
254+
assert.isFalse(rule.matches(target, axe.utils.getNodeFromTree(target)));
255+
});
256+
241257
it("should not match a disabled input's label - implicit label (input)", function() {
242258
fixture.innerHTML = '<label>Test<input type="text" disabled></label>';
243259
var target = fixture.querySelector('label');

0 commit comments

Comments
 (0)