diff --git a/chrome/content/zotero/elements/attachmentRow.js b/chrome/content/zotero/elements/attachmentRow.js index 8f128f208e..d5880ef01b 100644 --- a/chrome/content/zotero/elements/attachmentRow.js +++ b/chrome/content/zotero/elements/attachmentRow.js @@ -106,9 +106,20 @@ import { getCSSItemTypeIcon } from 'components/icons'; Zotero.Utilities.Internal.onDragItems(event, [this._attachment.id]); }; - _handleAnnotationClick = () => { - Zotero_Tabs.select('zotero-pane'); - ZoteroPane.selectItems(this._attachment.getAnnotations().map(a => a.id)); + _handleAnnotationClick = async () => { + let paneID = "attachment-annotations"; + let win = Zotero.getMainWindow(); + if (win) { + win.Zotero_Tabs.select('zotero-pane'); + let itemDetails = win.ZoteroContextPane.sidenav?.container; + let pane = itemDetails?.getPane(paneID); + if (pane) { + pane._section.open = true; + await itemDetails?.scrollToPane(paneID, 'instant', { pendingScroll: true }); + } + await win.ZoteroPane.selectItem(this._attachment.id); + win.focus(); + } }; _handleRemove = async () => { diff --git a/chrome/content/zotero/elements/itemDetails.js b/chrome/content/zotero/elements/itemDetails.js index 71b7365a03..17bf62e1a2 100644 --- a/chrome/content/zotero/elements/itemDetails.js +++ b/chrome/content/zotero/elements/itemDetails.js @@ -541,19 +541,35 @@ } } - async scrollToPane(paneID, behavior = 'smooth') { - let panes = this.getEnabledPanes(); + /** + * Scroll to a specific pane section. + * @param {string} paneID - ID of the section to scroll to + * @param {'smooth' | 'instant'} behavior - 'smooth' for smooth scrolling, 'instant' for instant scroll + * @param {object} [options] + * @param {boolean} [options.pendingScroll = false] - If true, the pane will be scrolled to when `render` is called. + * @returns {Promise} - Returns true if the pane was/will be scrolled to, false otherwise. + */ + async scrollToPane(paneID, behavior = 'smooth', options = {}) { + let { pendingScroll = false } = options; + let panes; + // For pending scroll, hidden sections are also considered + if (pendingScroll) { + panes = this.getPanes(); + } + else { + panes = this.getEnabledPanes(); + } let paneIndex = panes.findIndex(elem => elem.dataset.pane == paneID); let pane = panes[paneIndex]; - if (!pane) return null; + if (!pane) return false; let scrollPromise; // If the itemPane is collapsed, just remember which pane needs to be scrolled to // when itemPane is expanded. - if (this._collapsed) { + if (this._collapsed || pendingScroll) { this._lastScrollPaneID = paneID; - return null; + return true; } // Temporarily disable intersection observer to prevent unwanted rendering