diff --git a/chrome/content/zotero/collectionViewItemTree.jsx b/chrome/content/zotero/collectionViewItemTree.jsx index 442ead0493..b35b8d6a0f 100644 --- a/chrome/content/zotero/collectionViewItemTree.jsx +++ b/chrome/content/zotero/collectionViewItemTree.jsx @@ -721,7 +721,7 @@ class CollectionViewItemTreeRowProvider extends ItemTreeRowProvider { if (!item) continue; let topLevelItem = item.topLevelItem; let isAnythingDeleted = topLevelItem.deleted - || topLevelItem.getAllDescendents(true).length > topLevelItem.getAllDescendents(false).length; + || topLevelItem.getDescendantItems({ includeTrashed: true }).length > topLevelItem.getDescendantItems().length; // Remove the top-level item's row if neither it nor any of its // descendents remain trashed if (!isAnythingDeleted) { diff --git a/chrome/content/zotero/integration/citationDialog/searchHandler.mjs b/chrome/content/zotero/integration/citationDialog/searchHandler.mjs index ecadead5b8..6d781ec201 100644 --- a/chrome/content/zotero/integration/citationDialog/searchHandler.mjs +++ b/chrome/content/zotero/integration/citationDialog/searchHandler.mjs @@ -260,12 +260,7 @@ export class CitationDialogSearchHandler { isItemWithAnnotations(item) { if (item.isAnnotation()) return true; - if (item.isFileAttachment() && item.getAnnotations().length) return true; - if (item.isRegularItem()) { - let attachments = Zotero.Items.get(item.getAttachments()); - return attachments.some(att => att.isFileAttachment() && att.getAnnotations().length); - } - return false; + return item.getDescendantItems().some(descendent => descendent.isAnnotation()); } isItemWithNotes(item) { @@ -279,10 +274,7 @@ export class CitationDialogSearchHandler { getAllAnnotations(item) { if (item.isAnnotation()) return [item]; - if (item.isFileAttachment()) return item.getAnnotations(); - let attachmentIDs = item.getAttachments(); - let attachments = Zotero.Items.get(attachmentIDs).filter(item => item.isFileAttachment()); - let annotations = attachments.flatMap(attachment => attachment.getAnnotations()); + let annotations = item.getDescendantItems().filter(descendent => descendent.isAnnotation()); annotations.sort((a, b) => { if (a.parentItemID !== b.parentItemID) return 0; return (a.annotationSortIndex > b.annotationSortIndex) - (a.annotationSortIndex < b.annotationSortIndex); diff --git a/chrome/content/zotero/xpcom/data/dataObjectUtilities.js b/chrome/content/zotero/xpcom/data/dataObjectUtilities.js index 22568b7803..db2a1fb259 100644 --- a/chrome/content/zotero/xpcom/data/dataObjectUtilities.js +++ b/chrome/content/zotero/xpcom/data/dataObjectUtilities.js @@ -741,6 +741,7 @@ Zotero.DataObjectUtilities = { isRegularItem: () => false, // Should be false to prevent items dropped into deleted searches getNotes: () => [], getAttachments: () => [], + getDescendantItems: () => [], isFileAttachment: () => false, isTopLevelItem: () => false, getField: function (field, _) { diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js index 97c1ccd230..88146282a9 100644 --- a/chrome/content/zotero/xpcom/data/item.js +++ b/chrome/content/zotero/xpcom/data/item.js @@ -2460,28 +2460,30 @@ Zotero.Item.prototype.numChildren = function (includeTrashed) { /** - * Get all descendents of an item -- child notes and attachments of a regular item, - * annotations of its file attachments, and annotations of a standalone file attachment + * Get descendant items -- child notes and attachments of a regular item, plus + * annotations of its file attachments; annotations of a standalone file attachment * - * @param {Boolean} includeTrashed Include trashed items - * @return {Zotero.Item[]} + * @param {Object} [options] + * @param {Boolean} [options.includeTrashed=false] Include trashed items + * @param {Boolean} [options.includeAnnotations=true] Include annotations of file attachments + * @return {Zotero.Item[]} */ -Zotero.Item.prototype.getAllDescendents = function (includeTrashed) { - let attachments = []; - let notes = []; - let annotations = []; +Zotero.Item.prototype.getDescendantItems = function ({ includeTrashed = false, includeAnnotations = true } = {}) { + let descendents = []; if (this.isRegularItem()) { - attachments = Zotero.Items.get(this.getAttachments(includeTrashed)); - notes = Zotero.Items.get(this.getNotes(includeTrashed)); - for (let attachment of attachments) { - if (!attachment.isFileAttachment()) continue; - annotations.push(...attachment.getAnnotations(includeTrashed)); + let attachments = Zotero.Items.get(this.getAttachments(includeTrashed)); + descendents.push(...attachments, ...Zotero.Items.get(this.getNotes(includeTrashed))); + if (includeAnnotations) { + for (let attachment of attachments) { + if (!attachment.isFileAttachment()) continue; + descendents.push(...attachment.getAnnotations(includeTrashed)); + } } } - else if (this.isFileAttachment()) { - annotations = this.getAnnotations(includeTrashed); + else if (includeAnnotations && this.isFileAttachment()) { + descendents.push(...this.getAnnotations(includeTrashed)); } - return [...attachments, ...notes, ...annotations]; + return descendents; }; diff --git a/chrome/content/zotero/xpcom/data/items.js b/chrome/content/zotero/xpcom/data/items.js index dd35b89a53..72a0024d29 100644 --- a/chrome/content/zotero/xpcom/data/items.js +++ b/chrome/content/zotero/xpcom/data/items.js @@ -1336,7 +1336,7 @@ Zotero.Items = function () { // Remove all child items too if (item.isRegularItem()) { - allItems.push(...this.get(item.getNotes(true).concat(item.getAttachments(true)))); + allItems.push(...item.getDescendantItems({ includeTrashed: true, includeAnnotations: false })); } allItems.push(item); diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js index 6a26ab02b5..42620724ff 100644 --- a/chrome/content/zotero/zoteroPane.js +++ b/chrome/content/zotero/zoteroPane.js @@ -2859,7 +2859,7 @@ var ZoteroPane = new function () { } let parent = this.itemsView.getRow(row).ref; - let childIDs = []; + let childItems = []; let subcollections = []; if (parent instanceof Zotero.Collection) { // If the restored item is a collection, restore its subcollections too @@ -2868,26 +2868,8 @@ var ZoteroPane = new function () { } } else { - if (!parent.isNote()) { - childIDs.push(...parent.getNotes(true)); - } - // Include annotations of the item's file attachments, or of the item - // itself for a standalone file attachment - let fileAttachments = []; - if (parent.isRegularItem()) { - let attachmentIDs = parent.getAttachments(true); - childIDs.push(...attachmentIDs); - fileAttachments = Zotero.Items.get(attachmentIDs) - .filter(attachment => attachment.isFileAttachment()); - } - else if (parent.isFileAttachment()) { - fileAttachments = [parent]; - } - for (let attachment of fileAttachments) { - childIDs.push(...attachment.getAnnotations(true).map(a => a.id)); - } + childItems = parent.getDescendantItems({ includeTrashed: true }); } - let childItems = Zotero.Items.get(childIDs); if (isSelected(parent)) { if (parent.deleted) { parent.deleted = false;