From 473de6e4c54ff9027088cee915dd6687d8f19b12 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Fri, 17 Dec 2021 18:29:12 +0100 Subject: [PATCH 1/2] ensure apply of rule inside atrule works If that atrule happens to contain another rule that is technically unrelated. Co-authored-by: Jordan Pittman --- src/lib/expandApplyAtRules.js | 36 ++++++++++++++++++++ tests/apply.test.js | 62 +++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/src/lib/expandApplyAtRules.js b/src/lib/expandApplyAtRules.js index 60499329041f..4eff0f693e40 100644 --- a/src/lib/expandApplyAtRules.js +++ b/src/lib/expandApplyAtRules.js @@ -266,6 +266,42 @@ function processApply(root, context) { if (canRewriteSelector) { root.walkRules((rule) => { + // Let's imagine you have the following structure: + // + // .foo { + // @apply bar; + // } + // + // @supports (a: b) { + // .bar { + // color: blue + // } + // + // .something-unrelated {} + // } + // + // In this case we want to apply `.bar` but it happens to be in + // an atrule node. We clone that node instead of the nested one + // because we still want that @supports rule to be there once we + // applied everything. + // + // However it happens to be that the `.something-unrelated` is + // also in that same shared @supports atrule. This is not good, + // and this should not be there. The good part is that this is + // a clone already and it can be safely removed. The question is + // how do we know we can remove it. Basically what we can do is + // match it against the applyCandidate that you want to apply. If + // it doesn't match the we can safely delete it. + // + // If we didn't do this, then the `replaceSelector` function + // would have replaced this with something that didn't exist and + // therefore it removed the selector altogether. In this specific + // case it would result in `{}` instead of `.something-unrelated {}` + if (!extractClasses(rule).some((thing) => thing === applyCandidate)) { + rule.remove() + return + } + rule.selector = replaceSelector(parent.selector, rule.selector, applyCandidate) rule.walkDecls((d) => { diff --git a/tests/apply.test.js b/tests/apply.test.js index 613e2af04a0c..c74bb2875f5d 100644 --- a/tests/apply.test.js +++ b/tests/apply.test.js @@ -712,3 +712,65 @@ it('should not be possible to apply user css with variants', () => { ) }) }) + +it('should not apply unrelated siblings when applying something from within atrules', () => { + let config = { + content: [{ raw: html`
` }], + plugins: [], + } + + let input = css` + @tailwind components; + @tailwind utilities; + + @layer components { + .foo { + font-weight: bold; + @apply bar; + } + + .bar { + color: green; + } + + @supports (a: b) { + .bar { + color: blue; + } + + .something-unrelated { + color: red; + } + } + } + ` + + return run(input, config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .foo { + font-weight: bold; + color: green; + } + + @supports (a: b) { + .foo { + color: blue; + } + } + + .bar { + color: green; + } + + @supports (a: b) { + .bar { + color: blue; + } + + .something-unrelated { + color: red; + } + } + `) + }) +}) From f36b6c983ca99db7580e282ccec5d4677cedebd6 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Fri, 17 Dec 2021 18:35:31 +0100 Subject: [PATCH 2/2] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02c1d4a9123b..040b7578e013 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Only generate variants for non-`user` layers ([#6589](https://github.com/tailwindlabs/tailwindcss/pull/6589)) - Properly extract classes with arbitrary values in arrays and classes followed by escaped quotes ([#6590](https://github.com/tailwindlabs/tailwindcss/pull/6590)) - Improve jsx interpolation candidate matching ([#6593](https://github.com/tailwindlabs/tailwindcss/pull/6593)) +- Ensure `@apply` of a rule inside an AtRule works ([#6594](https://github.com/tailwindlabs/tailwindcss/pull/6594)) ## [3.0.6] - 2021-12-16