Repository: sveltejs/svelte (JavaScript)
Date: 2021-07-22 15:01:28+00:00
Task type: Bug Fix

Issue:
compiler sometimes sometimes tries to encapsulate :global(...)
### Describe the bug

There's a bug in how some css selectors are compiled, such that the class that the compiler adds (to scope things to the module) is prepended to the contents of `:global(...)`.

### Reproduction

```css
:global(div) > div {
	color: red;
}
```

compiles to:

```css
.svelte-lxuwwediv>div.svelte-lxuwwe{color:red}
```

This bug is about the extra `.svelte-lxuwwe` at the beginning that's smashed right up against the first `div`.

Here's a repl showing this in action: https://svelte.dev/repl/9b67838a3ad04a52b3a21255f84051c2?version=3.38.3


### Logs

_No response_

### System Info

```shell
System:
    OS: Linux 5.10 Alpine Linux
    CPU: (8) x64 Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
    Memory: 235.31 MB / 7.43 GB
    Container: Yes
    Shell: 1.32.1 - /bin/ash
  Binaries:
    Node: 16.2.0 - /usr/local/bin/node
    Yarn: 1.22.5 - /usr/local/bin/yarn
    npm: 7.13.0 - /usr/local/bin/npm
  npmPackages:
    rollup: ^2.3.4 => 2.49.0
    svelte: ^3.0.0 => 3.38.2
```


### Severity

annoyance


Issue discussion:

Solution patch:
diff --git a/src/compiler/compile/css/Selector.ts b/src/compiler/compile/css/Selector.ts
--- a/src/compiler/compile/css/Selector.ts
+++ b/src/compiler/compile/css/Selector.ts
@@ -278,14 +278,12 @@ function block_might_apply_to_node(block: Block, node: Element): BlockAppliesToN
 			return BlockAppliesToNode.NotPossible;
 		}
 
-		if (selector.type === 'PseudoClassSelector' || selector.type === 'PseudoElementSelector') {
-			continue;
+		if (block.selectors.length === 1 && selector.type === 'PseudoClassSelector' && name === 'global') {
+			return BlockAppliesToNode.NotPossible;
 		}
 
-		if (selector.type === 'PseudoClassSelector' && name === 'global') {
-			// TODO shouldn't see this here... maybe we should enforce that :global(...)
-			// cannot be sandwiched between non-global selectors?
-			return BlockAppliesToNode.NotPossible;
+		if (selector.type === 'PseudoClassSelector' || selector.type === 'PseudoElementSelector') {
+			continue;
 		}
 
 		if (selector.type === 'ClassSelector') {


Test patch:
diff --git a/test/css/samples/global-with-child-combinator/_config.js b/test/css/samples/global-with-child-combinator/_config.js
new file mode 100644
--- /dev/null
+++ b/test/css/samples/global-with-child-combinator/_config.js
@@ -0,0 +1,3 @@
+export default {
+	warnings: []
+};
diff --git a/test/css/samples/global-with-child-combinator/expected.css b/test/css/samples/global-with-child-combinator/expected.css
new file mode 100644
--- /dev/null
+++ b/test/css/samples/global-with-child-combinator/expected.css
@@ -0,0 +1 @@
+div>div.svelte-xyz{color:red}
\ No newline at end of file
diff --git a/test/css/samples/global-with-child-combinator/input.svelte b/test/css/samples/global-with-child-combinator/input.svelte
new file mode 100644
--- /dev/null
+++ b/test/css/samples/global-with-child-combinator/input.svelte
@@ -0,0 +1,9 @@
+<style>
+	:global(div) > div {
+		color: red;
+	}
+</style>
+
+<div>
+	<div />
+</div>
\ No newline at end of file