Skip to content

Commit f06c81a

Browse files
authored
fix(custom-element): properly locate parent when slotted in shadow dom (#12480)
close #12479
1 parent cea3cf7 commit f06c81a

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

packages/runtime-dom/__tests__/customElement.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,31 @@ describe('defineCustomElement', () => {
995995
)
996996
})
997997

998+
test('should resolve correct parent when element is slotted in shadow DOM', async () => {
999+
const GrandParent = defineCustomElement({
1000+
provide: {
1001+
foo: ref('GrandParent'),
1002+
},
1003+
render() {
1004+
return h('my-parent-in-shadow', h('slot'))
1005+
},
1006+
})
1007+
const Parent = defineCustomElement({
1008+
provide: {
1009+
foo: ref('Parent'),
1010+
},
1011+
render() {
1012+
return h('slot')
1013+
},
1014+
})
1015+
customElements.define('my-grand-parent', GrandParent)
1016+
customElements.define('my-parent-in-shadow', Parent)
1017+
container.innerHTML = `<my-grand-parent><my-consumer></my-consumer></my-grand-parent>`
1018+
const grandParent = container.childNodes[0] as VueElement,
1019+
consumer = grandParent.firstElementChild as VueElement
1020+
expect(consumer.shadowRoot!.textContent).toBe('Parent')
1021+
})
1022+
9981023
// #13212
9991024
test('inherited from app context within nested elements', async () => {
10001025
const outerValues: (string | undefined)[] = []

packages/runtime-dom/src/apiCustomElement.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,12 @@ export class VueElement
291291
// locate nearest Vue custom element parent for provide/inject
292292
let parent: Node | null = this
293293
while (
294-
(parent = parent && (parent.parentNode || (parent as ShadowRoot).host))
294+
(parent =
295+
parent &&
296+
// #12479 should check assignedSlot first to get correct parent
297+
((parent as Element).assignedSlot ||
298+
parent.parentNode ||
299+
(parent as ShadowRoot).host))
295300
) {
296301
if (parent instanceof VueElement) {
297302
this._parent = parent

0 commit comments

Comments
 (0)