From 3a34c6a18f034381e32f77e72b74478810f296ea Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Sun, 5 Jul 2026 17:01:09 -0400 Subject: [PATCH] Run a focused button's action on Enter in Advanced Search The pane-level Enter handler ran the default action (save in the saved editor, submit in the temporary pane) regardless of the event target, so Enter with focus on the Cancel button saved and closed the editor, and Enter on Clear ran the search. Click the focused button instead, which the platform otherwise only does for Space. --- .../zotero/elements/advancedSearchPane.js | 7 +++++ test/tests/advancedSearchTest.js | 29 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/chrome/content/zotero/elements/advancedSearchPane.js b/chrome/content/zotero/elements/advancedSearchPane.js index b2601ce91f..601887a37c 100644 --- a/chrome/content/zotero/elements/advancedSearchPane.js +++ b/chrome/content/zotero/elements/advancedSearchPane.js @@ -78,6 +78,13 @@ // Shift-Enter adds a new condition (handled by the search element), so // don't run/save the search for it if (event.key === 'Enter' && !event.shiftKey) { + // Enter on a focused button runs that button (which the platform only does + // for Space), not the pane's default action + let button = event.target.closest && event.target.closest('button, toolbarbutton'); + if (button) { + button.click(); + return; + } if (this.type === 'temporary') { await this.submit(); } diff --git a/test/tests/advancedSearchTest.js b/test/tests/advancedSearchTest.js index 31b15ab5c1..2025eab7c9 100644 --- a/test/tests/advancedSearchTest.js +++ b/test/tests/advancedSearchTest.js @@ -692,6 +692,35 @@ describe("Advanced Search", function () { await selectLibrary(win); }); + it("should run a focused button's action on Enter instead of the pane default", async function () { + var saved = await createDataObject('search', { name: "EnterOnCancel" }); + await select(win, saved); + await zp.setSavedSearchEditorState('open'); + assert.equal(deck.selectedSearchType, 'saved'); + + var savedPane = deck.pane; + var save = sinon.stub(savedPane, 'save'); + var cancel = sinon.stub(savedPane, 'cancel'); + try { + var cancelButton = savedPane.querySelector('.cancel-button'); + cancelButton.focus(); + cancelButton.dispatchEvent( + new win.KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true }) + ); + // Enter on the focused Cancel button cancels -- it mustn't save + assert.isTrue(save.notCalled); + assert.isTrue(cancel.called); + } + finally { + save.restore(); + cancel.restore(); + } + + await zp.setSavedSearchEditorState('closed'); + await saved.eraseTx(); + await selectLibrary(win); + }); + it("should prompt for a name when saving a new search", async function () { await selectLibrary(win); await zp.toggleAdvancedSearchState('open');