diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js index 90c0f03b65..e41351b140 100644 --- a/chrome/content/zotero/zoteroPane.js +++ b/chrome/content/zotero/zoteroPane.js @@ -3445,6 +3445,11 @@ var ZoteroPane = new function () { * Show context menu once it's ready */ this.onItemsContextMenuOpen = async function (event, x, y) { + // Library section headers (in a grouped cross-library view) aren't items, so + // don't show the item context menu when one is right-clicked + if (event.target?.closest?.('.library-header-row')) { + return; + } await ZoteroPane.buildItemContextMenu(); x = x || event.screenX; y = y || event.screenY; diff --git a/test/tests/zoteroPaneTest.js b/test/tests/zoteroPaneTest.js index a27fcbf3d0..9adb9e8d46 100644 --- a/test/tests/zoteroPaneTest.js +++ b/test/tests/zoteroPaneTest.js @@ -1137,7 +1137,40 @@ describe("ZoteroPane", function () { await selectLibrary(win); await group.eraseTx(); }); - + + it("shouldn't open the item context menu on a library header row", async function () { + let group = await createGroup(); + let c1 = await createDataObject('collection'); + let c2 = await createDataObject('collection', { libraryID: group.libraryID }); + await createDataObject('item', { collections: [c1.id] }); + await createDataObject('item', { libraryID: group.libraryID, collections: [c2.id] }); + + // Cross-library multiple-collection selection -> grouped view with headers + await zp.collectionsView.expandLibrary(group.libraryID); + let cv = zp.collectionsView; + await cv.selectByID("C" + c1.id); + await waitForItemsLoad(win); + cv.selection.toggleSelect(cv.getRowIndexByID("C" + c2.id)); + await zp.onCollectionSelected(); + await zp.itemsView.waitForLoad(); + + let headerRow = zp.itemsView.getRowIndexByID("L" + Zotero.Libraries.userLibraryID); + let headerNode = win.document.getElementById(`${zp.itemsView.id}-row-${headerRow}`); + assert.isTrue(headerNode.classList.contains('library-header-row')); + + let spy = sinon.spy(zp, 'buildItemContextMenu'); + try { + await zp.onItemsContextMenuOpen({ target: headerNode, screenX: 0, screenY: 0 }); + assert.isFalse(spy.called, "Context menu shouldn't be built for a header row"); + } + finally { + spy.restore(); + } + + await selectLibrary(win); + await group.eraseTx(); + }); + it("should show “Export Note…” for standalone file attachment with note", async function () { var item1 = await importFileAttachment('test.png'); item1.setNote('
Foo
');