Skip to content

Commit 88119e2

Browse files
committed
Don’t crash when important and parent selectors are equal in @apply (#12112)
* Don’t crash when important and parent selectors are equal in `@apply` * Update changelog
1 parent bbe3fca commit 88119e2

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121
- Batch reading content files to prevent `too many open files` error ([#12079](https://github.com/tailwindlabs/tailwindcss/pull/12079))
2222
- Skip over classes inside `:not(…)` when nested in an at-rule ([#12105](https://github.com/tailwindlabs/tailwindcss/pull/12105))
2323
- Update types to work with `Node16` module resolution ([#12097](https://github.com/tailwindlabs/tailwindcss/pull/12097))
24+
- Don’t crash when important and parent selectors are equal in `@apply` ([#12112](https://github.com/tailwindlabs/tailwindcss/pull/12112))
2425

2526
## [3.3.3] - 2023-07-13
2627

src/lib/expandApplyAtRules.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,13 @@ function processApply(root, context, localCache) {
553553
? parent.selector.slice(importantSelector.length)
554554
: parent.selector
555555

556+
// If the selector becomes empty after replacing the important selector
557+
// This means that it's the same as the parent selector and we don't want to replace it
558+
// Otherwise we'll crash
559+
if (parentSelector === '') {
560+
parentSelector = parent.selector
561+
}
562+
556563
rule.selector = replaceSelector(parentSelector, rule.selector, applyCandidate)
557564

558565
// And then re-add it if it was removed

tests/apply.test.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2470,4 +2470,56 @@ crosscheck(({ stable, oxide }) => {
24702470
// 3. They all use invalid selector syntax that Lightning CSS does not support
24712471
// It may be enough for Oxide to not support it at all
24722472
oxide.test.todo('::ng-deep, ::deep, ::v-deep pseudo elements are left alone')
2473+
2474+
test('should not break replacing important selector when the same as the parent selector (pseudo)', async () => {
2475+
let config = {
2476+
important: ':root',
2477+
content: [],
2478+
}
2479+
2480+
let input = css`
2481+
@tailwind components;
2482+
@layer components {
2483+
:root {
2484+
@apply flex;
2485+
}
2486+
}
2487+
`
2488+
2489+
let result = await run(input, config)
2490+
2491+
expect(result.css).toMatchFormattedCss(css`
2492+
:root {
2493+
display: flex;
2494+
}
2495+
`)
2496+
})
2497+
2498+
test('should not break replacing important selector when the same as the parent selector (class)', async () => {
2499+
let config = {
2500+
important: '.foo',
2501+
content: [
2502+
{
2503+
raw: html` <div class="foo"></div> `,
2504+
},
2505+
],
2506+
}
2507+
2508+
let input = css`
2509+
@tailwind components;
2510+
@layer components {
2511+
.foo {
2512+
@apply flex;
2513+
}
2514+
}
2515+
`
2516+
2517+
let result = await run(input, config)
2518+
2519+
expect(result.css).toMatchFormattedCss(css`
2520+
.foo {
2521+
display: flex;
2522+
}
2523+
`)
2524+
})
24732525
})

0 commit comments

Comments
 (0)