Skip to content

Commit e5beae8

Browse files
authored
Fixed an issue with context selector not at the beginning (#2498)
1 parent 63a0a6c commit e5beae8

File tree

9 files changed

+97
-11
lines changed

9 files changed

+97
-11
lines changed

.changeset/famous-ghosts-roll.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@emotion/cache': patch
3+
'@emotion/css': patch
4+
'@emotion/react': patch
5+
---
6+
7+
Fixed an edge case issue with incorrect rules being generated. When a context selector (`&`) was used not at the beginning of a selector (which is not valid SCSS but is allowed by the Stylis parser that we are using) within a group of selectors containing a pseudoclass then it was not replaced correctly with the current context selector.

packages/babel-plugin/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"escape-string-regexp": "^4.0.0",
2525
"find-root": "^1.1.0",
2626
"source-map": "^0.5.7",
27-
"stylis": "^4.0.3"
27+
"stylis": "^4.0.10"
2828
},
2929
"peerDependencies": {
3030
"@babel/core": "^7.0.0"

packages/cache/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"@emotion/sheet": "^1.0.0",
2020
"@emotion/utils": "^1.0.0",
2121
"@emotion/weak-memoize": "^0.2.5",
22-
"stylis": "^4.0.3"
22+
"stylis": "^4.0.10"
2323
},
2424
"devDependencies": {
2525
"@emotion/hash": "*",

packages/cache/src/stylis-plugins.js

+31-3
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,37 @@ import {
77
token,
88
char,
99
from,
10-
identifier,
1110
peek,
12-
position
11+
position,
12+
slice
1313
} from 'stylis'
1414

1515
const last = arr => (arr.length ? arr[arr.length - 1] : null)
1616

17+
// based on https://github.com/thysultan/stylis.js/blob/e6843c373ebcbbfade25ebcc23f540ed8508da0a/src/Tokenizer.js#L239-L244
18+
const identifierWithPointTracking = (begin, points, index) => {
19+
let previous = 0
20+
let character = 0
21+
22+
while (true) {
23+
previous = character
24+
character = peek()
25+
26+
// &\f
27+
if (previous === 38 && character === 12) {
28+
points[index] = 1
29+
}
30+
31+
if (token(character)) {
32+
break
33+
}
34+
35+
next()
36+
}
37+
38+
return slice(begin, position)
39+
}
40+
1741
const toRules = (parsed, points) => {
1842
// pretend we've started with a comma
1943
let index = -1
@@ -30,7 +54,11 @@ const toRules = (parsed, points) => {
3054
// it's very unlikely for this sequence to actually appear in a different context, so we just leverage this fact here
3155
points[index] = 1
3256
}
33-
parsed[index] += identifier(position - 1)
57+
parsed[index] += identifierWithPointTracking(
58+
position - 1,
59+
points,
60+
index
61+
)
3462
break
3563
case 2:
3664
parsed[index] += delimit(character)

packages/css-prettifier/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"repository": "https://github.com/emotion-js/emotion/tree/main/packages/css-prettifier",
1717
"dependencies": {
1818
"@emotion/memoize": "^0.7.4",
19-
"stylis": "^4.0.3"
19+
"stylis": "^4.0.10"
2020
},
2121
"devDependencies": {},
2222
"publishConfig": {

packages/css/test/__snapshots__/selectivity.test.js.snap

+20
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,26 @@ exports[`css media query with nested selector without declarations on root 1`] =
124124
}"
125125
`;
126126

127+
exports[`css should allow a weird class containing & when pseudoclass appears in the selector group 1`] = `
128+
".css-13p6h3h:hover,
129+
.css-13p6h3h .t\\\\&t {
130+
background: blue;
131+
}"
132+
`;
133+
134+
exports[`css should allow for context selector being appended to an element type 1`] = `
135+
"a.css-ciaq1 {
136+
background: blue;
137+
}"
138+
`;
139+
140+
exports[`css should allow for context selector being appended to an element type when pseudoclass appears in the selector group 1`] = `
141+
".css-miigdc:hover,
142+
a.css-miigdc {
143+
background: blue;
144+
}"
145+
`;
146+
127147
exports[`orphaned pseudos in nested atrules 1`] = `
128148
"@media (max-width: 400px) {
129149
@supports (display: grid) {

packages/css/test/selectivity.test.js

+31
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,37 @@ describe('css', () => {
117117
`
118118
expect(sheet).toMatchSnapshot()
119119
})
120+
121+
// this isn't compatible with SCSS but is allowed in Stylis
122+
test('should allow for context selector being appended to an element type', () => {
123+
css`
124+
a& {
125+
background: blue;
126+
}
127+
`
128+
expect(sheet).toMatchSnapshot()
129+
})
130+
131+
// #2488
132+
test('should allow for context selector being appended to an element type when pseudoclass appears in the selector group', () => {
133+
css`
134+
&:hover,
135+
a& {
136+
background: blue;
137+
}
138+
`
139+
expect(sheet).toMatchSnapshot()
140+
})
141+
142+
test('should allow a weird class containing & when pseudoclass appears in the selector group', () => {
143+
css`
144+
&:hover,
145+
.t\\&t {
146+
background: blue;
147+
}
148+
`
149+
expect(sheet).toMatchSnapshot()
150+
})
120151
})
121152

122153
describe('orphaned pseudos', () => {

packages/jest/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"@emotion/css-prettifier": "^1.0.0",
2222
"chalk": "^4.1.0",
2323
"specificity": "^0.4.1",
24-
"stylis": "^4.0.3"
24+
"stylis": "^4.0.10"
2525
},
2626
"peerDependencies": {
2727
"@types/jest": "^26.0.14",

yarn.lock

+4-4
Original file line numberDiff line numberDiff line change
@@ -26417,10 +26417,10 @@ stylehacks@^4.0.0:
2641726417
postcss "^7.0.0"
2641826418
postcss-selector-parser "^3.0.0"
2641926419

26420-
stylis@^4.0.3:
26421-
version "4.0.3"
26422-
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.3.tgz#0d714765f3f694a685550f0c45411ebf90a9bded"
26423-
integrity sha512-iAxdFyR9cHKp4H5M2dJlDnvcb/3TvPprzlKjvYVbH7Sh+y8hjY/mUu/ssdcvVz6Z4lKI3vsoS0jAkMYmX7ozfA==
26420+
stylis@^4.0.10:
26421+
version "4.0.10"
26422+
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240"
26423+
integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==
2642426424

2642526425
sudo-prompt@^8.2.0:
2642626426
version "8.2.5"

0 commit comments

Comments
 (0)