diff --git a/chrome/content/zotero/components/tabBar.jsx b/chrome/content/zotero/components/tabBar.jsx index 9eb3bdef70..d7cabf1099 100644 --- a/chrome/content/zotero/components/tabBar.jsx +++ b/chrome/content/zotero/components/tabBar.jsx @@ -115,6 +115,13 @@ const TabBar = forwardRef(function (props, ref) { }; }, []); + useEffect(() => { + // Scroll selected tab into view + let selectedTabNode = tabsInnerContainerRef.current.querySelector(".tab.selected"); + if (!selectedTabNode || dragging) return; + selectedTabNode.scrollIntoView({ behavior: 'smooth' }); + }, [tabs]); + useLayoutEffect(updateScrollArrows); useLayoutEffect(updateOverflowing, [tabs]); @@ -414,6 +421,7 @@ TabBar.displayName = 'TabBar'; TabBar.propTypes = { onTabSelect: PropTypes.func.isRequired, onTabClose: PropTypes.func.isRequired, + onLoad: PropTypes.func.isRequired, onTabMove: PropTypes.func.isRequired, refocusReader: PropTypes.func.isRequired, onContextMenu: PropTypes.func.isRequired, diff --git a/chrome/content/zotero/tabs.js b/chrome/content/zotero/tabs.js index fc9c905a03..3c67762627 100644 --- a/chrome/content/zotero/tabs.js +++ b/chrome/content/zotero/tabs.js @@ -493,24 +493,6 @@ var Zotero_Tabs = new function () { tabNode.focus(); } } - // Allow React to create a tab node - setTimeout(() => { - tabNode.scrollIntoView({ behavior: 'smooth' }); - }); - // Border is not included when scrolling element node into view, therefore we do it manually. - // TODO: `scroll-padding` since Firefox 68 can probably be used instead - setTimeout(() => { - if (!tabNode) { - return; - } - let tabsContainerNode = document.querySelector('#tab-bar-container .tabs'); - if (tabNode.offsetLeft + tabNode.offsetWidth - tabsContainerNode.offsetWidth + 1 >= tabsContainerNode.scrollLeft) { - document.querySelector('#tab-bar-container .tabs').scrollLeft += 1; - } - else if (tabNode.offsetLeft - 1 <= tabsContainerNode.scrollLeft) { - document.querySelector('#tab-bar-container .tabs').scrollLeft -= 1; - } - }, 500); tab.timeSelected = Zotero.Date.getUnixTimestamp(); // Without `setTimeout` the tab closing that happens in `unloadUnusedTabs` results in // tabs deck selection index bigger than the deck children count. It feels like something @@ -633,14 +615,12 @@ var Zotero_Tabs = new function () { if (tabIndexToFocus !== null) { const nextTab = this._tabs[tabIndexToFocus]; // There may be duplicate tabs - in normal tab array and in pinned tabs - // So to get the right one, fetch all tabs with a given id and filter out one - // that's visible + // Go through all candidates and try to focus the visible one let candidates = document.querySelectorAll(`[data-id="${nextTab.id}"]`); for (let node of candidates) { - if (node.offsetParent) { - node.focus(); - return; - } + node.focus(); + // Visible tab was found and focused + if (document.activeElement == node) return; } } }; diff --git a/scss/components/_tabBar.scss b/scss/components/_tabBar.scss index 7bf38b2620..ac548a7b1f 100644 --- a/scss/components/_tabBar.scss +++ b/scss/components/_tabBar.scss @@ -147,6 +147,7 @@ padding: 4px 1px; column-gap: 4px; -moz-window-dragging: drag; + scroll-padding: 2px; // ensures a tab is scrolled into view without cutoff borders .pinned-tabs & { padding: 4px 0;