Skip to content

Commit 08767a5

Browse files
authored
any-link : improve fallbacks for area (#364)
1 parent 4c66948 commit 08767a5

8 files changed

+193
-16
lines changed

cli/csstools-cli/src/plugins/postcss-preset-env.ts

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export default function postcssPresetEnv() {
1010
'features',
1111
'browsers',
1212
'autoprefixer',
13+
'preserve',
1314
'importFrom',
1415
'exportTo',
1516
'enableClientSidePolyfills',

plugins/postcss-pseudo-class-any-link/CHANGELOG.md

+17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
# Changes to PostCSS Pseudo Class Any Link
22

3+
### Unreleased
4+
5+
- Improve handling of `<area>` fallbacks for IE and Edge.
6+
7+
```diff
8+
a:any-link {
9+
text-decoration: none;
10+
}
11+
12+
/* becomes */
13+
14+
- a:link, a:visited, aarea[href] {
15+
+ a:link, a:visited {
16+
text-decoration: none;
17+
}
18+
```
19+
320
### 7.1.2 (April 4, 2022)
421

522
- Improved : compound selector order with pseudo elements

plugins/postcss-pseudo-class-any-link/src/replace-any-link.js

+51-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { sortCompoundSelectorsInsideComplexSelector } from './compound-selector-
44
const linkAST = parser().astSync(':link').nodes[0];
55
const visitedAST = parser().astSync(':visited').nodes[0];
66
const areaHrefAST = parser().astSync('area[href]').nodes[0];
7+
const hrefAST = parser().astSync('[href]').nodes[0];
78

89
export function replaceAnyLink(rule, result, preserve, areaHrefNeedsFixing) {
910
let updatedSelectors = [];
@@ -53,26 +54,33 @@ function modifiedSelector(selector, areaHrefNeedsFixing) {
5354

5455
// update the selector
5556
parser((selectorsAST) => {
56-
let anyLinkCount = 0;
57+
let replacements = [];
5758
selectorsAST.walkPseudos((pseudo) => {
5859
if (pseudo.value !== ':any-link' || (pseudo.nodes && pseudo.nodes.length)) {
5960
return;
6061
}
6162

62-
anyLinkCount++;
63-
});
63+
if (!areaHrefNeedsFixing) {
64+
replacements.push([linkAST.clone(), visitedAST.clone()]);
65+
return;
66+
}
6467

65-
if (!anyLinkCount) {
66-
return;
67-
}
68+
const tags = getTagElementsNextToPseudo(pseudo);
69+
if (tags.includes('area')) {
70+
replacements.push([linkAST.clone(), visitedAST.clone(), hrefAST.clone()]);
71+
return;
72+
}
6873

69-
let replacements = [];
70-
for (let i = 0; i < anyLinkCount; i++) {
71-
if (areaHrefNeedsFixing) {
72-
replacements.push([linkAST.clone(), visitedAST.clone(), areaHrefAST.clone()]);
73-
} else {
74+
if (tags.length) {
7475
replacements.push([linkAST.clone(), visitedAST.clone()]);
76+
return;
7577
}
78+
79+
replacements.push([linkAST.clone(), visitedAST.clone(), areaHrefAST.clone()]);
80+
});
81+
82+
if (!replacements.length) {
83+
return;
7684
}
7785

7886
let replacementsCartesianProduct = cartesianProduct(...replacements);
@@ -121,3 +129,35 @@ function cartesianProduct(...args) {
121129
helper([], 0);
122130
return r;
123131
}
132+
133+
function getTagElementsNextToPseudo(pseudo) {
134+
let tags = [];
135+
136+
let prev = pseudo.prev();
137+
while (prev) {
138+
if (prev.type === 'combinator') {
139+
break;
140+
}
141+
142+
if (prev.type === 'tag') {
143+
tags.push(prev.value);
144+
}
145+
146+
prev = prev.prev();
147+
}
148+
149+
let next = pseudo.next();
150+
while (next) {
151+
if (next.type === 'combinator') {
152+
break;
153+
}
154+
155+
if (next.type === 'tag') {
156+
tags.push(next.value);
157+
}
158+
159+
next = next.next();
160+
}
161+
162+
return tags;
163+
}

plugins/postcss-pseudo-class-any-link/test/basic.css

+20
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,23 @@ ul a:any-link > span {
3030
::before:any-link {
3131
order: 8;
3232
}
33+
34+
a:any-link {
35+
order: 9;
36+
}
37+
38+
area:any-link {
39+
order: 10;
40+
}
41+
42+
area :any-link {
43+
order: 11;
44+
}
45+
46+
area > :any-link {
47+
order: 12;
48+
}
49+
50+
div:any-link {
51+
order: 13;
52+
}

plugins/postcss-pseudo-class-any-link/test/basic.expect.css

+40
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,43 @@ ul a:any-link > span {
6161
::before:any-link {
6262
order: 8;
6363
}
64+
65+
a:link, a:visited {
66+
order: 9;
67+
}
68+
69+
a:any-link {
70+
order: 9;
71+
}
72+
73+
area:link, area:visited {
74+
order: 10;
75+
}
76+
77+
area:any-link {
78+
order: 10;
79+
}
80+
81+
area :link, area :visited {
82+
order: 11;
83+
}
84+
85+
area :any-link {
86+
order: 11;
87+
}
88+
89+
area > :link, area > :visited {
90+
order: 12;
91+
}
92+
93+
area > :any-link {
94+
order: 12;
95+
}
96+
97+
div:link, div:visited {
98+
order: 13;
99+
}
100+
101+
div:any-link {
102+
order: 13;
103+
}

plugins/postcss-pseudo-class-any-link/test/basic.preserve-false.expect.css

+20
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,23 @@ ul a:visited > span {
3232
:link::before, :visited::before {
3333
order: 8;
3434
}
35+
36+
a:link, a:visited {
37+
order: 9;
38+
}
39+
40+
area:link, area:visited {
41+
order: 10;
42+
}
43+
44+
area :link, area :visited {
45+
order: 11;
46+
}
47+
48+
area > :link, area > :visited {
49+
order: 12;
50+
}
51+
52+
div:link, div:visited {
53+
order: 13;
54+
}

plugins/postcss-pseudo-class-any-link/test/basic.sub-features-area-href.expect.css

+41-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
:visited,
1111
area[href],
1212
ul a:link > span,
13-
ul a:visited > span,
14-
ul aarea[href] > span {
13+
ul a:visited > span {
1514
order: 2;
1615
}
1716

@@ -63,3 +62,43 @@ ul a:any-link > span {
6362
::before:any-link {
6463
order: 8;
6564
}
65+
66+
a:link, a:visited {
67+
order: 9;
68+
}
69+
70+
a:any-link {
71+
order: 9;
72+
}
73+
74+
area:link, area:visited, area[href] {
75+
order: 10;
76+
}
77+
78+
area:any-link {
79+
order: 10;
80+
}
81+
82+
area :link, area :visited, area area[href] {
83+
order: 11;
84+
}
85+
86+
area :any-link {
87+
order: 11;
88+
}
89+
90+
area > :link, area > :visited, area > area[href] {
91+
order: 12;
92+
}
93+
94+
area > :any-link {
95+
order: 12;
96+
}
97+
98+
div:link, div:visited {
99+
order: 13;
100+
}
101+
102+
div:any-link {
103+
order: 13;
104+
}

plugins/postcss-pseudo-class-any-link/test/generated-selector-cases.sub-features-area-href.expect.css

+3-3
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
order: 19;
7979
}
8080

81-
button:link, button:visited, buttonarea[href] {
81+
button:link, button:visited {
8282
order: 20;
8383
}
8484

@@ -430,7 +430,7 @@ button {
430430
order: 99;
431431
}
432432

433-
__foo:link, __foo:visited, __fooarea[href] {
433+
__foo:link, __foo:visited {
434434
order: 100;
435435
}
436436

@@ -978,7 +978,7 @@ foo[baz=":any-link"] {
978978
order: 224;
979979
}
980980

981-
__:link, __:visited, __area[href] {
981+
__:link, __:visited {
982982
order: 225;
983983
}
984984

0 commit comments

Comments
 (0)