Skip to content

Commit

Permalink
fix(link-in-text-block): don't match style or script text (#3775)
Browse files Browse the repository at this point in the history
* fix(link-in-text-block): don't match style or script text

* fake img
  • Loading branch information
straker authored Nov 9, 2022
1 parent d11aed8 commit ab877f9
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 32 deletions.
21 changes: 16 additions & 5 deletions lib/checks/color/link-in-text-block-evaluate.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ function linkInTextBlockEvaluate(node, options) {
// Compute contrasts, giving preference to foreground color and doing as little work as possible
var textContrast =
nodeColor && parentColor ? getContrast(nodeColor, parentColor) : undefined;
if (textContrast) {
textContrast = Math.floor(textContrast * 100) / 100;
}

if (textContrast && textContrast >= requiredContrastRatio) {
return true;
Expand All @@ -61,6 +64,10 @@ function linkInTextBlockEvaluate(node, options) {
? getContrast(nodeBackgroundColor, parentBackgroundColor)
: undefined;

if (backgroundContrast) {
backgroundContrast = Math.floor(backgroundContrast * 100) / 100;
}

if (backgroundContrast && backgroundContrast >= requiredContrastRatio) {
return true;
}
Expand All @@ -80,13 +87,17 @@ function linkInTextBlockEvaluate(node, options) {
}

// Report bgContrast only if the background changes but text color stays the same
if (textContrast === 1.0 && backgroundContrast > 1.0) {
if (textContrast === 1 && backgroundContrast > 1) {
this.data({
messageKey: 'bgContrast',
contrastRatio: backgroundContrast,
requiredContrastRatio,
nodeBackgroundColor,
parentBackgroundColor
nodeBackgroundColor: nodeBackgroundColor
? nodeBackgroundColor.toHexString()
: undefined,
parentBackgroundColor: parentBackgroundColor
? parentBackgroundColor.toHexString()
: undefined
});
return false;
}
Expand All @@ -95,8 +106,8 @@ function linkInTextBlockEvaluate(node, options) {
messageKey: 'fgContrast',
contrastRatio: textContrast,
requiredContrastRatio,
nodeColor,
parentColor
nodeColor: nodeColor ? nodeColor.toHexString() : undefined,
parentColor: parentColor ? parentColor.toHexString() : undefined
});
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/link-in-text-block-matches.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { sanitize } from '../commons/text';
import { isVisibleOnScreen, isInTextBlock } from '../commons/dom';

function linkInTextBlockMatches(node) {
var text = sanitize(node.textContent);
var text = sanitize(node.innerText);
var role = node.getAttribute('role');

if (role && role !== 'link') {
Expand Down
50 changes: 50 additions & 0 deletions test/checks/color/link-in-text-block.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,5 +303,55 @@ describe('link-in-text-block', function () {
);
assert.equal(checkContext._relatedNodes[0], linkElm.parentNode);
});

it('should return the proper values stored in data (fgContrast)', function () {
fixture.innerHTML =
'<div> <span style="display:block; color: #100" id="parent">' +
' <p style="display:inline"><a href="" id="link">' +
' link text ' +
' </a> inside block </p> inside block' +
'</span> outside block </div>';

axe.testUtils.flatTreeSetup(fixture);
var linkElm = document.getElementById('link');

axe.testUtils
.getCheckEvaluate('link-in-text-block')
.call(checkContext, linkElm);

assert.deepEqual(checkContext._data, {
messageKey: 'fgContrast',
contrastRatio: 2.18,
requiredContrastRatio: 3,
nodeColor: '#0000ee',
parentColor: '#110000'
});
});

it('should return the proper values stored in data (bgContrast)', function () {
var linkElm = getLinkElm(
{
color: 'black',
backgroundColor: 'white'
},
{
color: 'black',
backgroundColor: '#F0F0F0'
}
);
assert.isFalse(
axe.testUtils
.getCheckEvaluate('link-in-text-block')
.call(checkContext, linkElm)
);

assert.deepEqual(checkContext._data, {
messageKey: 'bgContrast',
contrastRatio: 1.13,
requiredContrastRatio: 3,
nodeBackgroundColor: '#ffffff',
parentBackgroundColor: '#f0f0f0'
});
});
});
});
12 changes: 12 additions & 0 deletions test/integration/rules/link-in-text-block/link-in-text-block.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ <h1>General applicability tests</h1>
<a href="#" id="ignore9">Link text</a>
</p>

