mirror of https://github.com/vuejs/core.git
fix(compiler-sfc): support global selector nesting
This commit is contained in:
parent
6eb29d345a
commit
436415a4cc
|
@ -181,12 +181,40 @@ color: red
|
|||
".foo .bar { color: red;
|
||||
}"
|
||||
`)
|
||||
// global ignores anything before it
|
||||
|
||||
expect(compileScoped(`.baz .qux ::v-global(.foo .bar) { color: red; }`))
|
||||
.toMatchInlineSnapshot(`
|
||||
".foo .bar { color: red;
|
||||
".baz .qux[data-v-test] .foo .bar { color: red;
|
||||
}"
|
||||
`)
|
||||
|
||||
expect(compileScoped(`::v-global(body) h1 { color: red; }`))
|
||||
.toMatchInlineSnapshot(`
|
||||
"body h1[data-v-test] { color: red;
|
||||
}"
|
||||
`)
|
||||
|
||||
expect(compileScoped(`::v-global(body h1) { color: red; }`))
|
||||
.toMatchInlineSnapshot(`
|
||||
"body h1 { color: red;
|
||||
}"
|
||||
`)
|
||||
|
||||
expect(compileScoped(`html ::v-global(body) h1 { color: red; }`))
|
||||
.toMatchInlineSnapshot(`
|
||||
"html body h1[data-v-test] { color: red;
|
||||
}"
|
||||
`)
|
||||
|
||||
expect(compileScoped(`::v-global(body){ color: red; h1 { color: blue; } }`))
|
||||
.toMatchInlineSnapshot(`
|
||||
"body{
|
||||
&{ color: red;
|
||||
}
|
||||
h1[data-v-test] { color: blue;
|
||||
}
|
||||
}"
|
||||
`)
|
||||
})
|
||||
|
||||
test(':is() and :where() with multiple selectors', () => {
|
||||
|
|
|
@ -103,8 +103,14 @@ function rewriteSelector(
|
|||
) {
|
||||
let node: selectorParser.Node | null = null
|
||||
let shouldInject = !deep
|
||||
let wrappedGlobal = false
|
||||
// find the last child node to insert attribute selector
|
||||
selector.each(n => {
|
||||
if ((rule as any).__global) {
|
||||
shouldInject = false
|
||||
return false
|
||||
}
|
||||
|
||||
// DEPRECATED ">>>" and "/deep/" combinator
|
||||
if (
|
||||
n.type === 'combinator' &&
|
||||
|
@ -189,8 +195,12 @@ function rewriteSelector(
|
|||
// global: replace with inner selector and do not inject [id].
|
||||
// ::v-global(.foo) -> .foo
|
||||
if (value === ':global' || value === '::v-global') {
|
||||
selector.replaceWith(n.nodes[0])
|
||||
return false
|
||||
n.replaceWith(...n.nodes)
|
||||
if (selector.nodes.length === 1) {
|
||||
shouldInject = false
|
||||
wrappedGlobal = true
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,7 +243,7 @@ function rewriteSelector(
|
|||
if (rule.nodes.some(node => node.type === 'rule')) {
|
||||
const deep = (rule as any).__deep
|
||||
if (!deep) {
|
||||
extractAndWrapNodes(rule)
|
||||
extractAndWrapNodes(rule, wrappedGlobal)
|
||||
const atruleNodes = rule.nodes.filter(node => node.type === 'atrule')
|
||||
for (const atnode of atruleNodes) {
|
||||
extractAndWrapNodes(atnode)
|
||||
|
@ -281,7 +291,7 @@ function isSpaceCombinator(node: selectorParser.Node) {
|
|||
return node.type === 'combinator' && /^\s+$/.test(node.value)
|
||||
}
|
||||
|
||||
function extractAndWrapNodes(parentNode: Rule | AtRule) {
|
||||
function extractAndWrapNodes(parentNode: Rule | AtRule, wrappedGlobal = false) {
|
||||
if (!parentNode.nodes) return
|
||||
const nodes = parentNode.nodes.filter(
|
||||
node => node.type === 'decl' || node.type === 'comment',
|
||||
|
@ -294,6 +304,7 @@ function extractAndWrapNodes(parentNode: Rule | AtRule) {
|
|||
nodes: nodes,
|
||||
selector: '&',
|
||||
})
|
||||
;(wrappedRule as any).__global = wrappedGlobal
|
||||
parentNode.prepend(wrappedRule)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue