]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(custom-elements): ensure custom elements can inherit provides from ancestors...
authorThorsten Lünborg <t.luenborg@googlemail.com>
Fri, 11 Nov 2022 02:33:17 +0000 (03:33 +0100)
committerGitHub <noreply@github.com>
Fri, 11 Nov 2022 02:33:17 +0000 (21:33 -0500)
fix #5096

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

index dd087ad279d38c13be192b68ebb0957c5ddb89f2..c45aaa0081dab0c35fef290f3353acd2f3453c85 100644 (file)
@@ -337,6 +337,52 @@ describe('defineCustomElement', () => {
       await nextTick()
       expect(consumer.shadowRoot!.innerHTML).toBe(`<div>changed!</div>`)
     })
+
+    test('inherited from ancestors', async () => {
+      const fooA = ref('FooA!')
+      const fooB = ref('FooB!')
+      const ProviderA = defineCustomElement({
+        provide: {
+          fooA
+        },
+        render() {
+          return h('provider-b')
+        }
+      })
+      const ProviderB = defineCustomElement({
+        provide: {
+          fooB
+        },
+        render() {
+          return h('my-multi-consumer')
+        }
+      })
+
+      const Consumer = defineCustomElement({
+        setup() {
+          const fooA = inject<Ref>('fooA')!
+          const fooB = inject<Ref>('fooB')!
+          return () => h('div', `${fooA.value} ${fooB.value}`)
+        }
+      })
+
+      customElements.define('provider-a', ProviderA)
+      customElements.define('provider-b', ProviderB)
+      customElements.define('my-multi-consumer', Consumer)
+      container.innerHTML = `<provider-a><provider-a>`
+      const providerA = container.childNodes[0] as VueElement
+      const providerB = providerA.shadowRoot!.childNodes[0] as VueElement
+      const consumer = providerB.shadowRoot!.childNodes[0] as VueElement
+
+      expect(consumer.shadowRoot!.innerHTML).toBe(`<div>FooA! FooB!</div>`)
+
+      fooA.value = 'changedA!'
+      fooB.value = 'changedB!'
+      await nextTick()
+      expect(consumer.shadowRoot!.innerHTML).toBe(
+        `<div>changedA! changedB!</div>`
+      )
+    })
   })
 
   describe('styles', () => {
index 5108e3bdfbe82ead778cf0aaed7b9dc221e1d9c3..5bd81345a45dfd6a2c03fd9309b6e669be25b72c 100644 (file)
@@ -368,6 +368,7 @@ export class VueElement extends BaseClass {
         ) {
           if (parent instanceof VueElement) {
             instance.parent = parent._instance
+            instance.provides = parent._instance!.provides
             break
           }
         }