Skip to content

Commit

Permalink
Fixed an issue with context selector not at the beginning (#2498)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Oct 4, 2021
1 parent 63a0a6c commit e5beae8
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 11 deletions.
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

0 comments on commit e5beae8

Please sign in to comment.