diff --git a/packages/compiler-sfc/__tests__/compileStyle.spec.ts b/packages/compiler-sfc/__tests__/compileStyle.spec.ts index 0da713a0504..71c0689a397 100644 --- a/packages/compiler-sfc/__tests__/compileStyle.spec.ts +++ b/packages/compiler-sfc/__tests__/compileStyle.spec.ts @@ -429,4 +429,23 @@ describe('SFC style preprocessors', () => { expect(res.errors.length).toBe(0) }) + + test('should mount scope on correct selector when have universal selector', () => { + expect(compileScoped(`* { color: red; }`)).toMatchInlineSnapshot(` + "[data-v-test] { color: red; + }" + `) + expect(compileScoped('* .foo { color: red; }')).toMatchInlineSnapshot(` + ".foo[data-v-test] { color: red; + }" + `) + expect(compileScoped(`*.foo { color: red; }`)).toMatchInlineSnapshot(` + ".foo[data-v-test] { color: red; + }" + `) + expect(compileScoped(`.foo * { color: red; }`)).toMatchInlineSnapshot(` + ".foo[data-v-test] * { color: red; + }" + `) + }) }) diff --git a/packages/compiler-sfc/src/style/pluginScoped.ts b/packages/compiler-sfc/src/style/pluginScoped.ts index 0a46de7fcb4..3812e67092a 100644 --- a/packages/compiler-sfc/src/style/pluginScoped.ts +++ b/packages/compiler-sfc/src/style/pluginScoped.ts @@ -170,6 +170,32 @@ function rewriteSelector( } } + if (n.type === 'universal') { + const prev = selector.at(selector.index(n) - 1) + const next = selector.at(selector.index(n) + 1) + // * ... {} + if (!prev) { + // * .foo {} -> .foo[xxxxxxx] {} + if (next) { + if (next.type === 'combinator' && next.value === ' ') { + selector.removeChild(next) + } + selector.removeChild(n) + return + } else { + // * {} -> [xxxxxxx] {} + node = selectorParser.combinator({ + value: '', + }) + selector.insertBefore(n, node) + selector.removeChild(n) + return false + } + } + // .foo * -> .foo[xxxxxxx] * + if (node) return + } + if ( (n.type !== 'pseudo' && n.type !== 'combinator') || (n.type === 'pseudo' &&