From e9dc118eb7644bc42204c32bfd7d8ca26f900580 Mon Sep 17 00:00:00 2001 From: Paolo Ricciuti Date: Thu, 12 Sep 2024 09:52:00 +0200 Subject: [PATCH] fix: allow for nesting selector in pseudoclasses (#13209) Fixes #13203 The problem is that we were checking for NestingSelectors only in the selectors of the immediate child of the selectors. Since Nesting could be in selectors like :is or :where or :has that can also be nested i think we need to walk the selectors to find if there's a selector or not. --- .changeset/tough-snails-chew.md | 5 +++++ .../phases/2-analyze/css/css-prune.js | 20 ++++++++++++++++--- .../css/samples/nested-in-pseudo/_config.js | 5 +++++ .../css/samples/nested-in-pseudo/expected.css | 6 ++++++ .../samples/nested-in-pseudo/expected.html | 1 + .../css/samples/nested-in-pseudo/input.svelte | 11 ++++++++++ 6 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 .changeset/tough-snails-chew.md create mode 100644 packages/svelte/tests/css/samples/nested-in-pseudo/_config.js create mode 100644 packages/svelte/tests/css/samples/nested-in-pseudo/expected.css create mode 100644 packages/svelte/tests/css/samples/nested-in-pseudo/expected.html create mode 100644 packages/svelte/tests/css/samples/nested-in-pseudo/input.svelte diff --git a/.changeset/tough-snails-chew.md b/.changeset/tough-snails-chew.md new file mode 100644 index 0000000000..174a3d0197 --- /dev/null +++ b/.changeset/tough-snails-chew.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: allow for nesting selector in pseudoclasses diff --git a/packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js b/packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js index a99745f809..1896c83d1a 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js +++ b/packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js @@ -73,9 +73,23 @@ const visitors = { const inner = selectors[selectors.length - 1]; if (node.metadata.rule?.metadata.parent_rule && selectors.length > 0) { - const has_explicit_nesting_selector = selectors.some((selector) => - selector.selectors.some((s) => s.type === 'NestingSelector') - ); + let has_explicit_nesting_selector = false; + + // nesting could be inside pseudo classes like :is, :has or :where + for (let selector of selectors) { + walk( + selector, + {}, + { + // @ts-ignore + NestingSelector() { + has_explicit_nesting_selector = true; + } + } + ); + // if we found one we can break from the others + if (has_explicit_nesting_selector) break; + } if (!has_explicit_nesting_selector) { selectors[0] = { diff --git a/packages/svelte/tests/css/samples/nested-in-pseudo/_config.js b/packages/svelte/tests/css/samples/nested-in-pseudo/_config.js new file mode 100644 index 0000000000..292c6c49ac --- /dev/null +++ b/packages/svelte/tests/css/samples/nested-in-pseudo/_config.js @@ -0,0 +1,5 @@ +import { test } from '../../test'; + +export default test({ + warnings: [] +}); diff --git a/packages/svelte/tests/css/samples/nested-in-pseudo/expected.css b/packages/svelte/tests/css/samples/nested-in-pseudo/expected.css new file mode 100644 index 0000000000..3f365a8988 --- /dev/null +++ b/packages/svelte/tests/css/samples/nested-in-pseudo/expected.css @@ -0,0 +1,6 @@ + +nav.svelte-xyz{ + header:where(.svelte-xyz):has(&){ + color: red; + } +} diff --git a/packages/svelte/tests/css/samples/nested-in-pseudo/expected.html b/packages/svelte/tests/css/samples/nested-in-pseudo/expected.html new file mode 100644 index 0000000000..44a5d4a52d --- /dev/null +++ b/packages/svelte/tests/css/samples/nested-in-pseudo/expected.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/packages/svelte/tests/css/samples/nested-in-pseudo/input.svelte b/packages/svelte/tests/css/samples/nested-in-pseudo/input.svelte new file mode 100644 index 0000000000..8a6758f60f --- /dev/null +++ b/packages/svelte/tests/css/samples/nested-in-pseudo/input.svelte @@ -0,0 +1,11 @@ +
+ +
+ + \ No newline at end of file