Merge pull request #3087 from ehuss/limit-global-keypress
Fix global keypresses triggering when other elements are in focus
This commit is contained in:
commit
9190b5d093
12 changed files with 129 additions and 5 deletions
|
|
@ -19,6 +19,17 @@ function playground_text(playground, hidden = true) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for global keypress handlers so they don't trigger when certain elements are active.
|
||||
* @returns {boolean} True if the keypress handler should be skipped.
|
||||
*/
|
||||
function mdbook_something_else_has_focus(e) {
|
||||
// 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() {
|
||||
function fetch_with_timeout(url, options, timeout = 6000) {
|
||||
return Promise.race([
|
||||
|
|
@ -648,12 +659,15 @@ aria-label="Show hidden lines"></button>';
|
|||
|
||||
(function chapterNavigation() {
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.altKey || e.ctrlKey || e.metaKey) {
|
||||
return;
|
||||
}
|
||||
if (window.search && window.search.hasFocus()) {
|
||||
if (e.altKey ||
|
||||
e.ctrlKey ||
|
||||
e.metaKey ||
|
||||
window.search && window.search.hasFocus() ||
|
||||
mdbook_something_else_has_focus(e)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const html = document.querySelector('html');
|
||||
|
||||
function next() {
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ window.search = window.search || {};
|
|||
e.shiftKey ||
|
||||
e.target.type === 'textarea' ||
|
||||
e.target.type === 'text' ||
|
||||
!hasFocus() && /^(?:input|select|textarea)$/i.test(e.target.nodeName)
|
||||
!hasFocus() && mdbook_something_else_has_focus(e)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
6
tests/gui/books/editor/book.toml
Normal file
6
tests/gui/books/editor/book.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[book]
|
||||
title = "editor"
|
||||
language = "en"
|
||||
|
||||
[output.html.playground]
|
||||
editable = true
|
||||
4
tests/gui/books/editor/src/SUMMARY.md
Normal file
4
tests/gui/books/editor/src/SUMMARY.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# Summary
|
||||
|
||||
- [Chapter 1](./chapter_1.md)
|
||||
- [Chapter 2](./chapter_2.md)
|
||||
7
tests/gui/books/editor/src/chapter_1.md
Normal file
7
tests/gui/books/editor/src/chapter_1.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Chapter 1
|
||||
|
||||
```rust,editable
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
```
|
||||
1
tests/gui/books/editor/src/chapter_2.md
Normal file
1
tests/gui/books/editor/src/chapter_2.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Chapter 2
|
||||
6
tests/gui/books/shadow-dom/book.toml
Normal file
6
tests/gui/books/shadow-dom/book.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[book]
|
||||
title = "shadow-dom"
|
||||
language = "en"
|
||||
|
||||
[output.html]
|
||||
additional-js = ["shadow-dom.js"]
|
||||
38
tests/gui/books/shadow-dom/shadow-dom.js
Normal file
38
tests/gui/books/shadow-dom/shadow-dom.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
(function() {
|
||||
let shadowHost = null;
|
||||
let shadowInput = null;
|
||||
|
||||
document.addEventListener('keypress', function(e) {
|
||||
if (e.key === 'x' || e.key === 'X') {
|
||||
if (shadowHost && shadowHost.isConnected) {
|
||||
shadowInput.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
shadowHost = document.createElement('div');
|
||||
shadowHost.id = 'shadow-input-host';
|
||||
shadowHost.style.cssText = 'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:9999;';
|
||||
|
||||
document.body.appendChild(shadowHost);
|
||||
|
||||
const shadowRoot = shadowHost.attachShadow({ mode: 'open' });
|
||||
|
||||
shadowInput = document.createElement('input');
|
||||
shadowInput.type = 'text';
|
||||
shadowInput.id = 'shadow-input';
|
||||
shadowInput.placeholder = 'Shadow DOM input (press Escape to close)';
|
||||
shadowInput.style.cssText = 'font-size:1.2em;padding:8px;width:300px;';
|
||||
|
||||
shadowRoot.appendChild(shadowInput);
|
||||
shadowInput.focus();
|
||||
|
||||
shadowInput.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
shadowHost.remove();
|
||||
shadowHost = null;
|
||||
shadowInput = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
3
tests/gui/books/shadow-dom/src/SUMMARY.md
Normal file
3
tests/gui/books/shadow-dom/src/SUMMARY.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Summary
|
||||
|
||||
- [Chapter 1](./chapter_1.md)
|
||||
1
tests/gui/books/shadow-dom/src/chapter_1.md
Normal file
1
tests/gui/books/shadow-dom/src/chapter_1.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Chapter 1
|
||||
24
tests/gui/editor-keypress.goml
Normal file
24
tests/gui/editor-keypress.goml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Tests for global keypress handlers when ACE editor is in focus.
|
||||
// See https://github.com/rust-lang/mdBook/issues/3064
|
||||
|
||||
go-to: |DOC_PATH| + "editor/chapter_1.html"
|
||||
|
||||
click: ".ace_editor"
|
||||
press-key: "s"
|
||||
// Wait briefly to allow any event handlers triggered by the keypress to run.
|
||||
// Otherwise there is a race here since the wrapper is already display:none.
|
||||
wait-for: 200
|
||||
wait-for-css: ("#mdbook-search-wrapper", {"display": "none"})
|
||||
|
||||
// ? inside ACE editor shouldn't show global help popup.
|
||||
press-key: "?"
|
||||
wait-for: 200
|
||||
wait-for-css: ("#mdbook-help-container", {"display": "none"})
|
||||
|
||||
// Make sure arrow keys don"t navigate.
|
||||
press-key: "ArrowRight"
|
||||
wait-for: 200
|
||||
assert-window-property: ({"location": |DOC_PATH| + "editor/chapter_1.html"})
|
||||
press-key: "ArrowLeft"
|
||||
wait-for: 200
|
||||
assert-window-property: ({"location": |DOC_PATH| + "editor/chapter_1.html"})
|
||||
20
tests/gui/shadow-dom.goml
Normal file
20
tests/gui/shadow-dom.goml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// Tests the keypress handler when there is a shadow-dom element.
|
||||
// See https://github.com/rust-lang/mdBook/issues/2507
|
||||
|
||||
go-to: |DOC_PATH| + "shadow-dom/chapter_1.html"
|
||||
|
||||
// Open the shadow-dom generated element.
|
||||
press-key: 'x'
|
||||
wait-for: '#shadow-input-host'
|
||||
// See what happens when the s key is pressed.
|
||||
press-key: 's'
|
||||
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: 200
|
||||
wait-for-css: ("#mdbook-help-container", {"display": "none"})
|
||||
Loading…
Add table
Reference in a new issue