Ensure comments in @layer rules don't crash (#5854)

* ensure comments in @layer rules don't crash

* update changelog
This commit is contained in:
Robin Malfait 2021-10-22 15:19:21 +02:00 committed by GitHub
parent 0ab39c312a
commit ee3f3fd0be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 141 additions and 7 deletions

View File

@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix before/after utilities overriding custom content values at larger breakpoints ([#5820](https://github.com/tailwindlabs/tailwindcss/pull/5820))
- Cleanup duplicate properties ([#5830](https://github.com/tailwindlabs/tailwindcss/pull/5830))
- Allow `_` inside `url()` when using arbitrary values ([#5853](https://github.com/tailwindlabs/tailwindcss/pull/5853))
- Prevent crashes when using comments in `@layer` AtRules ([#5854](https://github.com/tailwindlabs/tailwindcss/pull/5854))
## [3.0.0-alpha.1] - 2021-10-01

View File

@ -448,28 +448,42 @@ function generateRules(candidates, context) {
allRules.push(matches)
}
return allRules.flat(1).map(([{ sort, layer, options }, rule]) => {
if (options.respectImportant) {
if (context.tailwindConfig.important === true) {
// Strategy based on `tailwindConfig.important`
let strategy = ((important) => {
if (important === true) {
return (rule) => {
rule.walkDecls((d) => {
if (d.parent.type === 'rule' && !inKeyframes(d.parent)) {
d.important = true
}
})
} else if (typeof context.tailwindConfig.important === 'string') {
}
}
if (typeof important === 'string') {
return (rule) => {
rule.selectors = rule.selectors.map((selector) => {
return `${important} ${selector}`
})
}
}
})(context.tailwindConfig.important)
return allRules.flat(1).map(([{ sort, layer, options }, rule]) => {
if (options.respectImportant) {
if (strategy) {
let container = postcss.root({ nodes: [rule.clone()] })
container.walkRules((r) => {
if (inKeyframes(r)) {
return
}
r.selectors = r.selectors.map((selector) => {
return `${context.tailwindConfig.important} ${selector}`
})
strategy(r)
})
rule = container.nodes[0]
}
}
return [sort | context.layerOrder[layer], rule]
})
}

View File

@ -50,6 +50,125 @@ test('custom user-land utilities', () => {
})
})
test('comments can be used inside layers without crashing', () => {
let config = {
content: [
{
raw: html`<div class="important-utility important-component"></div>`,
},
],
corePlugins: { preflight: false },
theme: {},
plugins: [],
}
let input = css`
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
/* Important base */
div {
background-color: #bada55;
}
}
@layer utilities {
/* Important utility */
.important-utility {
text-align: banana;
}
}
@layer components {
/* Important component */
.important-component {
text-align: banana;
}
}
`
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
/* Important base */
div {
background-color: #bada55;
}
/* Important component */
.important-component {
text-align: banana;
}
/* Important utility */
.important-utility {
text-align: banana;
}
`)
})
})
test('comments can be used inside layers (with important) without crashing', () => {
let config = {
important: true,
content: [
{
raw: html`<div class="important-utility important-component"></div>`,
},
],
corePlugins: { preflight: false },
theme: {},
plugins: [],
}
let input = css`
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
/* Important base */
div {
background-color: #bada55;
}
}
@layer utilities {
/* Important utility */
.important-utility {
text-align: banana;
}
}
@layer components {
/* Important component */
.important-component {
text-align: banana;
}
}
`
return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
/* Important base */
div {
background-color: #bada55;
}
/* Important component */
.important-component {
text-align: banana;
}
/* Important utility */
.important-utility {
text-align: banana !important;
}
`)
})
})
test('layers are grouped and inserted at the matching @tailwind rule', () => {
let config = {
content: [