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:
parent
40c0cbe272
commit
25d17db78c
3 changed files with 69 additions and 2 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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``)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue