tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 7bfb0e0a3a9794ba601e16630eac7d42c3521a18
parent 692649f52101262f67a2f1a36399cc6d4639158e
Author: DJ <dj@walker.dev>
Date:   Fri, 24 Oct 2025 14:13:41 +0000

Bug 1987784 - Prevent tabstrip from changing scroll position when expanding a tab group. r=sthompson,tabbrowser-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D264327

Diffstat:
Mbrowser/components/tabbrowser/content/tabs.js | 17++++++++++++++---
Mbrowser/components/tabbrowser/test/browser/tabs/browser_tab_groups.js | 48++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/browser/components/tabbrowser/content/tabs.js b/browser/components/tabbrowser/content/tabs.js @@ -19,6 +19,7 @@ #mustUpdateTabMinHeight = false; #tabMinHeight = 36; + #animatingGroups = new Set(); constructor() { super(); @@ -34,6 +35,7 @@ this.addEventListener("TabGroupLabelHoverEnd", this); this.addEventListener("TabGroupExpand", this); this.addEventListener("TabGroupCollapse", this); + this.addEventListener("TabGroupAnimationComplete", this); this.addEventListener("TabGroupCreate", this); this.addEventListener("TabGroupRemoved", this); this.addEventListener("transitionend", this); @@ -371,13 +373,19 @@ this.previewPanel?.deactivate(event.target.group); } - on_TabGroupExpand() { + on_TabGroupExpand(event) { this._invalidateCachedVisibleTabs(); + this.#animatingGroups.add(event.target.id); } - on_TabGroupCollapse() { + on_TabGroupCollapse(event) { this._invalidateCachedVisibleTabs(); this._unlockTabSizing(); + this.#animatingGroups.add(event.target.id); + } + + on_TabGroupAnimationComplete(event) { + this.#animatingGroups.delete(event.target.id); } on_TabGroupCreate() { @@ -737,7 +745,10 @@ this.toggleAttribute("overflow", true); this._updateCloseButtons(); - this._handleTabSelect(true); + + if (!this.#animatingGroups.size) { + this._handleTabSelect(true); + } document .getElementById("tab-preview-panel") diff --git a/browser/components/tabbrowser/test/browser/tabs/browser_tab_groups.js b/browser/components/tabbrowser/test/browser/tabs/browser_tab_groups.js @@ -239,6 +239,54 @@ add_task(async function test_tabGroupCollapseWhileSelected() { await removeTabGroup(group); }); +add_task(async function test_tabGroupPreventScrollOnUncollapse() { + let win = await BrowserTestUtils.openNewBrowserWindow(); + + // create a tab group that overflows the tabstrip + await BrowserTestUtils.overflowTabs(null, win); + let bigGroup = win.gBrowser.addTabGroup(win.gBrowser.tabs); + + // create some more tabs after the group + createManyTabs(4, win); + + await BrowserTestUtils.waitForCondition(() => { + return Array.from(win.gBrowser.tabs).every(tab => tab._fullyOpen); + }); + + info("selecting the last tab"); + let tabSelected = BrowserTestUtils.waitForEvent(win, "TabSelect"); + win.gBrowser.selectedTab = win.gBrowser.tabs[win.gBrowser.tabs.length - 1]; + await tabSelected; + + info("scrolling to beginning of tabstrip"); + let arrowScrollbox = win.gBrowser.tabContainer.arrowScrollbox; + let scrolledToStart = BrowserTestUtils.waitForCondition(() => + arrowScrollbox.hasAttribute("scrolledtostart") + ); + + bigGroup.labelElement.scrollIntoView(true); + await scrolledToStart; + Assert.ok(!bigGroup.collapsed, "Group is expanded"); + Assert.ok( + arrowScrollbox.hasAttribute("scrolledtostart"), + "arrowscrollbox is scrolled to start" + ); + + info("Collapsing and expanding the big group"); + await TabGroupTestUtils.toggleCollapsed(bigGroup, true); + Assert.ok(bigGroup.collapsed, "Group is collapsed"); + await TabGroupTestUtils.toggleCollapsed(bigGroup, false); + Assert.ok(!bigGroup.collapsed, "Group is expanded"); + + Assert.ok( + arrowScrollbox.hasAttribute("scrolledtostart"), + "arrowscrollbox is still scrolled to start" + ); + + await TabGroupTestUtils.removeTabGroup(bigGroup); + BrowserTestUtils.closeWindow(win); +}); + /** * Bug 1979067 - The collapsed tab group's overflow counter should be included in the bounds * calculations that determine whether the tabstrip scroll button is enabled.