diff --git a/chrome/content/zotero/elements/attachmentRow.js b/chrome/content/zotero/elements/attachmentRow.js index 72fc1f705b..d5880ef01b 100644 --- a/chrome/content/zotero/elements/attachmentRow.js +++ b/chrome/content/zotero/elements/attachmentRow.js @@ -106,19 +106,18 @@ import { getCSSItemTypeIcon } from 'components/icons'; Zotero.Utilities.Internal.onDragItems(event, [this._attachment.id]); }; - _handleAnnotationClick = () => { - // TODO: jump to annotations pane - let pane; - if (ZoteroContextPane) { - pane = ZoteroContextPane.sidenav?.container.querySelector(`:scope > [data-pane="attachment-annotations"]`); - } - if (pane) { - pane._section.open = true; - } + _handleAnnotationClick = async () => { + let paneID = "attachment-annotations"; let win = Zotero.getMainWindow(); if (win) { - win.ZoteroPane.selectItem(this._attachment.id); 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(); } }; diff --git a/chrome/content/zotero/elements/itemDetails.js b/chrome/content/zotero/elements/itemDetails.js index 2c6ea9c1e5..ff2dc838dd 100644 --- a/chrome/content/zotero/elements/itemDetails.js +++ b/chrome/content/zotero/elements/itemDetails.js @@ -543,19 +543,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; } // If the pane is already at the top, no need to scroll