From c3e2c556b532656b50b8ab5cd2d9eabc26622d63 Mon Sep 17 00:00:00 2001 From: yangxiuxiu <79584569+RicardoErii@users.noreply.github.com> Date: Mon, 4 Dec 2023 16:53:21 +0800 Subject: [PATCH] fix(compiler-sfc): fix :where and :is selector in scoped mode with multiple selectors (#9735) close #9707 --- .../compiler-sfc/__tests__/compileStyle.spec.ts | 17 +++++++++++++++++ packages/compiler-sfc/src/style/pluginScoped.ts | 16 ++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/packages/compiler-sfc/__tests__/compileStyle.spec.ts b/packages/compiler-sfc/__tests__/compileStyle.spec.ts index 66fc201f547..624cbaa043f 100644 --- a/packages/compiler-sfc/__tests__/compileStyle.spec.ts +++ b/packages/compiler-sfc/__tests__/compileStyle.spec.ts @@ -144,6 +144,23 @@ describe('SFC scoped CSS', () => { `) }) + test(':is() and :where() with multiple selectors', () => { + expect(compileScoped(`:is(.foo) { color: red; }`)).toMatchInlineSnapshot(` + ":is(.foo[data-v-test]) { color: red; + }" + `) + expect(compileScoped(`:where(.foo, .bar) { color: red; }`)) + .toMatchInlineSnapshot(` + ":where(.foo[data-v-test], .bar[data-v-test]) { color: red; + }" + `) + expect(compileScoped(`:is(.foo, .bar) div { color: red; }`)) + .toMatchInlineSnapshot(` + ":is(.foo, .bar) div[data-v-test] { color: red; + }" + `) + }) + test('media query', () => { expect(compileScoped(`@media print { .foo { color: red }}`)) .toMatchInlineSnapshot(` diff --git a/packages/compiler-sfc/src/style/pluginScoped.ts b/packages/compiler-sfc/src/style/pluginScoped.ts index 5394b77743f..f71c304f502 100644 --- a/packages/compiler-sfc/src/style/pluginScoped.ts +++ b/packages/compiler-sfc/src/style/pluginScoped.ts @@ -170,15 +170,23 @@ function rewriteSelector( } } - if (n.type !== 'pseudo' && n.type !== 'combinator') { + if ( + (n.type !== 'pseudo' && n.type !== 'combinator') || + (n.type === 'pseudo' && (n.value === ':is' || n.value === ':where')) + ) { node = n } + }) - if (n.type === 'pseudo' && (n.value === ':is' || n.value === ':where')) { - rewriteSelector(id, n.nodes[0], selectorRoot, slotted) + if (node) { + const { type, value } = node as selectorParser.Node + if (type === 'pseudo' && (value === ':is' || value === ':where')) { + ;(node as selectorParser.Pseudo).nodes.forEach(value => + rewriteSelector(id, value, selectorRoot, slotted) + ) shouldInject = false } - }) + } if (node) { ;(node as selectorParser.Node).spaces.after = ''