Przeglądaj źródła

fix(custom-element): prevent injecting child styles if shadowRoot is false (#12769)

close #12630
edison 11 miesięcy temu
rodzic
commit
73055d8d95

+ 6 - 1
packages/runtime-core/src/renderer.ts

@@ -86,6 +86,7 @@ import { isAsyncWrapper } from './apiAsyncComponent'
 import { isCompatEnabled } from './compat/compatConfig'
 import { DeprecationTypes } from './compat/compatConfig'
 import type { TransitionHooks } from './components/BaseTransition'
+import type { VueElement } from '@vue/runtime-dom'
 
 export interface Renderer<HostElement = RendererElement> {
   render: RootRenderFunction<HostElement>
@@ -1348,7 +1349,11 @@ function baseCreateRenderer(
           }
         } else {
           // custom element style injection
-          if (root.ce) {
+          if (
+            root.ce &&
+            // @ts-expect-error _def is private
+            (root.ce as VueElement)._def.shadowRoot !== false
+          ) {
             root.ce._injectChildStyle(type)
           }
 

+ 24 - 0
packages/runtime-dom/__tests__/customElement.spec.ts

@@ -916,6 +916,30 @@ describe('defineCustomElement', () => {
       assertStyles(el, [`div { color: blue; }`, `div { color: red; }`])
     })
 
+    test("child components should not inject styles to root element's shadow root w/ shadowRoot false", async () => {
+      const Bar = defineComponent({
+        styles: [`div { color: green; }`],
+        render() {
+          return 'bar'
+        },
+      })
+      const Baz = () => h(Bar)
+      const Foo = defineCustomElement(
+        {
+          render() {
+            return [h(Baz)]
+          },
+        },
+        { shadowRoot: false },
+      )
+
+      customElements.define('my-foo-with-shadowroot-false', Foo)
+      container.innerHTML = `<my-foo-with-shadowroot-false></my-foo-with-shadowroot-false>`
+      const el = container.childNodes[0] as VueElement
+      const style = el.shadowRoot?.querySelector('style')
+      expect(style).toBeUndefined()
+    })
+
     test('with nonce', () => {
       const Foo = defineCustomElement(
         {