fix(sfc): fix v-slotted attribute injection
This commit is contained in:
parent
3a3a24d621
commit
362831d8ab
@ -55,52 +55,73 @@ describe('SFC scoped CSS', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('::v-deep', () => {
|
test('::v-deep', () => {
|
||||||
expect(compile(`::v-deep(.foo) { color: red; }`)).toMatch(
|
expect(compile(`::v-deep(.foo) { color: red; }`)).toMatchInlineSnapshot(`
|
||||||
`[test] .foo { color: red;`
|
"[test] .foo { color: red;
|
||||||
)
|
}"
|
||||||
expect(compile(`::v-deep(.foo .bar) { color: red; }`)).toMatch(
|
`)
|
||||||
`[test] .foo .bar { color: red;`
|
expect(compile(`::v-deep(.foo .bar) { color: red; }`))
|
||||||
)
|
.toMatchInlineSnapshot(`
|
||||||
expect(compile(`.baz .qux ::v-deep(.foo .bar) { color: red; }`)).toMatch(
|
"[test] .foo .bar { color: red;
|
||||||
`.baz .qux[test] .foo .bar { color: red;`
|
}"
|
||||||
)
|
`)
|
||||||
|
expect(compile(`.baz .qux ::v-deep(.foo .bar) { color: red; }`))
|
||||||
|
.toMatchInlineSnapshot(`
|
||||||
|
".baz .qux[test] .foo .bar { color: red;
|
||||||
|
}"
|
||||||
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('::v-slotted', () => {
|
test('::v-slotted', () => {
|
||||||
expect(compile(`::v-slotted(.foo) { color: red; }`)).toMatch(
|
expect(compile(`::v-slotted(.foo) { color: red; }`)).toMatchInlineSnapshot(`
|
||||||
`.foo[test-s] { color: red;`
|
".foo[test-s] { color: red;
|
||||||
)
|
}"
|
||||||
expect(compile(`::v-slotted(.foo .bar) { color: red; }`)).toMatch(
|
`)
|
||||||
`.foo .bar[test-s] { color: red;`
|
expect(compile(`::v-slotted(.foo .bar) { color: red; }`))
|
||||||
)
|
.toMatchInlineSnapshot(`
|
||||||
expect(compile(`.baz .qux ::v-slotted(.foo .bar) { color: red; }`)).toMatch(
|
".foo .bar[test-s] { color: red;
|
||||||
`.baz .qux[test] .foo .bar[test-s] { color: red;`
|
}"
|
||||||
)
|
`)
|
||||||
|
expect(compile(`.baz .qux ::v-slotted(.foo .bar) { color: red; }`))
|
||||||
|
.toMatchInlineSnapshot(`
|
||||||
|
".baz .qux .foo .bar[test-s] { color: red;
|
||||||
|
}"
|
||||||
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('::v-global', () => {
|
test('::v-global', () => {
|
||||||
expect(compile(`::v-global(.foo) { color: red; }`)).toMatch(
|
expect(compile(`::v-global(.foo) { color: red; }`)).toMatchInlineSnapshot(`
|
||||||
`.foo { color: red;`
|
".foo { color: red;
|
||||||
)
|
}"
|
||||||
expect(compile(`::v-global(.foo .bar) { color: red; }`)).toMatch(
|
`)
|
||||||
`.foo .bar { color: red;`
|
expect(compile(`::v-global(.foo .bar) { color: red; }`))
|
||||||
)
|
.toMatchInlineSnapshot(`
|
||||||
|
".foo .bar { color: red;
|
||||||
|
}"
|
||||||
|
`)
|
||||||
// global ignores anything before it
|
// global ignores anything before it
|
||||||
expect(compile(`.baz .qux ::v-global(.foo .bar) { color: red; }`)).toMatch(
|
expect(compile(`.baz .qux ::v-global(.foo .bar) { color: red; }`))
|
||||||
`.foo .bar { color: red;`
|
.toMatchInlineSnapshot(`
|
||||||
)
|
".foo .bar { color: red;
|
||||||
|
}"
|
||||||
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('media query', () => {
|
test('media query', () => {
|
||||||
expect(compile(`@media print { .foo { color: red }}`)).toMatch(
|
expect(compile(`@media print { .foo { color: red }}`))
|
||||||
/@media print {\s+\.foo\[test\] \{ color: red/
|
.toMatchInlineSnapshot(`
|
||||||
)
|
"@media print {
|
||||||
|
.foo[test] { color: red
|
||||||
|
}}"
|
||||||
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('supports query', () => {
|
test('supports query', () => {
|
||||||
expect(
|
expect(compile(`@supports(display: grid) { .foo { display: grid }}`))
|
||||||
compile(`@supports(display: grid) { .foo { display: grid }}`)
|
.toMatchInlineSnapshot(`
|
||||||
).toMatch(/@supports\(display: grid\) {\s+\.foo\[test\] \{ display: grid/)
|
"@supports(display: grid) {
|
||||||
|
.foo[test] { display: grid
|
||||||
|
}}"
|
||||||
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('scoped keyframes', () => {
|
test('scoped keyframes', () => {
|
||||||
@ -169,17 +190,23 @@ describe('SFC scoped CSS', () => {
|
|||||||
id: 'test'
|
id: 'test'
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(code).toMatch(`.foo[test], .bar[test] { color: red;`)
|
expect(code).toMatchInlineSnapshot(`
|
||||||
|
".foo[test], .bar[test] { color: red;
|
||||||
|
}"
|
||||||
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('deprecated syntax', () => {
|
describe('deprecated syntax', () => {
|
||||||
test('::v-deep as combinator', () => {
|
test('::v-deep as combinator', () => {
|
||||||
expect(compile(`::v-deep .foo { color: red; }`)).toMatch(
|
expect(compile(`::v-deep .foo { color: red; }`)).toMatchInlineSnapshot(`
|
||||||
`[test] .foo { color: red;`
|
"[test] .foo { color: red;
|
||||||
)
|
}"
|
||||||
expect(compile(`.bar ::v-deep .foo { color: red; }`)).toMatch(
|
`)
|
||||||
`.bar[test] .foo { color: red;`
|
expect(compile(`.bar ::v-deep .foo { color: red; }`))
|
||||||
)
|
.toMatchInlineSnapshot(`
|
||||||
|
".bar[test] .foo { color: red;
|
||||||
|
}"
|
||||||
|
`)
|
||||||
expect(
|
expect(
|
||||||
`::v-deep usage as a combinator has been deprecated.`
|
`::v-deep usage as a combinator has been deprecated.`
|
||||||
).toHaveBeenWarned()
|
).toHaveBeenWarned()
|
||||||
@ -187,7 +214,10 @@ describe('SFC scoped CSS', () => {
|
|||||||
|
|
||||||
test('>>> (deprecated syntax)', () => {
|
test('>>> (deprecated syntax)', () => {
|
||||||
const code = compile(`>>> .foo { color: red; }`)
|
const code = compile(`>>> .foo { color: red; }`)
|
||||||
expect(code).toMatch(`[test] .foo { color: red;`)
|
expect(code).toMatchInlineSnapshot(`
|
||||||
|
"[test] .foo { color: red;
|
||||||
|
}"
|
||||||
|
`)
|
||||||
expect(
|
expect(
|
||||||
`the >>> and /deep/ combinators have been deprecated.`
|
`the >>> and /deep/ combinators have been deprecated.`
|
||||||
).toHaveBeenWarned()
|
).toHaveBeenWarned()
|
||||||
@ -195,7 +225,10 @@ describe('SFC scoped CSS', () => {
|
|||||||
|
|
||||||
test('/deep/ (deprecated syntax)', () => {
|
test('/deep/ (deprecated syntax)', () => {
|
||||||
const code = compile(`/deep/ .foo { color: red; }`)
|
const code = compile(`/deep/ .foo { color: red; }`)
|
||||||
expect(code).toMatch(`[test] .foo { color: red;`)
|
expect(code).toMatchInlineSnapshot(`
|
||||||
|
"[test] .foo { color: red;
|
||||||
|
}"
|
||||||
|
`)
|
||||||
expect(
|
expect(
|
||||||
`the >>> and /deep/ combinators have been deprecated.`
|
`the >>> and /deep/ combinators have been deprecated.`
|
||||||
).toHaveBeenWarned()
|
).toHaveBeenWarned()
|
@ -22,7 +22,7 @@ export default postcss.plugin('vue-scoped', (options: any) => (root: Root) => {
|
|||||||
node.selector = selectorParser(selectors => {
|
node.selector = selectorParser(selectors => {
|
||||||
function rewriteSelector(selector: Selector, slotted?: boolean) {
|
function rewriteSelector(selector: Selector, slotted?: boolean) {
|
||||||
let node: Node | null = null
|
let node: Node | null = null
|
||||||
|
let shouldInject = true
|
||||||
// find the last child node to insert attribute selector
|
// find the last child node to insert attribute selector
|
||||||
selector.each(n => {
|
selector.each(n => {
|
||||||
// DEPRECATED ">>>" and "/deep/" combinator
|
// DEPRECATED ">>>" and "/deep/" combinator
|
||||||
@ -81,6 +81,9 @@ export default postcss.plugin('vue-scoped', (options: any) => (root: Root) => {
|
|||||||
rewriteSelector(n.nodes[0] as Selector, true /* slotted */)
|
rewriteSelector(n.nodes[0] as Selector, true /* slotted */)
|
||||||
selector.insertAfter(n, n.nodes[0])
|
selector.insertAfter(n, n.nodes[0])
|
||||||
selector.removeChild(n)
|
selector.removeChild(n)
|
||||||
|
// since slotted attribute already scopes the selector there's no
|
||||||
|
// need for the non-slot attribute.
|
||||||
|
shouldInject = false
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,6 +110,7 @@ export default postcss.plugin('vue-scoped', (options: any) => (root: Root) => {
|
|||||||
selector.first.spaces.before = ''
|
selector.first.spaces.before = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shouldInject) {
|
||||||
const idToAdd = slotted ? id + '-s' : id
|
const idToAdd = slotted ? id + '-s' : id
|
||||||
selector.insertAfter(
|
selector.insertAfter(
|
||||||
// If node is null it means we need to inject [id] at the start
|
// If node is null it means we need to inject [id] at the start
|
||||||
@ -120,6 +124,7 @@ export default postcss.plugin('vue-scoped', (options: any) => (root: Root) => {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
selectors.each(selector => rewriteSelector(selector as Selector))
|
selectors.each(selector => rewriteSelector(selector as Selector))
|
||||||
}).processSync(node.selector)
|
}).processSync(node.selector)
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user