Prevent invalid arbitrary variant selectors from failing the build (#10059)

* Refactor

* Prevent invalid arbitrary variant selectors from failing the build

* Update changelog

* Fix CS
This commit is contained in:
Jordan Pittman 2022-12-12 11:03:53 -05:00 • committed by GitHub
parent 40c0cbe272
commit 25d17db78c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 2 deletions

View file

@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Don’t reorder webkit scrollbar pseudo elements ([#9991](https://github.com/tailwindlabs/tailwindcss/pull/9991))
- Deterministic sorting of arbitrary variants ([#10016](https://github.com/tailwindlabs/tailwindcss/pull/10016))
- Add `data` key to theme types ([#10023](https://github.com/tailwindlabs/tailwindcss/pull/10023))
- Prevent invalid arbitrary variant selectors from failing the build ([#10059](https://github.com/tailwindlabs/tailwindcss/pull/10059))
### Changed

View file

@ -733,6 +733,8 @@ function* resolveMatches(candidate, context, original = candidate) {
}
for (let match of matches) {
let isValid = true
match[1].raws.tailwind = { ...match[1].raws.tailwind, candidate }
// Apply final format selector
@ -742,7 +744,7 @@ function* resolveMatches(candidate, context, original = candidate) {
container.walkRules((rule) => {
if (inKeyframes(rule)) return
rule.selector = finalizeSelector(finalFormat, {
let selectorOptions = {
selector: rule.selector,
candidate: original,
base: candidate
@ -751,11 +753,31 @@ function* resolveMatches(candidate, context, original = candidate) {
isArbitraryVariant: match[0].isArbitraryVariant,
context,
})
}
try {
rule.selector = finalizeSelector(finalFormat, selectorOptions)
} catch {
// The selector we produced is invalid
// This could be because:
// - A bug exists
// - A plugin introduced an invalid variant selector (ex: `addVariant('foo', '&;foo')`)
// - The user used an invalid arbitrary variant (ex: `[&;foo]:underline`)
// Either way the build will fail because of this
// We would rather that the build pass "silently" given that this could
// happen because of picking up invalid things when scanning content
// So we'll throw out the candidate instead
isValid = false
return false
}
})
match[1] = container.nodes[0]
}
if (!isValid) {
continue
}
yield match
}
}

View file

@ -1099,3 +1099,47 @@ it('Arbitrary variants are ordered alphabetically', () => {
`)
})
})
it('Arbitrary variants support multiple attribute selectors', () => {
let config = {
content: [
{
raw: html` <div class="[[data-foo='bar'][data-baz]_&]:underline"></div> `,
},
],
corePlugins: { preflight: false },
}
let input = css`
@tailwind utilities;
`
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
[data-foo='bar'][data-baz] .\[\[data-foo\=\'bar\'\]\[data-baz\]_\&\]\:underline {
text-decoration-line: underline;
}
`)
})
})
it('Invalid arbitrary variants selectors should produce nothing instead of failing', () => {
let config = {
content: [
{
raw: html`
<div class="[&;foo]:underline"></div>
`,
},
],
corePlugins: { preflight: false },
}
let input = css`
@tailwind utilities;
`
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css``)
})
})