From efc65d4e0c185cd597a6eeef013f6641b8e25d50 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Fri, 15 Nov 2024 14:33:10 +0100 Subject: [PATCH] fix: mark pseudo classes nested inside `:not` as used (#14303) fixes the css bug part of #14299 --- .changeset/chatty-singers-sin.md | 5 +++++ .../src/compiler/phases/2-analyze/css/css-analyze.js | 3 ++- .../svelte/src/compiler/phases/2-analyze/css/css-prune.js | 7 ++++++- .../svelte/tests/css/samples/not-selector/expected.css | 4 ++++ .../svelte/tests/css/samples/not-selector/input.svelte | 4 ++++ 5 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 .changeset/chatty-singers-sin.md diff --git a/.changeset/chatty-singers-sin.md b/.changeset/chatty-singers-sin.md new file mode 100644 index 0000000000..f69bc97454 --- /dev/null +++ b/.changeset/chatty-singers-sin.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: mark pseudo classes nested inside `:not` as used diff --git a/packages/svelte/src/compiler/phases/2-analyze/css/css-analyze.js b/packages/svelte/src/compiler/phases/2-analyze/css/css-analyze.js index 38551f328f..1dd2d9ae7c 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/css/css-analyze.js +++ b/packages/svelte/src/compiler/phases/2-analyze/css/css-analyze.js @@ -150,8 +150,9 @@ const css_visitors = { // So that nested selectors like `:root:not(.x)` are not marked as unused for (const child of node.selectors) { walk(/** @type {Css.Node} */ (child), null, { - ComplexSelector(node) { + ComplexSelector(node, context) { node.metadata.used = true; + context.next(); } }); } 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 bf0fd27566..bfb83d3e02 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 @@ -531,7 +531,12 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element, // with descendants, in which case we scope them all. if (name === 'not' && selector.args) { for (const complex_selector of selector.args.children) { - complex_selector.metadata.used = true; + walk(complex_selector, null, { + ComplexSelector(node, context) { + node.metadata.used = true; + context.next(); + } + }); const relative = truncate(complex_selector); if (complex_selector.children.length > 1) { diff --git a/packages/svelte/tests/css/samples/not-selector/expected.css b/packages/svelte/tests/css/samples/not-selector/expected.css index ea0b3aacac..1b0db0ff4b 100644 --- a/packages/svelte/tests/css/samples/not-selector/expected.css +++ b/packages/svelte/tests/css/samples/not-selector/expected.css @@ -29,3 +29,7 @@ span.svelte-xyz:not(:focus) { color: green; } + + p.svelte-xyz:not(:has(span)) { + color: green; + } diff --git a/packages/svelte/tests/css/samples/not-selector/input.svelte b/packages/svelte/tests/css/samples/not-selector/input.svelte index 3a786530a2..da8f4579c2 100644 --- a/packages/svelte/tests/css/samples/not-selector/input.svelte +++ b/packages/svelte/tests/css/samples/not-selector/input.svelte @@ -36,4 +36,8 @@ span:not(:focus) { color: green; } + + p:not(:has(span)) { + color: green; + } \ No newline at end of file