Skip to content

Commit 6d2300f

Browse files
authored
improve pseudo element handling (#318)
1 parent 9c210b6 commit 6d2300f

21 files changed

+206
-144
lines changed

plugins/postcss-is-pseudo-class/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes to PostCSS Is Pseudo Class
22

3+
### Unreleased (patch)
4+
5+
- Improved : compound selector order with pseudo elements
6+
37
### 2.0.1 (March 4, 2022)
48

59
- Preserve selector order as much as possible. Fixes issues where pseudo elements `::before` were moved.

plugins/postcss-is-pseudo-class/src/split-selectors/compound-selector-order.ts

Lines changed: 16 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -47,68 +47,38 @@ export function sortCompoundSelector(node) {
4747

4848
node.nodes.sort((a, b) => {
4949
if (a.type === 'selector' && b.type === 'selector' && a.nodes.length && b.nodes.length) {
50-
if (a.nodes[0].type === b.nodes[0].type) {
51-
return 0;
52-
}
53-
54-
if (selectorTypeOrder[a.nodes[0].type] < selectorTypeOrder[b.nodes[0].type]) {
55-
return -1;
56-
}
57-
58-
if (selectorTypeOrder[a.nodes[0].type] > selectorTypeOrder[b.nodes[0].type]) {
59-
return 1;
60-
}
50+
return selectorTypeOrder(a.nodes[0].value, a.nodes[0].type) - selectorTypeOrder(b.nodes[0].value, b.nodes[0].type);
6151
}
6252

6353
if (a.type === 'selector' && a.nodes.length) {
64-
if (a.nodes[0].type === b.type) {
65-
return 0;
66-
}
67-
68-
if (selectorTypeOrder[a.nodes[0].type] < selectorTypeOrder[b.type]) {
69-
return -1;
70-
}
71-
72-
if (selectorTypeOrder[a.nodes[0].type] > selectorTypeOrder[b.type]) {
73-
return 1;
74-
}
54+
return selectorTypeOrder(a.nodes[0].value, a.nodes[0].type) - selectorTypeOrder(b.value, b.type);
7555
}
7656

7757
if (b.type === 'selector' && b.nodes.length) {
78-
if (a.type === b.nodes[0].type) {
79-
return 0;
80-
}
81-
82-
if (selectorTypeOrder[a.type] < selectorTypeOrder[b.nodes[0].type]) {
83-
return -1;
84-
}
85-
86-
if (selectorTypeOrder[a.type] > selectorTypeOrder[b.nodes[0].type]) {
87-
return 1;
88-
}
89-
}
90-
91-
if (a.type === b.type) {
92-
return 0;
58+
return selectorTypeOrder(a.value, a.type) - selectorTypeOrder(b.nodes[0].value, b.nodes[0].type);
9359
}
9460

95-
if (selectorTypeOrder[a.type] < selectorTypeOrder[b.type]) {
96-
return -1;
97-
}
98-
99-
return 1;
61+
return selectorTypeOrder(a.value, a.type) - selectorTypeOrder(b.value, b.type);
10062
});
10163
}
10264

103-
const selectorTypeOrder = {
65+
function selectorTypeOrder(selector, type) {
66+
if (type === 'pseudo' && selector && selector.indexOf('::') === 0) {
67+
return selectorTypeOrderIndex['pseudoElement'];
68+
}
69+
return selectorTypeOrderIndex[type];
70+
}
71+
72+
const selectorTypeOrderIndex = {
10473
universal: 0,
10574
tag: 1,
10675
id: 2,
10776
class: 3,
10877
attribute: 4,
109-
pseudo: 5,
110-
selector: 7,
78+
selector: 5,
79+
pseudo: 6,
80+
pseudoElement: 7,
11181
string: 8,
112-
root : 9,
82+
root: 9,
11383
comment: 10,
11484
};

plugins/postcss-is-pseudo-class/test/basic.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,7 @@ foo[baz=":is(.some, .other)"], .ok {
101101
:is(a, button):is(:hover, :focus)::before {
102102
order: 26;
103103
}
104+
105+
:is(::after, .foo):is(:hover, :focus) {
106+
order: 27;
107+
}

plugins/postcss-is-pseudo-class/test/basic.does-not-exist.expect.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,3 +325,19 @@ button:hover::before {
325325
button:focus::before {
326326
order: 26;
327327
}
328+
329+
:not(.something-random):hover::after {
330+
order: 27;
331+
}
332+
333+
:not(.something-random):focus::after {
334+
order: 27;
335+
}
336+
337+
.foo:hover {
338+
order: 27;
339+
}
340+
341+
.foo:focus {
342+
order: 27;
343+
}

plugins/postcss-is-pseudo-class/test/basic.expect.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,3 +325,19 @@ button:hover::before {
325325
button:focus::before {
326326
order: 26;
327327
}
328+
329+
:not(.does-not-exist):hover::after {
330+
order: 27;
331+
}
332+
333+
:not(.does-not-exist):focus::after {
334+
order: 27;
335+
}
336+
337+
.foo:hover {
338+
order: 27;
339+
}
340+
341+
.foo:focus {
342+
order: 27;
343+
}

plugins/postcss-is-pseudo-class/test/basic.oncomplex.warning.expect.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,3 +325,19 @@ button:hover::before {
325325
button:focus::before {
326326
order: 26;
327327
}
328+
329+
:not(.does-not-exist):hover::after {
330+
order: 27;
331+
}
332+
333+
:not(.does-not-exist):focus::after {
334+
order: 27;
335+
}
336+
337+
.foo:hover {
338+
order: 27;
339+
}
340+
341+
.foo:focus {
342+
order: 27;
343+
}

plugins/postcss-is-pseudo-class/test/basic.preserve.expect.css

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,3 +397,23 @@ button:focus::before {
397397
:is(a, button):is(:hover, :focus)::before {
398398
order: 26;
399399
}
400+
401+
:not(.does-not-exist):hover::after {
402+
order: 27;
403+
}
404+
405+
:not(.does-not-exist):focus::after {
406+
order: 27;
407+
}
408+
409+
.foo:hover {
410+
order: 27;
411+
}
412+
413+
.foo:focus {
414+
order: 27;
415+
}
416+
417+
:is(::after, .foo):is(:hover, :focus) {
418+
order: 27;
419+
}

plugins/postcss-nesting/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes to PostCSS Nesting
22

3+
### Unreleased (patch)
4+
5+
- Improved : compound selector order with pseudo elements
6+
37
### 10.1.3 (March 4, 2022)
48

59
- Avoid creating duplicate selectors containing only comments.

plugins/postcss-nesting/src/lib/merge-selectors/compound-selector-order.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,28 +57,28 @@ export function sortCompoundSelector(node) {
5757
// `h1.foo`
5858

5959
node.nodes.sort((a, b) => {
60-
if (a.type === b.type) {
61-
return 0;
62-
}
63-
64-
if (selectorTypeOrder[a.type] < selectorTypeOrder[b.type]) {
65-
return -1;
66-
}
67-
68-
return 1;
60+
return selectorTypeOrder(a.value, a.type) - selectorTypeOrder(b.value, b.type);
6961
});
7062
}
7163

72-
const selectorTypeOrder = {
64+
function selectorTypeOrder(selector, type) {
65+
if (type === 'pseudo' && selector && selector.indexOf('::') === 0) {
66+
return selectorTypeOrderIndex['pseudoElement'];
67+
}
68+
return selectorTypeOrderIndex[type];
69+
}
70+
71+
const selectorTypeOrderIndex = {
7372
universal: 0,
7473
tag: 1,
7574
id: 2,
7675
class: 3,
7776
attribute: 4,
78-
pseudo: 5,
79-
selector: 7,
77+
selector: 5,
78+
pseudo: 6,
79+
pseudoElement: 7,
8080
string: 8,
81-
root : 9,
81+
root: 9,
8282
comment: 10,
8383

8484
nesting: 9999,

plugins/postcss-nesting/test/basic.css

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ a {
104104
.b {
105105
&.c,
106106
&.d {
107-
&:before {
107+
&::before {
108108
order: 41;
109109
}
110110
}
@@ -119,27 +119,33 @@ a {
119119
/* leading : root */
120120
.comments {
121121
/* leading : 1 */
122-
order: 1;
122+
order: 61;
123123
/* trailing: 2 */
124124

125125
& .comment {
126-
order: 2;
126+
order: 62;
127127
}
128128

129129
/* loose comment */
130130
& .comment {
131-
order: 3;
131+
order: 63;
132132
}
133133

134134
/* leading : 4 */
135-
order: 4;
135+
order: 64;
136136
/* trailing: 5 */
137137

138138
& .comment {
139139
/* nested deeper */
140140

141141
& .comment {
142-
order: 5;
142+
order: 65;
143143
}
144144
}
145145
}
146+
147+
.pseudo-element {
148+
@nest ::before& {
149+
order: 71;
150+
}
151+
}

plugins/postcss-nesting/test/basic.expect.css

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ a b[a="a&b"] {
121121
order: 31;
122122
}
123123

124-
.a.c:before, .b.c:before, .a.d:before, .b.d:before {
124+
.a.c::before, .b.c::before, .a.d::before, .b.d::before {
125125
order: 41;
126126
}
127127

@@ -132,23 +132,27 @@ a b[a="a&b"] {
132132
/* leading : root */
133133
.comments {
134134
/* leading : 1 */
135-
order: 1
135+
order: 61
136136
/* trailing: 2 */
137137
}
138138
.comments .comment {
139-
order: 2;
139+
order: 62;
140140
}
141141
/* loose comment */
142142
.comments .comment {
143-
order: 3;
143+
order: 63;
144144
}
145145
.comments {
146146

147147
/* leading : 4 */
148-
order: 4
148+
order: 64
149149
/* trailing: 5 */
150150
}
151151
/* nested deeper */
152152
.comments .comment .comment {
153-
order: 5;
153+
order: 65;
154154
}
155+
156+
.pseudo-element::before {
157+
order: 71
158+
}

plugins/postcss-nesting/test/basic.no-is-pseudo-selector.expect.css

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ a b[a="a&b"] {
121121
order: 31;
122122
}
123123

124-
.a.c:before, .b.c:before, .a.d:before, .b.d:before {
124+
.a.c::before, .b.c::before, .a.d::before, .b.d::before {
125125
order: 41;
126126
}
127127

@@ -132,23 +132,27 @@ a b[a="a&b"] {
132132
/* leading : root */
133133
.comments {
134134
/* leading : 1 */
135-
order: 1
135+
order: 61
136136
/* trailing: 2 */
137137
}
138138
.comments .comment {
139-
order: 2;
139+
order: 62;
140140
}
141141
/* loose comment */
142142
.comments .comment {
143-
order: 3;
143+
order: 63;
144144
}
145145
.comments {
146146

147147
/* leading : 4 */
148-
order: 4
148+
order: 64
149149
/* trailing: 5 */
150150
}
151151
/* nested deeper */
152152
.comments .comment .comment {
153-
order: 5;
153+
order: 65;
154154
}
155+
156+
.pseudo-element::before {
157+
order: 71
158+
}

plugins/postcss-nesting/test/spec-examples.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ table.colortable td.c {
1111
}
1212

1313
table.colortable td:first-child,
14-
:first-child:is(table.colortable td)+td {
14+
:is(table.colortable td):first-child+td {
1515
border: 1px solid black
1616
}
1717

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes to PostCSS Pseudo Class Any Link
22

3+
### Unreleased (patch)
4+
5+
- Improved : compound selector order with pseudo elements
6+
37
### 7.1.1 (February 5, 2022)
48

59
- Improved `es module` and `commonjs` compatibility

0 commit comments

Comments
 (0)