From 6ff349d65d35c41cbf75eeae98caafa6bbb9836a Mon Sep 17 00:00:00 2001 From: abaevbog Date: Wed, 4 Jun 2025 23:20:13 -0700 Subject: [PATCH] Select child attachment after a file is drag-dropped onto a top-level item (#5328) And also handle attachments added via context menu Fixes: zotero#5320 --- chrome/content/zotero/itemTree.jsx | 4 ++++ chrome/content/zotero/zoteroPane.js | 11 ++++++++--- test/tests/itemTreeTest.js | 25 +++++++++++++++++++++++++ test/tests/zoteroPaneTest.js | 13 +++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/chrome/content/zotero/itemTree.jsx b/chrome/content/zotero/itemTree.jsx index 4ae8181c61..35e8b6d31e 100644 --- a/chrome/content/zotero/itemTree.jsx +++ b/chrome/content/zotero/itemTree.jsx @@ -2680,6 +2680,10 @@ var ItemTree = class ItemTree extends LibraryTree { addedItems.push(item); } } + // Select children created after drag-drop onto a top-level item + if (parentItemID && addedItems.length) { + await this.selectItems(addedItems.map(item => item.id)); + } } finally { await Zotero.Notifier.commit(notifierQueue); diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js index c6c486ba99..8ab3827882 100644 --- a/chrome/content/zotero/zoteroPane.js +++ b/chrome/content/zotero/zoteroPane.js @@ -4546,7 +4546,7 @@ var ZoteroPane = new function() }; - this.addAttachmentFromURI = Zotero.Promise.method(function (link, itemID) { + this.addAttachmentFromURI = async function (link, itemID) { if (!this.canEdit()) { this.displayCannotEditLibraryMessage(); return; @@ -4556,12 +4556,13 @@ var ZoteroPane = new function() window.openDialog('chrome://zotero/content/attachLink.xhtml', 'zotero-attach-uri-dialog', 'centerscreen, modal', io); if (!io.out) return; - return Zotero.Attachments.linkFromURL({ + await Zotero.Attachments.linkFromURL({ url: io.out.link, parentItemID: itemID, title: io.out.title }); - }); + await this.selectItem(item.id); + }; /** * @param {Boolean} [link] @@ -4681,6 +4682,10 @@ var ZoteroPane = new function() addedItems.push(item); } + // Select added child attachments + if (parentItemID && addedItems.length) { + await this.selectItems(addedItems.map(item => item.id)); + } // Automatically retrieve metadata for top-level PDFs if (!parentItemID) { Zotero.RecognizeDocument.autoRecognizeItems(addedItems); diff --git a/test/tests/itemTreeTest.js b/test/tests/itemTreeTest.js index 44fd166c52..f8973780c7 100644 --- a/test/tests/itemTreeTest.js +++ b/test/tests/itemTreeTest.js @@ -1673,6 +1673,31 @@ describe("Zotero.ItemTree", function() { assert.equal(pdfAttachment2.parentItemID, parentItem.id); assert.equal(pdfAttachment2.getField('title'), 'test'); }); + + it("should select attachment after a file is dragged onto a top-level item", async function () { + let item = await createDataObject('item', { title: "Top-level Item" }); + // a file is dropped onto an existing item + let itemIndex = zp.itemsView.getRowIndexByID(item.id); + let file = getTestDataDirectory(); + file.append('test.pdf'); + + drop(itemIndex, 0, { + dropEffect: 'copy', + effectAllowed: 'copy', + types: ['application/x-moz-file'], + mozItemCount: 1, + mozGetDataAt: function (type, i) { + if (type == 'application/x-moz-file' && i == 0) { + return file; + } + } + }); + await waitForNotifierEvent('add', 'item'); + // the top-level item should be expanded + assert.isTrue(zp.itemsView.isContainerOpen(itemIndex)); + // the child attachment that was added should be selected + assert.equal(zp.itemsView.selection.focused, itemIndex + 1); + }); }); diff --git a/test/tests/zoteroPaneTest.js b/test/tests/zoteroPaneTest.js index 16e75783f0..a02ba11a20 100644 --- a/test/tests/zoteroPaneTest.js +++ b/test/tests/zoteroPaneTest.js @@ -1693,6 +1693,19 @@ describe("ZoteroPane", function() { assert.equal(epubAttachment.getField('title'), Zotero.getString('file-type-ebook')); }); + it("should select added file attachment", async function () { + let parentItem = await createDataObject('item'); + + let file = getTestDataDirectory(); + file.append('test.pdf'); + let [pdfAttachment1] = await zp.addAttachmentFromDialog(false, parentItem.id, [file.path]); + + let parentItemIndex = zp.itemsView.getRowIndexByID(parentItem.id); + assert.equal(zp.itemsView.selection.focused, parentItemIndex + 1); + let selected = zp.itemsView.getSelectedItems()[0]; + assert.equal(selected.id, pdfAttachment1.id); + }); + describe("Linked file renaming", function () { before(() => { Zotero.Prefs.set('autoRenameFiles.linked', true);