]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-sfc): nested css supports atrule and comment (#11899)
authorlinzhe <40790268+linzhe141@users.noreply.github.com>
Fri, 13 Sep 2024 08:53:49 +0000 (16:53 +0800)
committerGitHub <noreply@github.com>
Fri, 13 Sep 2024 08:53:49 +0000 (16:53 +0800)
close #11896

packages/compiler-sfc/__tests__/compileStyle.spec.ts
packages/compiler-sfc/src/style/pluginScoped.ts

index 72727c43196e3e9f3d331cfd59c587c8d85f6e72..b76414364dc90f18bee19191fd6bda760d463f59 100644 (file)
@@ -47,6 +47,38 @@ describe('SFC scoped CSS', () => {
     )
   })
 
+  test('nesting selector with atrule and comment', () => {
+    expect(
+      compileScoped(
+        `h1 {
+color: red;
+/*background-color: pink;*/
+@media only screen and (max-width: 800px) {
+  background-color: green;
+  .bar { color: white }
+}
+.foo { color: red; }
+}`,
+      ),
+    ).toMatch(
+      `h1 {
+&[data-v-test] {
+color: red
+/*background-color: pink;*/
+}
+@media only screen and (max-width: 800px) {
+&[data-v-test] {
+  background-color: green
+}
+.bar[data-v-test] { color: white
+}
+}
+.foo[data-v-test] { color: red;
+}
+}`,
+    )
+  })
+
   test('multiple selectors', () => {
     expect(compileScoped(`h1 .foo, .bar, .baz { color: red; }`)).toMatch(
       `h1 .foo[data-v-test], .bar[data-v-test], .baz[data-v-test] { color: red;`,
index 6a588b56726ee5ecd920ffe87d48c8dbb6dc8d15..b0224cf20d8eea0088f08dab8f426bf41149fa97 100644 (file)
@@ -233,16 +233,12 @@ function rewriteSelector(
 
   if (rule.nodes.some(node => node.type === 'rule')) {
     const deep = (rule as any).__deep
-    const decls = rule.nodes.filter(node => node.type === 'decl')
-    if (!deep && decls.length) {
-      for (const decl of decls) {
-        rule.removeChild(decl)
+    if (!deep) {
+      extractAndWrapNodes(rule)
+      const atruleNodes = rule.nodes.filter(node => node.type === 'atrule')
+      for (const atnode of atruleNodes) {
+        extractAndWrapNodes(atnode)
       }
-      const hostRule = new Rule({
-        nodes: decls,
-        selector: '&',
-      })
-      rule.prepend(hostRule)
     }
     shouldInject = deep
   }
@@ -286,5 +282,22 @@ function isSpaceCombinator(node: selectorParser.Node) {
   return node.type === 'combinator' && /^\s+$/.test(node.value)
 }
 
+function extractAndWrapNodes(parentNode: Rule | AtRule) {
+  if (!parentNode.nodes) return
+  const nodes = parentNode.nodes.filter(
+    node => node.type === 'decl' || node.type === 'comment',
+  )
+  if (nodes.length) {
+    for (const node of nodes) {
+      parentNode.removeChild(node)
+    }
+    const wrappedRule = new Rule({
+      nodes: nodes,
+      selector: '&',
+    })
+    parentNode.prepend(wrappedRule)
+  }
+}
+
 scopedPlugin.postcss = true
 export default scopedPlugin