From 949f4f8dfccd018b88f929bd650dc8920ce4f6f0 Mon Sep 17 00:00:00 2001
From: Wilco Fiers
Date: Mon, 15 May 2023 13:22:43 +0200
Subject: [PATCH] fix(link-in-text-block): set links with pseudo-content for
review (#4005)
* fix(link-in-text-block): set links with pseudo-content for review
* :robot: Automated formatting fixes
* fix typo
---
.../link-in-text-block-style-evaluate.js | 31 ++++++--
.../color/link-in-text-block-style.json | 4 +
locales/_template.json | 4 +
test/checks/color/link-in-text-block-style.js | 77 +++++++++++++------
.../link-in-text-block.html | 18 +++++
.../link-in-text-block.json | 5 +-
6 files changed, 106 insertions(+), 33 deletions(-)
diff --git a/lib/checks/color/link-in-text-block-style-evaluate.js b/lib/checks/color/link-in-text-block-style-evaluate.js
index aaf6fec010..e07929ea41 100644
--- a/lib/checks/color/link-in-text-block-style-evaluate.js
+++ b/lib/checks/color/link-in-text-block-style-evaluate.js
@@ -9,12 +9,8 @@ const blockLike = [
'grid',
'inline-block'
];
-function isBlock(elm) {
- var display = window.getComputedStyle(elm).getPropertyValue('display');
- return blockLike.indexOf(display) !== -1 || display.substr(0, 6) === 'table-';
-}
-function linkInTextBlockStyleEvaluate(node) {
+export default function linkInTextBlockStyleEvaluate(node) {
if (isBlock(node)) {
return false;
}
@@ -30,7 +26,28 @@ function linkInTextBlockStyleEvaluate(node) {
this.relatedNodes([parentBlock]);
- return elementIsDistinct(node, parentBlock);
+ if (elementIsDistinct(node, parentBlock)) {
+ return true;
+ }
+ if (hasPseudoContent(node)) {
+ this.data({ messageKey: 'pseudoContent' });
+ return undefined;
+ }
+ return false;
+}
+
+function isBlock(elm) {
+ var display = window.getComputedStyle(elm).getPropertyValue('display');
+ return blockLike.indexOf(display) !== -1 || display.substr(0, 6) === 'table-';
}
-export default linkInTextBlockStyleEvaluate;
+function hasPseudoContent(node) {
+ for (const pseudo of ['before', 'after']) {
+ const style = window.getComputedStyle(node, `:${pseudo}`);
+ const content = style.getPropertyValue('content');
+ if (content !== 'none') {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/lib/checks/color/link-in-text-block-style.json b/lib/checks/color/link-in-text-block-style.json
index 566f1cd715..bb909baf12 100644
--- a/lib/checks/color/link-in-text-block-style.json
+++ b/lib/checks/color/link-in-text-block-style.json
@@ -5,6 +5,10 @@
"impact": "serious",
"messages": {
"pass": "Links can be distinguished from surrounding text by visual styling",
+ "incomplete": {
+ "default": "Check if the link needs styling to distinguish it from nearby text",
+ "pseudoContent": "Check if the link's pseudo style is sufficient to distinguish it from the surrounding text"
+ },
"fail": "The link has no styling (such as underline) to distinguish it from the surrounding text"
}
}
diff --git a/locales/_template.json b/locales/_template.json
index 20d4246ba6..3cb970b002 100644
--- a/locales/_template.json
+++ b/locales/_template.json
@@ -623,6 +623,10 @@
},
"link-in-text-block-style": {
"pass": "Links can be distinguished from surrounding text by visual styling",
+ "incomplete": {
+ "default": "Check if the link needs styling to distinguish it from nearby text",
+ "pseudoContent": "Check if the link's pseudo style is sufficient to distinguish it from the surrounding text"
+ },
"fail": "The link has no styling (such as underline) to distinguish it from the surrounding text"
},
"link-in-text-block": {
diff --git a/test/checks/color/link-in-text-block-style.js b/test/checks/color/link-in-text-block-style.js
index 2f79c958e5..2fdb94fc4a 100644
--- a/test/checks/color/link-in-text-block-style.js
+++ b/test/checks/color/link-in-text-block-style.js
@@ -7,6 +7,11 @@ describe('link-in-text-block-style', function () {
var checkContext = axe.testUtils.MockCheckContext();
+ const { queryFixture } = axe.testUtils;
+ const linkInBlockStyleCheck = axe.testUtils.getCheckEvaluate(
+ 'link-in-text-block-style'
+ );
+
before(function () {
styleElm = document.createElement('style');
document.head.appendChild(styleElm);
@@ -107,11 +112,7 @@ describe('link-in-text-block-style', function () {
axe.testUtils.flatTreeSetup(fixture);
var linkElm = document.getElementById('link');
- assert.isFalse(
- axe.testUtils
- .getCheckEvaluate('link-in-text-block-style')
- .call(checkContext, linkElm)
- );
+ assert.isFalse(linkInBlockStyleCheck.call(checkContext, linkElm));
});
(shadowSupport.v1 ? it : xit)(
@@ -126,11 +127,7 @@ describe('link-in-text-block-style', function () {
axe.testUtils.flatTreeSetup(fixture);
- assert.isTrue(
- axe.testUtils
- .getCheckEvaluate('link-in-text-block-style')
- .call(checkContext, linkElm)
- );
+ assert.isTrue(linkInBlockStyleCheck.call(checkContext, linkElm));
}
);
@@ -148,11 +145,7 @@ describe('link-in-text-block-style', function () {
axe.testUtils.flatTreeSetup(fixture);
var linkElm = div.querySelector('a');
- assert.isTrue(
- axe.testUtils
- .getCheckEvaluate('link-in-text-block-style')
- .call(checkContext, linkElm)
- );
+ assert.isTrue(linkInBlockStyleCheck.call(checkContext, linkElm));
}
);
});
@@ -160,24 +153,58 @@ describe('link-in-text-block-style', function () {
describe('links distinguished through style', function () {
it('returns false if link style matches parent', function () {
var linkElm = getLinkElm({});
- assert.isFalse(
- axe.testUtils
- .getCheckEvaluate('link-in-text-block-style')
- .call(checkContext, linkElm)
- );
+ assert.isFalse(linkInBlockStyleCheck.call(checkContext, linkElm));
assert.equal(checkContext._relatedNodes[0], linkElm.parentNode);
+ assert.isNull(checkContext._data);
});
it('returns true if link has underline', function () {
var linkElm = getLinkElm({
textDecoration: 'underline'
});
- assert.isTrue(
- axe.testUtils
- .getCheckEvaluate('link-in-text-block-style')
- .call(checkContext, linkElm)
- );
+ assert.isTrue(linkInBlockStyleCheck.call(checkContext, linkElm));
assert.equal(checkContext._relatedNodes[0], linkElm.parentNode);
+ assert.isNull(checkContext._data);
+ });
+
+ it('returns undefined when the link has a :before pseudo element', function () {
+ const link = queryFixture(`
+
+ A link inside a block of text
+ `).actualNode;
+ const result = linkInBlockStyleCheck.call(checkContext, link);
+ assert.isUndefined(result);
+ assert.deepEqual(checkContext._data, { messageKey: 'pseudoContent' });
+ assert.equal(checkContext._relatedNodes[0], link.parentNode);
+ });
+
+ it('returns undefined when the link has a :after pseudo element', function () {
+ const link = queryFixture(`
+
+ A link inside a block of text
+ `).actualNode;
+ const result = linkInBlockStyleCheck.call(checkContext, link);
+ assert.isUndefined(result);
+ assert.deepEqual(checkContext._data, { messageKey: 'pseudoContent' });
+ assert.equal(checkContext._relatedNodes[0], link.parentNode);
+ });
+
+ it('does not return undefined when the pseudo element content is none', function () {
+ const link = queryFixture(`
+
+ A link inside a block of text
+ `).actualNode;
+ const result = linkInBlockStyleCheck.call(checkContext, link);
+ assert.isFalse(result);
});
});
});
diff --git a/test/integration/rules/link-in-text-block/link-in-text-block.html b/test/integration/rules/link-in-text-block/link-in-text-block.html
index 260a259e4f..9d69d819d0 100644
--- a/test/integration/rules/link-in-text-block/link-in-text-block.html
+++ b/test/integration/rules/link-in-text-block/link-in-text-block.html
@@ -149,3 +149,21 @@ Incomplete tests
Link test
+
+
+
+ Lorem ipsum dolor sit.
+
diff --git a/test/integration/rules/link-in-text-block/link-in-text-block.json b/test/integration/rules/link-in-text-block/link-in-text-block.json
index 366b5f07dd..e4e2c7dfaa 100644
--- a/test/integration/rules/link-in-text-block/link-in-text-block.json
+++ b/test/integration/rules/link-in-text-block/link-in-text-block.json
@@ -14,5 +14,8 @@
["#pass-text-color"],
["#pass-same-colors"]
],
- "incomplete": [["#incomplete-low-contrast-parent-has-gradient"]]
+ "incomplete": [
+ ["#incomplete-low-contrast-parent-has-gradient"],
+ ["#incomplete-pseudo-before"]
+ ]
}