]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compile-sfc): auto add nesting combinators for ::v-deep in scoped CSS
authordaiwei <daiwei521@126.com>
Sat, 5 Apr 2025 02:27:27 +0000 (10:27 +0800)
committerdaiwei <daiwei521@126.com>
Sat, 5 Apr 2025 02:27:27 +0000 (10:27 +0800)
packages/compiler-sfc/__tests__/compileStyle.spec.ts
packages/compiler-sfc/src/style/pluginScoped.ts

index b76414364dc90f18bee19191fd6bda760d463f59..ff5ca2a952d41d634bc2a392478507e5df98a660 100644 (file)
@@ -140,6 +140,18 @@ color: red
       }
       }"
     `)
+    expect(compileScoped(`.foo { :deep(.bar) { color: red; }}`))
+      .toMatchInlineSnapshot(`
+        ".foo {
+        &[data-v-test] .bar { color: red;
+        }}"
+      `)
+    expect(compileScoped(`.foo { & :deep(.bar) { color: red; }}`))
+      .toMatchInlineSnapshot(`
+        ".foo {
+        &[data-v-test] .bar { color: red;
+        }}"
+      `)
   })
 
   test('::v-slotted', () => {
index d0aaddd7676ba41d59eb1ed8899718dcbb89f746..b0854a22e429b10c9b5234894443ded2063e7253 100644 (file)
@@ -133,6 +133,29 @@ function rewriteSelector(
             selector.insertAfter(last, ss)
             last = ss
           })
+
+          // if css nesting is used, we need to insert a nesting combinator
+          // before the ::v-deep node
+          // .foo { ::v-deep(.bar) } -> .foo { &[xxxxxxx] .bar }
+          const isNestedRule = rule.parent && rule.parent.type === 'rule'
+          if (isNestedRule && n.parent) {
+            let hasNestingCombinator = false
+            let index = n.parent.index(n) - 1
+            while (index >= 0) {
+              const prev = n.parent.at(index)
+              if (!prev) break
+              if (prev.type === 'nesting') {
+                hasNestingCombinator = true
+                break
+              }
+              index--
+            }
+            if (!hasNestingCombinator) {
+              node = selectorParser.nesting()
+              selector.insertBefore(n, node)
+            }
+          }
+
           // insert a space combinator before if it doesn't already have one
           const prev = selector.at(selector.index(n) - 1)
           if (!prev || !isSpaceCombinator(prev)) {