Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/famous-ghosts-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@emotion/cache': patch
'@emotion/css': patch
'@emotion/react': patch
---

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.
2 changes: 1 addition & 1 deletion packages/babel-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"escape-string-regexp": "^4.0.0",
"find-root": "^1.1.0",
"source-map": "^0.5.7",
"stylis": "^4.0.3"
"stylis": "^4.0.10"
},
"peerDependencies": {
"@babel/core": "^7.0.0"
Expand Down
2 changes: 1 addition & 1 deletion packages/cache/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"@emotion/sheet": "^1.0.0",
"@emotion/utils": "^1.0.0",
"@emotion/weak-memoize": "^0.2.5",
"stylis": "^4.0.3"
"stylis": "^4.0.10"
},
"devDependencies": {
"@emotion/hash": "*",
Expand Down
34 changes: 31 additions & 3 deletions packages/cache/src/stylis-plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,37 @@ import {
token,
char,
from,
identifier,
peek,
position
position,
slice
} from 'stylis'

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

// based on https://github.com/thysultan/stylis.js/blob/e6843c373ebcbbfade25ebcc23f540ed8508da0a/src/Tokenizer.js#L239-L244
const identifierWithPointTracking = (begin, points, index) => {
let previous = 0
let character = 0

while (true) {
previous = character
character = peek()

// &\f
if (previous === 38 && character === 12) {
points[index] = 1
}

if (token(character)) {
break
}

next()
}

return slice(begin, position)
}

const toRules = (parsed, points) => {
// pretend we've started with a comma
let index = -1
Expand All @@ -30,7 +54,11 @@ const toRules = (parsed, points) => {
// it's very unlikely for this sequence to actually appear in a different context, so we just leverage this fact here
points[index] = 1
}
parsed[index] += identifier(position - 1)
parsed[index] += identifierWithPointTracking(
position - 1,
points,
index
)
break
case 2:
parsed[index] += delimit(character)
Expand Down
2 changes: 1 addition & 1 deletion packages/css-prettifier/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"repository": "https://github.com/emotion-js/emotion/tree/main/packages/css-prettifier",
"dependencies": {
"@emotion/memoize": "^0.7.4",
"stylis": "^4.0.3"
"stylis": "^4.0.10"
},
"devDependencies": {},
"publishConfig": {
Expand Down
20 changes: 20 additions & 0 deletions packages/css/test/__snapshots__/selectivity.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,26 @@ exports[`css media query with nested selector without declarations on root 1`] =
}"
`;

exports[`css should allow a weird class containing & when pseudoclass appears in the selector group 1`] = `
".css-13p6h3h:hover,
.css-13p6h3h .t\\\\&t {
background: blue;
}"
`;

exports[`css should allow for context selector being appended to an element type 1`] = `
"a.css-ciaq1 {
background: blue;
}"
`;

exports[`css should allow for context selector being appended to an element type when pseudoclass appears in the selector group 1`] = `
".css-miigdc:hover,
a.css-miigdc {
background: blue;
}"
`;

exports[`orphaned pseudos in nested atrules 1`] = `
"@media (max-width: 400px) {
@supports (display: grid) {
Expand Down
31 changes: 31 additions & 0 deletions packages/css/test/selectivity.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,37 @@ describe('css', () => {
`
expect(sheet).toMatchSnapshot()
})

// this isn't compatible with SCSS but is allowed in Stylis
test('should allow for context selector being appended to an element type', () => {
css`
a& {
background: blue;
}
`
expect(sheet).toMatchSnapshot()
})

// #2488
test('should allow for context selector being appended to an element type when pseudoclass appears in the selector group', () => {
css`
&:hover,
a& {
background: blue;
}
`
expect(sheet).toMatchSnapshot()
})

test('should allow a weird class containing & when pseudoclass appears in the selector group', () => {
css`
&:hover,
.t\\&t {
background: blue;
}
`
expect(sheet).toMatchSnapshot()
})
})

describe('orphaned pseudos', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/jest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"@emotion/css-prettifier": "^1.0.0",
"chalk": "^4.1.0",
"specificity": "^0.4.1",
"stylis": "^4.0.3"
"stylis": "^4.0.10"
},
"peerDependencies": {
"@types/jest": "^26.0.14",
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -26417,10 +26417,10 @@ stylehacks@^4.0.0:
postcss "^7.0.0"
postcss-selector-parser "^3.0.0"

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

sudo-prompt@^8.2.0:
version "8.2.5"
Expand Down