From 73055d8d9578d485e3fe846726b50666e1aa56f5 Mon Sep 17 00:00:00 2001 From: edison Date: Thu, 5 Jun 2025 10:02:26 +0800 Subject: [PATCH] fix(custom-element): prevent injecting child styles if shadowRoot is false (#12769) close #12630 --- packages/runtime-core/src/renderer.ts | 7 +++++- .../__tests__/customElement.spec.ts | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index 7b39aa917a..56f9759bc5 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/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 { render: RootRenderFunction @@ -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) } diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts index eee2151716..a2b4c26369 100644 --- a/packages/runtime-dom/__tests__/customElement.spec.ts +++ b/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 = `` + const el = container.childNodes[0] as VueElement + const style = el.shadowRoot?.querySelector('style') + expect(style).toBeUndefined() + }) + test('with nonce', () => { const Foo = defineCustomElement( { -- 2.47.2