Skip to content

Commit 0e7bc71

Browse files
authoredSep 13, 2024··
fix(compiler-sfc): nested css supports atrule and comment (#11899)
close #11896
1 parent 706d4ac commit 0e7bc71

File tree

2 files changed

+54
-9
lines changed

2 files changed

+54
-9
lines changed
 

‎packages/compiler-sfc/__tests__/compileStyle.spec.ts

+32
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,38 @@ describe('SFC scoped CSS', () => {
4747
)
4848
})
4949

50+
test('nesting selector with atrule and comment', () => {
51+
expect(
52+
compileScoped(
53+
`h1 {
54+
color: red;
55+
/*background-color: pink;*/
56+
@media only screen and (max-width: 800px) {
57+
background-color: green;
58+
.bar { color: white }
59+
}
60+
.foo { color: red; }
61+
}`,
62+
),
63+
).toMatch(
64+
`h1 {
65+
&[data-v-test] {
66+
color: red
67+
/*background-color: pink;*/
68+
}
69+
@media only screen and (max-width: 800px) {
70+
&[data-v-test] {
71+
background-color: green
72+
}
73+
.bar[data-v-test] { color: white
74+
}
75+
}
76+
.foo[data-v-test] { color: red;
77+
}
78+
}`,
79+
)
80+
})
81+
5082
test('multiple selectors', () => {
5183
expect(compileScoped(`h1 .foo, .bar, .baz { color: red; }`)).toMatch(
5284
`h1 .foo[data-v-test], .bar[data-v-test], .baz[data-v-test] { color: red;`,

‎packages/compiler-sfc/src/style/pluginScoped.ts

+22-9
Original file line numberDiff line numberDiff line change
@@ -233,16 +233,12 @@ function rewriteSelector(
233233

234234
if (rule.nodes.some(node => node.type === 'rule')) {
235235
const deep = (rule as any).__deep
236-
const decls = rule.nodes.filter(node => node.type === 'decl')
237-
if (!deep && decls.length) {
238-
for (const decl of decls) {
239-
rule.removeChild(decl)
236+
if (!deep) {
237+
extractAndWrapNodes(rule)
238+
const atruleNodes = rule.nodes.filter(node => node.type === 'atrule')
239+
for (const atnode of atruleNodes) {
240+
extractAndWrapNodes(atnode)
240241
}
241-
const hostRule = new Rule({
242-
nodes: decls,
243-
selector: '&',
244-
})
245-
rule.prepend(hostRule)
246242
}
247243
shouldInject = deep
248244
}
@@ -286,5 +282,22 @@ function isSpaceCombinator(node: selectorParser.Node) {
286282
return node.type === 'combinator' && /^\s+$/.test(node.value)
287283
}
288284

285+
function extractAndWrapNodes(parentNode: Rule | AtRule) {
286+
if (!parentNode.nodes) return
287+
const nodes = parentNode.nodes.filter(
288+
node => node.type === 'decl' || node.type === 'comment',
289+
)
290+
if (nodes.length) {
291+
for (const node of nodes) {
292+
parentNode.removeChild(node)
293+
}
294+
const wrappedRule = new Rule({
295+
nodes: nodes,
296+
selector: '&',
297+
})
298+
parentNode.prepend(wrappedRule)
299+
}
300+
}
301+
289302
scopedPlugin.postcss = true
290303
export default scopedPlugin

0 commit comments

Comments
 (0)
Please sign in to comment.