make shortcuts keypress listener non-capturing (#3743)

- ZoteroPane.handleKeyDown does not capture events. It is not strictly
necessary now but it helps to avoid future issues such as one solved in
b15fb36f1b. One benefit from this now is
if one tabs onto a toolbarbutton that opens a menu in contextPane (e.g.
an options button in itemBox), clicks space to open the menu and then
escape to close it, this will keep focus where it was, while the capturing
listener would immediately shift the focus to the reader.
- Removed shift-tab specific case from the handler. It looks like it
was handling the shift-tab in the following scenarios:
from notes search bar (can just be handled by Tab),
from "Return to notes list button" in note editor toolbar (it's no longer there),
from a child of zotero-view-item e.g. itembox. (does not apply,
since zotero-view-item itself is a focusable scrollable area)
- use reader.focus() instead of reader.focusFirst() in tab handler,
since focusFirst() focuses the <body> of the browser and it's not interactable.
This commit is contained in:
abaevbog 2024-02-27 01:52:40 -05:00 committed by GitHub
parent bbab56837e
commit 5f0e3d550b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -74,7 +74,7 @@ var ZoteroPane = new function()
Zotero.debug("Initializing Zotero pane");
// Set key down handler
document.addEventListener('keydown', ZoteroPane_Local.handleKeyDown, true);
document.addEventListener('keydown', ZoteroPane_Local.handleKeyDown);
// focusout, unlike blur, bubbles up to document level
// so handleBlur gets triggered when any field, not just the document, looses focus
document.addEventListener('focusout', ZoteroPane.handleBlur);
@ -875,47 +875,24 @@ var ZoteroPane = new function()
*/
function handleKeyDown(event, from) {
if (Zotero_Tabs.selectedIndex > 0) {
// Escape from outside of the reader will focus reader's scrollable area
if (event.key === 'Escape') {
// If focus is on an opened popup, let Escape just close it
if (document.activeElement.open) {
return;
}
if (!document.activeElement.classList.contains('reader')) {
let reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
if (reader) {
reader.focus();
// Keep propagating if current focus is on input or textarea
// The Escape event needs to be handled by itemBox, tagBox, etc. to undo edits.
if (!["input", "textarea"].includes(document.activeElement.tagName)) {
event.preventDefault();
event.stopPropagation();
}
}
}
}
else if (event.key === 'Tab' && event.shiftKey) {
let node = document.activeElement;
if (node && node.nodeType === Node.ELEMENT_NODE && (
node.parentNode.classList.contains('zotero-view-item')
|| node.getAttribute('type') === 'search'
|| node.getAttribute('anonid') === 'editor-view'
&& node.contentWindow.document.activeElement.classList.contains('toolbar-button-return'))) {
let reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
if (reader) {
reader.focus();
}
event.preventDefault();
event.stopPropagation();
}
}
// Tab into the reader from outside of it (e.g. from the contextPane)
// will focus the scrollable area
else if (event.key === 'Tab') {
if (!document.activeElement.classList.contains('reader')) {
setTimeout(() => {
if (document.activeElement.classList.contains('reader')) {
let reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
if (reader) {
reader.focusFirst();
reader.focus();
}
}
});