<p>
hello world, goodbye world
<a href="#" id="ignore10" style="text-decoration: none; background: #eee">
<style>
a {
color: #333;
}
</style>
<img width="50px" height="50px" src="some-img.png" alt="" />
</a>
</p>

<h1>Default styling tests</h1>

<p style="color: black">
Expand Down
67 changes: 41 additions & 26 deletions test/rule-matches/link-in-text-block-matches.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,82 @@
describe('link-in-text-block-matches', function () {
describe('link-in-text-block-matches', () => {
'use strict';

var fixture = document.getElementById('fixture');
var fixtureSetup = axe.testUtils.fixtureSetup;
var rule;
const { fixtureSetup } = axe.testUtils;
const rule = axe.utils.getRule('link-in-text-block');

beforeEach(function () {
rule = axe.utils.getRule('link-in-text-block');
});

afterEach(function () {
fixture.innerHTML = '';
});

it('should return true if link is in text block', function () {
it('should return true if link is in text block', () => {
fixtureSetup(
'<p>Some paragraph with text <a id="target" href="#">world</a></p>'
);
var node = document.getElementById('target');
const node = document.getElementById('target');
assert.isTrue(rule.matches(node));
});

it('should return false if element has a non-link role', function () {
it('should return false if element has a non-link role', () => {
fixtureSetup(
'<p>Some paragraph with text <a id="target" href="#" role="button">hello</a></p>'
);
var node = document.getElementById('target');
const node = document.getElementById('target');
assert.isFalse(rule.matches(node));
});

it('should should return false if element does not have text', function () {
it('should should return false if element does not have text', () => {
fixtureSetup(
'<p>Some paragraph with text <a id="target" href="#"></a></p>'
);
var node = document.getElementById('target');
const node = document.getElementById('target');
assert.isFalse(rule.matches(node));
});

it('should return false if element has <style>', () => {
fixtureSetup(`
<p>Some paragraph with text
<a id="target" href="#">
<style>a { color: #333 }</style>
</a>
</p>
`);
const node = document.getElementById('target');
assert.isFalse(rule.matches(node));
});

it('should return false if element has <script>', () => {
fixtureSetup(`
<p>Some paragraph with text
<a id="target" href="#">
<script>console.log('foo')</script>
</a>
</p>
`);
const node = document.getElementById('target');
assert.isFalse(rule.matches(node));
});

it('should return false if element is hidden', function () {
it('should return false if element is hidden', () => {
fixtureSetup(
'<p>Some paragraph with text <a id="target" href="#"" style="display: none">hello</a></p>'
);
var node = document.getElementById('target');
const node = document.getElementById('target');
assert.isFalse(rule.matches(node));
});

it('should return false if link is not in text block', function () {
it('should return false if link is not in text block', () => {
fixtureSetup('<a id="target" href="#">hello</a>');
var node = document.getElementById('target');
const node = document.getElementById('target');
assert.isFalse(rule.matches(node));
});

it('should return false if link is only text in block', function () {
it('should return false if link is only text in block', () => {
fixtureSetup('<p><a id="target" href="#">world</a></p>');
var node = document.getElementById('target');
const node = document.getElementById('target');
assert.isFalse(rule.matches(node));
});

it('should return false if link is display block', function () {
it('should return false if link is display block', () => {
fixtureSetup(
'<p>Some paragraph with text <a id="target" href="#" style="display: block">world</a></p>'
);
var node = document.getElementById('target');
const node = document.getElementById('target');
assert.isFalse(rule.matches(node));
});
});

0 comments on commit ab877f9

Please sign in to comment.