Skip to content

Commit

Permalink
Prevent invalid arbitrary variant selectors from failing the build (#…
Browse files Browse the repository at this point in the history
…10059)

* Refactor

* Prevent invalid arbitrary variant selectors from failing the build

* Update changelog

* Fix CS
  • Loading branch information
thecrypticace committed Dec 12, 2022
1 parent 40c0cbe commit 25d17db
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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

Expand Down
26 changes: 24 additions & 2 deletions src/lib/generateRules.js
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
}
}
Expand Down
44 changes: 44 additions & 0 deletions tests/arbitrary-variants.test.js
Expand Up @@ -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``)
})
})

0 comments on commit 25d17db

Please sign in to comment.