Skip to content

Commit 708f541

Browse files
7nik7nik
and
7nik
authored
fix: better scope :global() with nesting selector & (#15671)
Co-authored-by: 7nik <[email protected]>
1 parent 7694818 commit 708f541

File tree

4 files changed

+33
-6
lines changed

4 files changed

+33
-6
lines changed

Diff for: .changeset/stupid-vans-draw.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: better scope `:global()` with nesting selector `&`

Diff for: packages/svelte/src/compiler/phases/2-analyze/css/css-prune.js

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
/** @import * as Compiler from '#compiler' */
22
import { walk } from 'zimmerframe';
3-
import { get_parent_rules, get_possible_values, is_outer_global } from './utils.js';
3+
import {
4+
get_parent_rules,
5+
get_possible_values,
6+
is_outer_global,
7+
is_unscoped_pseudo_class
8+
} from './utils.js';
49
import { regex_ends_with_whitespace, regex_starts_with_whitespace } from '../../patterns.js';
510
import { get_attribute_chunks, is_text_attribute } from '../../../utils/ast.js';
611

@@ -286,20 +291,26 @@ function apply_combinator(relative_selector, rest_selectors, rule, node, directi
286291
* a global selector
287292
* @param {Compiler.AST.CSS.RelativeSelector} selector
288293
* @param {Compiler.AST.CSS.Rule} rule
294+
* @returns {boolean}
289295
*/
290296
function is_global(selector, rule) {
291297
if (selector.metadata.is_global || selector.metadata.is_global_like) {
292298
return true;
293299
}
294300

301+
let explicitly_global = false;
302+
295303
for (const s of selector.selectors) {
296304
/** @type {Compiler.AST.CSS.SelectorList | null} */
297305
let selector_list = null;
306+
let can_be_global = false;
298307
let owner = rule;
299308

300309
if (s.type === 'PseudoClassSelector') {
301310
if ((s.name === 'is' || s.name === 'where') && s.args) {
302311
selector_list = s.args;
312+
} else {
313+
can_be_global = is_unscoped_pseudo_class(s);
303314
}
304315
}
305316

@@ -308,18 +319,19 @@ function is_global(selector, rule) {
308319
selector_list = owner.prelude;
309320
}
310321

311-
const has_global_selectors = selector_list?.children.some((complex_selector) => {
322+
const has_global_selectors = !!selector_list?.children.some((complex_selector) => {
312323
return complex_selector.children.every((relative_selector) =>
313324
is_global(relative_selector, owner)
314325
);
315326
});
327+
explicitly_global ||= has_global_selectors;
316328

317-
if (!has_global_selectors) {
329+
if (!has_global_selectors && !can_be_global) {
318330
return false;
319331
}
320332
}
321333

322-
return true;
334+
return explicitly_global || selector.selectors.length === 0;
323335
}
324336

325337
const regex_backslash_and_following_character = /\\(.)/g;
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
div.svelte-xyz {
22
&.class{
3-
color: red;
3+
color: green;
4+
}
5+
}
6+
* {
7+
&:hover .class.svelte-xyz {
8+
color: green;
49
}
510
}

Diff for: packages/svelte/tests/css/samples/global-with-nesting/input.svelte

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
<style>
22
div {
33
&:global(.class){
4-
color: red;
4+
color: green;
5+
}
6+
}
7+
:global(*) {
8+
&:hover .class {
9+
color: green;
510
}
611
}
712
</style>

0 commit comments

Comments
 (0)