diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index 2aa027c29ba2e..8706def9f288c 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -188,9 +188,15 @@ async function webviewPreloads(ctx: PreloadContext) { }, 0); }; - const isEditableElement = (element: Element) => { - return element.tagName.toLowerCase() === 'input' || element.tagName.toLowerCase() === 'textarea' - || ('editContext' in element && !!element.editContext); + const hasActiveEditableElement = ( + parent: Node | DocumentFragment, + root: ShadowRoot | Document = document + ): boolean => { + const element = root.activeElement; + return !!(element && parent.contains(element) + && (element.matches(':read-write') || element.tagName.toLowerCase() === 'select' + || (element.shadowRoot && hasActiveEditableElement(element.shadowRoot, element.shadowRoot))) + ); }; // check if an input element is focused within the output element @@ -202,7 +208,7 @@ async function webviewPreloads(ctx: PreloadContext) { } const id = lastFocusedOutput?.id; - if (id && (isEditableElement(activeElement) || activeElement.tagName === 'SELECT')) { + if (id && (hasActiveEditableElement(activeElement, window.document))) { postNotebookMessage('outputInputFocus', { inputFocused: true, id }); activeElement.addEventListener('blur', () => { @@ -309,7 +315,7 @@ async function webviewPreloads(ctx: PreloadContext) { return; } const activeElement = window.document.activeElement; - if (activeElement && isEditableElement(activeElement)) { + if (activeElement && hasActiveEditableElement(activeElement, window.document)) { (activeElement as HTMLInputElement).select(); } }; @@ -335,7 +341,7 @@ async function webviewPreloads(ctx: PreloadContext) { return; } const activeElement = window.document.activeElement; - if (activeElement && isEditableElement(activeElement)) { + if (activeElement && hasActiveEditableElement(activeElement, window.document)) { // Leave for default behavior. return; } @@ -363,7 +369,7 @@ async function webviewPreloads(ctx: PreloadContext) { return; } const activeElement = window.document.activeElement; - if (activeElement && isEditableElement(activeElement)) { + if (activeElement && hasActiveEditableElement(activeElement, window.document)) { // The input element will handle this. return; } @@ -702,7 +708,7 @@ async function webviewPreloads(ctx: PreloadContext) { focusableElement.tabIndex = -1; postNotebookMessage('outputInputFocus', { inputFocused: false, id }); } else { - const inputFocused = isEditableElement(focusableElement); + const inputFocused = hasActiveEditableElement(focusableElement, focusableElement.ownerDocument); postNotebookMessage('outputInputFocus', { inputFocused, id }); }