Просмотр исходного кода

fix(compiler-sfc): add scoping tag to trailing universal selector (#12918)

close #12906
thecodewarrior 1 год назад
Родитель
Сommit
949df80880

+ 25 - 1
packages/compiler-sfc/__tests__/compileStyle.spec.ts

@@ -493,7 +493,31 @@ describe('SFC style preprocessors', () => {
       }"
     `)
     expect(compileScoped(`.foo * { color: red; }`)).toMatchInlineSnapshot(`
-      ".foo[data-v-test] * { color: red;
+      ".foo[data-v-test] [data-v-test] { color: red;
+      }"
+    `)
+    expect(compileScoped(`.foo :active { color: red; }`))
+      .toMatchInlineSnapshot(`
+      ".foo[data-v-test] :active { color: red;
+      }"
+    `)
+    expect(compileScoped(`.foo *:active { color: red; }`))
+      .toMatchInlineSnapshot(`
+      ".foo[data-v-test] [data-v-test]:active { color: red;
+      }"
+    `)
+    expect(compileScoped(`.foo * .bar { color: red; }`)).toMatchInlineSnapshot(`
+      ".foo * .bar[data-v-test] { color: red;
+      }"
+    `)
+    expect(compileScoped(`:last-child * { color: red; }`))
+      .toMatchInlineSnapshot(`
+      "[data-v-test]:last-child [data-v-test] { color: red;
+      }"
+    `)
+    expect(compileScoped(`:last-child *:active { color: red; }`))
+      .toMatchInlineSnapshot(`
+      "[data-v-test]:last-child [data-v-test]:active { color: red;
       }"
     `)
   })

+ 22 - 3
packages/compiler-sfc/src/style/pluginScoped.ts

@@ -102,6 +102,7 @@ function rewriteSelector(
   slotted = false,
 ) {
   let node: selectorParser.Node | null = null
+  let starNode: selectorParser.Node | null = null
   let shouldInject = !deep
   // find the last child node to insert attribute selector
   selector.each(n => {
@@ -216,17 +217,21 @@ function rewriteSelector(
           return false
         }
       }
-      // .foo * -> .foo[xxxxxxx] *
-      if (node) return
+      // store the universal selector so it can be rewritten later
+      // .foo * -> .foo[xxxxxxx] [xxxxxxx]
+      starNode = n
     }
 
     if (
-      (n.type !== 'pseudo' && n.type !== 'combinator') ||
+      (n.type !== 'pseudo' &&
+        n.type !== 'combinator' &&
+        n.type !== 'universal') ||
       (n.type === 'pseudo' &&
         (n.value === ':is' || n.value === ':where') &&
         !node)
     ) {
       node = n
+      starNode = null
     }
   })
 
@@ -274,6 +279,20 @@ function rewriteSelector(
         quoteMark: `"`,
       }),
     )
+    // Used for trailing universal selectors (#12906)
+    // `.foo * {}` -> `.foo[xxxxxxx] [xxxxxxx] {}`
+    if (starNode) {
+      selector.insertBefore(
+        starNode,
+        selectorParser.attribute({
+          attribute: idToAdd,
+          value: idToAdd,
+          raws: {},
+          quoteMark: `"`,
+        }),
+      )
+      selector.removeChild(starNode)
+    }
   }
 }