Skip to content

Commit f98f8bd

Browse files
mfairchild365marcysutton
authored andcommitted
fix(color-contrast): Include THEAD and TBODY in contrast checks (#514)
1 parent 6296a5f commit f98f8bd

File tree

2 files changed

+34
-15
lines changed

2 files changed

+34
-15
lines changed

lib/commons/color/get-background-color.js

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -121,29 +121,34 @@ function elmPartiallyObscured(elm, bgElm, bgColor) {
121121
* @param {Element} elm
122122
*/
123123
function includeMissingElements(elmStack, elm) {
124-
const elementMap = {'TD': 'TR', 'TH': 'TR', 'INPUT': 'LABEL'};
124+
const elementMap = {'TD': ['TR', 'TBODY'], 'TH': ['TR', 'THEAD'], 'INPUT': ['LABEL']};
125125
const tagArray = elmStack.map((elm) => {
126126
return elm.tagName;
127127
});
128128
let bgNodes = elmStack;
129+
//jshint maxdepth:7
129130
for (let candidate in elementMap) {
130-
// check that TR or LABEL has paired nodeName from elementMap, but don't expect elm to be that candidate
131+
// check that TR or LABEL has paired nodeName from elementMap, but don't expect elm to be that candidate
131132
if (tagArray.includes(candidate)) {
132-
// look up the tree for a matching candidate
133-
let ancestorMatch = axe.commons.dom.findUp(elm, elementMap[candidate]);
134-
if (ancestorMatch && elmStack.indexOf(ancestorMatch) === -1) {
135-
// found an ancestor not in elmStack, and it overlaps
136-
let overlaps = axe.commons.dom.visuallyOverlaps(elm.getBoundingClientRect(), ancestorMatch);
137-
if (overlaps) {
138-
// if target is in the elementMap, use its position.
139-
bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, ancestorMatch);
133+
for (let candidateIndex in elementMap[candidate]) {
134+
if (candidate.hasOwnProperty(candidateIndex)) {
135+
// look up the tree for a matching candidate
136+
let ancestorMatch = axe.commons.dom.findUp(elm, elementMap[candidate][candidateIndex]);
137+
if (ancestorMatch && elmStack.indexOf(ancestorMatch) === -1) {
138+
// found an ancestor not in elmStack, and it overlaps
139+
let overlaps = axe.commons.dom.visuallyOverlaps(elm.getBoundingClientRect(), ancestorMatch);
140+
if (overlaps) {
141+
// if target is in the elementMap, use its position.
142+
bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, ancestorMatch);
143+
}
144+
}
145+
// tagName matches value
146+
// (such as LABEL, when matching itself. It should be in the list, but Phantom skips it)
147+
if (elm.tagName === elementMap[candidate][candidateIndex] && tagArray.indexOf(elm.tagName) === -1) {
148+
bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, elm);
149+
}
140150
}
141151
}
142-
// tagName matches value
143-
// (such as LABEL, when matching itself. It should be in the list, but Phantom skips it)
144-
if (elm.tagName === elementMap[candidate] && tagArray.indexOf(elm.tagName) === -1) {
145-
bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, elm);
146-
}
147152
}
148153
}
149154
return bgNodes;

test/checks/color/color-contrast.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,20 @@ describe('color-contrast', function () {
190190
assert.isTrue(result);
191191
});
192192

193+
it('should return true when there is sufficient contrast based on thead', function () {
194+
fixture.innerHTML = '<table><thead style="background: #d00d2c"><tr><th id="target" style="color: #fff; padding: .5em">Col 1</th></tr></thead></table>';
195+
var target = fixture.querySelector('#target');
196+
assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
197+
assert.deepEqual(checkContext._relatedNodes, []);
198+
});
199+
200+
it('should return true when there is sufficient contrast based on tbody', function () {
201+
fixture.innerHTML = '<table><tbody style="background: #d00d2c"><tr><td id="target" style="color: #fff; padding: .5em">Col 1</td></tr></tbody></table>';
202+
var target = fixture.querySelector('#target');
203+
assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
204+
assert.deepEqual(checkContext._relatedNodes, []);
205+
});
206+
193207
it('should return undefined if element overlaps text content', function () {
194208
fixture.innerHTML = '<div style="background-color: white; height: 60px; width: 80px; border:1px solid;position: relative;">' +
195209
'<div id="target" style="color: white; height: 40px; width: 60px; border:1px solid red;">Hi</div>' +

0 commit comments

Comments
 (0)