From 1a9d8a509c86aeaf5035b3604612dd410924693d Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Fri, 13 Sep 2024 12:49:44 +0200 Subject: [PATCH] fix: allow `&` to appear at the top when inside a `:global(...)` (#13215) It's a valid CSS rule, which means "select the scope root": https://developer.mozilla.org/en-US/docs/Web/CSS/Nesting_selector#using_outside_nested_rule --- packages/svelte/messages/compile-errors/style.md | 2 +- packages/svelte/src/compiler/errors.js | 4 ++-- .../compiler/phases/2-analyze/css/css-analyze.js | 13 ++++++++++++- .../samples/css-nesting-selector-root/_config.js | 10 ++++++++++ .../css-nesting-selector-root/main.svelte | 16 ++++++++++++++++ 5 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 packages/svelte/tests/compiler-errors/samples/css-nesting-selector-root/_config.js create mode 100644 packages/svelte/tests/compiler-errors/samples/css-nesting-selector-root/main.svelte diff --git a/packages/svelte/messages/compile-errors/style.md b/packages/svelte/messages/compile-errors/style.md index b6ba7aa3ff..1e1ab45e8c 100644 --- a/packages/svelte/messages/compile-errors/style.md +++ b/packages/svelte/messages/compile-errors/style.md @@ -40,7 +40,7 @@ ## css_nesting_selector_invalid_placement -> Nesting selectors can only be used inside a rule +> Nesting selectors can only be used inside a rule or as the first selector inside a lone `:global(...)` ## css_selector_invalid diff --git a/packages/svelte/src/compiler/errors.js b/packages/svelte/src/compiler/errors.js index c4714e2dbc..3facf74282 100644 --- a/packages/svelte/src/compiler/errors.js +++ b/packages/svelte/src/compiler/errors.js @@ -536,12 +536,12 @@ export function css_global_invalid_selector_list(node) { } /** - * Nesting selectors can only be used inside a rule + * Nesting selectors can only be used inside a rule or as the first selector inside a lone `:global(...)` * @param {null | number | NodeLike} node * @returns {never} */ export function css_nesting_selector_invalid_placement(node) { - e(node, "css_nesting_selector_invalid_placement", "Nesting selectors can only be used inside a rule"); + e(node, "css_nesting_selector_invalid_placement", "Nesting selectors can only be used inside a rule or as the first selector inside a lone `:global(...)`"); } /** 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 e4fa7a8084..419ebf5955 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 @@ -222,7 +222,18 @@ const css_visitors = { const parent_rule = rule.metadata.parent_rule; if (!parent_rule) { - e.css_nesting_selector_invalid_placement(node); + // https://developer.mozilla.org/en-US/docs/Web/CSS/Nesting_selector#using_outside_nested_rule + const children = rule.prelude.children; + const selectors = children[0].children[0].selectors; + if ( + children.length > 1 || + selectors.length > 1 || + selectors[0].type !== 'PseudoClassSelector' || + selectors[0].name !== 'global' || + selectors[0].args?.children[0]?.children[0].selectors[0] !== node + ) { + e.css_nesting_selector_invalid_placement(node); + } } else if ( // :global { &.foo { ... } } is invalid parent_rule.metadata.is_global_block && diff --git a/packages/svelte/tests/compiler-errors/samples/css-nesting-selector-root/_config.js b/packages/svelte/tests/compiler-errors/samples/css-nesting-selector-root/_config.js new file mode 100644 index 0000000000..ad7d04c2f1 --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/css-nesting-selector-root/_config.js @@ -0,0 +1,10 @@ +import { test } from '../../test'; + +export default test({ + error: { + code: 'css_nesting_selector_invalid_placement', + message: + 'Nesting selectors can only be used inside a rule or as the first selector inside a lone `:global(...)`', + position: [151, 152] + } +}); diff --git a/packages/svelte/tests/compiler-errors/samples/css-nesting-selector-root/main.svelte b/packages/svelte/tests/compiler-errors/samples/css-nesting-selector-root/main.svelte new file mode 100644 index 0000000000..a88a925265 --- /dev/null +++ b/packages/svelte/tests/compiler-errors/samples/css-nesting-selector-root/main.svelte @@ -0,0 +1,16 @@ +