From 88119e2ecd32784f13c32ac3a01e6d3cb64305fb Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Fri, 29 Sep 2023 16:04:32 -0400 Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20crash=20when=20important=20and?= =?UTF-8?q?=20parent=20selectors=20are=20equal=20in=20`@apply`=20(#12112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Don’t crash when important and parent selectors are equal in `@apply` * Update changelog --- CHANGELOG.md | 1 + src/lib/expandApplyAtRules.js | 7 +++++ tests/apply.test.js | 52 +++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd3bf0544a8e..9109028ac75a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Batch reading content files to prevent `too many open files` error ([#12079](https://github.com/tailwindlabs/tailwindcss/pull/12079)) - Skip over classes inside `:not(…)` when nested in an at-rule ([#12105](https://github.com/tailwindlabs/tailwindcss/pull/12105)) - Update types to work with `Node16` module resolution ([#12097](https://github.com/tailwindlabs/tailwindcss/pull/12097)) +- Don’t crash when important and parent selectors are equal in `@apply` ([#12112](https://github.com/tailwindlabs/tailwindcss/pull/12112)) ## [3.3.3] - 2023-07-13 diff --git a/src/lib/expandApplyAtRules.js b/src/lib/expandApplyAtRules.js index 3763809e003e..ed48dbc4f75b 100644 --- a/src/lib/expandApplyAtRules.js +++ b/src/lib/expandApplyAtRules.js @@ -553,6 +553,13 @@ function processApply(root, context, localCache) { ? parent.selector.slice(importantSelector.length) : parent.selector + // If the selector becomes empty after replacing the important selector + // This means that it's the same as the parent selector and we don't want to replace it + // Otherwise we'll crash + if (parentSelector === '') { + parentSelector = parent.selector + } + rule.selector = replaceSelector(parentSelector, rule.selector, applyCandidate) // And then re-add it if it was removed diff --git a/tests/apply.test.js b/tests/apply.test.js index e4af6ee58a77..141d5dab912f 100644 --- a/tests/apply.test.js +++ b/tests/apply.test.js @@ -2470,4 +2470,56 @@ crosscheck(({ stable, oxide }) => { // 3. They all use invalid selector syntax that Lightning CSS does not support // It may be enough for Oxide to not support it at all oxide.test.todo('::ng-deep, ::deep, ::v-deep pseudo elements are left alone') + + test('should not break replacing important selector when the same as the parent selector (pseudo)', async () => { + let config = { + important: ':root', + content: [], + } + + let input = css` + @tailwind components; + @layer components { + :root { + @apply flex; + } + } + ` + + let result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + :root { + display: flex; + } + `) + }) + + test('should not break replacing important selector when the same as the parent selector (class)', async () => { + let config = { + important: '.foo', + content: [ + { + raw: html`
`, + }, + ], + } + + let input = css` + @tailwind components; + @layer components { + .foo { + @apply flex; + } + } + ` + + let result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + .foo { + display: flex; + } + `) + }) })