From 287ae1895067358a372a7724021db5e33713a0cb Mon Sep 17 00:00:00 2001 From: Simon Schwedes Date: Fri, 12 Dec 2025 16:17:16 +0100 Subject: [PATCH 1/2] fix(v-model.trim): correct the activeElement discovery for shadow DOM --- packages/runtime-dom/src/directives/vModel.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index 3b446e320c5..4ac56828035 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -51,6 +51,12 @@ function castValue(value: string, trim?: boolean, number?: boolean | null) { return value } +function activeElement() { + return document.activeElement && document.activeElement.shadowRoot + ? document.activeElement.shadowRoot.activeElement + : document.activeElement +} + // We are exporting the v-model runtime directly as vnode hooks so that it can // be tree-shaken in case v-model is never used. export const vModelText: ModelDirective< @@ -102,7 +108,7 @@ export const vModelText: ModelDirective< return } - if (document.activeElement === el && el.type !== 'range') { + if (activeElement() === el && el.type !== 'range') { // #8546 if (lazy && value === oldValue) { return From acebcddda97f76270e30663e54041a90834864f3 Mon Sep 17 00:00:00 2001 From: Simon Schwedes Date: Fri, 12 Dec 2025 18:23:10 +0100 Subject: [PATCH 2/2] fix(v-model.trim): improve on previous approach The current approach grants support for nested shadow doms --- packages/runtime-dom/src/directives/vModel.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index 4ac56828035..b49bf809e27 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -51,12 +51,6 @@ function castValue(value: string, trim?: boolean, number?: boolean | null) { return value } -function activeElement() { - return document.activeElement && document.activeElement.shadowRoot - ? document.activeElement.shadowRoot.activeElement - : document.activeElement -} - // We are exporting the v-model runtime directly as vnode hooks so that it can // be tree-shaken in case v-model is never used. export const vModelText: ModelDirective< @@ -108,7 +102,12 @@ export const vModelText: ModelDirective< return } - if (activeElement() === el && el.type !== 'range') { + const rootNode = el.getRootNode() + if ( + (rootNode instanceof Document || rootNode instanceof ShadowRoot) && + rootNode.activeElement === el && + el.type !== 'range' + ) { // #8546 if (lazy && value === oldValue) { return