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
This commit is contained in:
Eric Huss 2026-05-04 11:51:32 -07:00
parent c5c31bb9f5
commit 4fb647c760
2 changed files with 8 additions and 3 deletions

View file

@ -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() {

View file

@ -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"})