mirror of
https://github.com/zotero/zotero.git
synced 2026-10-05 02:43:38 +00:00
Include plugin toolbar buttons in keyboard focus route
This commit is contained in:
parent
8e7639d73d
commit
785e363390
2 changed files with 85 additions and 3 deletions
|
|
@ -174,6 +174,12 @@ var ZoteroPane = new function () {
|
|||
function setUpKeyboardNavigation() {
|
||||
let collectionTreeToolbar = document.getElementById("zotero-toolbar-collection-tree");
|
||||
let itemTreeToolbar = document.getElementById("zotero-toolbar-item-tree");
|
||||
// Plugins append their toolbar buttons after Zotero's built-in controls.
|
||||
// Read the current buttons for each key event so installation needs no registration.
|
||||
let pluginButtons = () => [...document.querySelectorAll(
|
||||
'#zotero-items-toolbar > toolbarbutton[tabindex="0"]'
|
||||
)].filter(button => !button.disabled && !button.hidden
|
||||
&& getComputedStyle(button).display !== 'none');
|
||||
let titleBar = document.getElementById("zotero-title-bar");
|
||||
let itemTree = document.getElementById("zotero-items-tree");
|
||||
let collectionsTree = document.getElementById("zotero-collections-tree");
|
||||
|
|
@ -367,6 +373,11 @@ var ZoteroPane = new function () {
|
|||
});
|
||||
|
||||
itemTreeToolbar.addEventListener("keydown", (event) => {
|
||||
let adjacentPluginButton = (button, direction) => {
|
||||
let buttons = pluginButtons();
|
||||
let index = buttons.indexOf(button);
|
||||
return index === -1 ? null : buttons[index + direction];
|
||||
};
|
||||
let actionsMap = {
|
||||
'zotero-tb-add': {
|
||||
ArrowNext: () => document.getElementById("zotero-tb-lookup"),
|
||||
|
|
@ -397,7 +408,7 @@ var ZoteroPane = new function () {
|
|||
ShiftTab: () => document.getElementById('zotero-tb-collections-search').click()
|
||||
},
|
||||
'zotero-tb-note-add': {
|
||||
ArrowNext: () => null,
|
||||
ArrowNext: () => pluginButtons()[0] || null,
|
||||
ArrowPrevious: () => document.getElementById("zotero-tb-attachment-add"),
|
||||
Tab: () => document.getElementById("zotero-tb-search").focus(),
|
||||
ShiftTab: () => document.getElementById('zotero-tb-collections-search').click()
|
||||
|
|
@ -420,10 +431,21 @@ var ZoteroPane = new function () {
|
|||
ShiftTab: () => document.getElementById("zotero-tb-search-textbox")
|
||||
},
|
||||
'zotero-tb-toggle-item-pane-stacked': {
|
||||
Tab: () => itemTree.querySelector(".virtualized-table"),
|
||||
Tab: () => pluginButtons()[0] || itemTree.querySelector(".virtualized-table"),
|
||||
ShiftTab: () => document.getElementById("zotero-tb-search-advanced-button")
|
||||
},
|
||||
};
|
||||
if (pluginButtons().includes(event.target)) {
|
||||
actionsMap[event.target.id] = {
|
||||
ArrowNext: () => adjacentPluginButton(event.target, 1) || null,
|
||||
ArrowPrevious: () => adjacentPluginButton(event.target, -1)
|
||||
|| document.getElementById('zotero-tb-note-add'),
|
||||
Tab: () => adjacentPluginButton(event.target, 1)
|
||||
|| itemTree.querySelector(".virtualized-table"),
|
||||
ShiftTab: () => adjacentPluginButton(event.target, -1)
|
||||
|| document.getElementById('zotero-tb-toggle-item-pane-stacked')
|
||||
};
|
||||
}
|
||||
moveFocus(actionsMap, event, true);
|
||||
});
|
||||
|
||||
|
|
@ -468,7 +490,8 @@ var ZoteroPane = new function () {
|
|||
if (advancedSearchDeck?.state === 'collapsed') {
|
||||
return document.querySelector('#zotero-tb-search .advanced-close-button');
|
||||
}
|
||||
return document.getElementById('zotero-tb-toggle-item-pane-stacked');
|
||||
return pluginButtons().at(-1)
|
||||
|| document.getElementById('zotero-tb-toggle-item-pane-stacked');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1898,6 +1898,65 @@ describe("ZoteroPane", function () {
|
|||
doc.activeElement.dispatchEvent(leftArrow);
|
||||
assert.equal(doc.activeElement.id, "zotero-tb-add");
|
||||
});
|
||||
|
||||
it("should include plugin toolbarbuttons in the Tab and arrow routes", async function () {
|
||||
if (!await activatePaneWindow()) {
|
||||
this.skip();
|
||||
}
|
||||
let toolbar = doc.getElementById('zotero-items-toolbar');
|
||||
let buttons = ['first', 'second'].map(name => {
|
||||
let button = doc.createXULElement('toolbarbutton');
|
||||
button.id = `test-plugin-${name}`;
|
||||
button.setAttribute('tabindex', '0');
|
||||
toolbar.append(button);
|
||||
return button;
|
||||
});
|
||||
try {
|
||||
// The plugin buttons are appended after the search and pane-toggle
|
||||
// controls, so keyboard traversal must reach them in that order.
|
||||
doc.getElementById('zotero-tb-add').focus();
|
||||
doc.activeElement.dispatchEvent(tab);
|
||||
assert.equal(doc.activeElement.id, 'zotero-tb-search-textbox');
|
||||
let paneToggle = doc.getElementById('zotero-tb-toggle-item-pane-stacked');
|
||||
paneToggle.dispatchEvent(tab);
|
||||
assert.equal(doc.activeElement, buttons[0]);
|
||||
doc.activeElement.dispatchEvent(tab);
|
||||
assert.equal(doc.activeElement, buttons[1]);
|
||||
doc.activeElement.dispatchEvent(tab);
|
||||
assert.equal(doc.activeElement,
|
||||
doc.getElementById('zotero-items-tree').querySelector('.virtualized-table'));
|
||||
doc.activeElement.dispatchEvent(shiftTab);
|
||||
assert.equal(doc.activeElement, buttons[1]);
|
||||
doc.activeElement.dispatchEvent(shiftTab);
|
||||
assert.equal(doc.activeElement, buttons[0]);
|
||||
doc.activeElement.dispatchEvent(shiftTab);
|
||||
assert.include(
|
||||
['zotero-tb-toggle-item-pane-stacked', 'zotero-tb-search-advanced-button'],
|
||||
doc.activeElement.id
|
||||
);
|
||||
doc.getElementById('zotero-tb-lookup').focus();
|
||||
doc.activeElement.dispatchEvent(tab);
|
||||
assert.equal(doc.activeElement.id, 'zotero-tb-search-textbox');
|
||||
doc.getElementById('zotero-tb-attachment-add').focus();
|
||||
doc.activeElement.dispatchEvent(tab);
|
||||
assert.equal(doc.activeElement.id, 'zotero-tb-search-textbox');
|
||||
|
||||
doc.getElementById('zotero-tb-note-add').focus();
|
||||
doc.activeElement.dispatchEvent(rightArrow);
|
||||
assert.equal(doc.activeElement, buttons[0]);
|
||||
doc.activeElement.dispatchEvent(rightArrow);
|
||||
assert.equal(doc.activeElement, buttons[1]);
|
||||
doc.activeElement.dispatchEvent(leftArrow);
|
||||
assert.equal(doc.activeElement, buttons[0]);
|
||||
|
||||
buttons[0].hidden = true;
|
||||
paneToggle.dispatchEvent(tab);
|
||||
assert.equal(doc.activeElement, buttons[1]);
|
||||
}
|
||||
finally {
|
||||
buttons.forEach(button => button.remove());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("#addAttachmentFromDialog()", function () {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue