From 4fb647c760ec10a5c4a7882cc44527b21ac7615d Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 4 May 2026 11:51:32 -0700 Subject: [PATCH] Fix global keypress handling with shadow DOM elements This fixes an issue where global keypresses were being caught when they shouldn't when there is a shadow DOM element with focus. This can happen if the user has included their own extensions. Arguably the extension should do a stopPropagation, but they don't always do that. I think this is relatively safe way to approach this. Fixes https://github.com/rust-lang/mdBook/issues/2507 --- crates/mdbook-html/front-end/js/book.js | 5 ++++- tests/gui/shadow-dom.goml | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/mdbook-html/front-end/js/book.js b/crates/mdbook-html/front-end/js/book.js index ed1dfca4..fe74b710 100644 --- a/crates/mdbook-html/front-end/js/book.js +++ b/crates/mdbook-html/front-end/js/book.js @@ -24,7 +24,10 @@ function playground_text(playground, hidden = true) { * @returns {boolean} True if the keypress handler should be skipped. */ function mdbook_something_else_has_focus(e) { - return /^(?:input|select|textarea)$/i.test(e.target.nodeName); + // Check composedPath in case the event happened from something generated + // from the shadowDOM. + const target = e.composedPath()[0] || e.target; + return /^(?:input|select|textarea)$/i.test(target.nodeName); } (function codeSnippets() { diff --git a/tests/gui/shadow-dom.goml b/tests/gui/shadow-dom.goml index b1f11210..2b401f20 100644 --- a/tests/gui/shadow-dom.goml +++ b/tests/gui/shadow-dom.goml @@ -8,11 +8,13 @@ press-key: 'x' wait-for: '#shadow-input-host' // See what happens when the s key is pressed. press-key: 's' -wait-for-css-false: ("#mdbook-search-wrapper", {"display": "none"}) +wait-for: 200 +wait-for-css: ("#mdbook-search-wrapper", {"display": "none"}) // Also try the global key handlers. reload: press-key: 'x' wait-for: '#shadow-input-host' press-key: '?' -wait-for-css: ("#mdbook-help-container", {"display": "flex"}) +wait-for: 200 +wait-for-css: ("#mdbook-help-container", {"display": "none"})