tor-browser

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

commit e957f391a8f3a623fc3916f4da7974f8578c0632
parent 711947df5d30fd63d1029b1828b2ad4a2854f1d6
Author: Kelly Cochrane <kcochrane@mozilla.com>
Date:   Tue,  4 Nov 2025 15:29:44 +0000

Bug 1996103 - Fix issues with collapsing a tab group that contains a split view r=tabbrowser-reviewers,nsharpley,sthompson

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

Diffstat:
Mbrowser/components/tabbrowser/content/tabgroup.js | 75+++++++++++++++++++++++++++++++++++++++++++++------------------------------
Mbrowser/themes/shared/tabbrowser/tabs.css | 29++++++++++++++++++-----------
2 files changed, 63 insertions(+), 41 deletions(-)

diff --git a/browser/components/tabbrowser/content/tabgroup.js b/browser/components/tabbrowser/content/tabgroup.js @@ -191,13 +191,21 @@ } for (const mutation of mutations) { for (const addedNode of mutation.addedNodes) { - if (addedNode.tagName == "tab") { + if (gBrowser.isTab(addedNode)) { this.#updateTabAriaHidden(addedNode); + } else if (gBrowser.isSplitViewWrapper(addedNode)) { + for (const splitViewTab of addedNode.tabs) { + this.#updateTabAriaHidden(splitViewTab); + } } } for (const removedNode of mutation.removedNodes) { - if (removedNode.tagName == "tab") { + if (gBrowser.isTab(removedNode)) { this.#updateTabAriaHidden(removedNode); + } else if (gBrowser.isSplitViewWrapper(removedNode)) { + for (const splitViewTab of removedNode.tabs) { + this.#updateTabAriaHidden(splitViewTab); + } } } } @@ -309,6 +317,7 @@ this.toggleAttribute("collapsed", val); this.#updateLabelAriaAttributes(); this.#updateTooltip(); + this.#updateOverflowLabel(); for (const tab of this.tabs) { this.#updateTabAriaHidden(tab); } @@ -390,7 +399,16 @@ * @param {MozTabbrowserTab} tab */ #updateTabAriaHidden(tab) { - if (tab.group?.collapsed && !tab.selected) { + if (tab.splitview) { + if ( + tab.group?.collapsed && + !tab.splitview.tabs.some(splitViewTab => splitViewTab.selected) + ) { + tab.splitview.setAttribute("aria-hidden", "true"); + } else { + tab.splitview.removeAttribute("aria-hidden"); + } + } else if (tab.group?.collapsed && !tab.selected) { tab.setAttribute("aria-hidden", "true"); } else { tab.removeAttribute("aria-hidden"); @@ -401,34 +419,31 @@ // When a group containing the active tab is collapsed, // the overflow count displays the number of additional tabs // in the group adjacent to the active tab. - let overflowCountLabel = this.overflowContainer.querySelector( - ".tab-group-overflow-count" - ); - let tabs = this.tabs; - let tabCount = tabs.length; - const overflowOffset = - this.hasActiveTab && gBrowser.selectedTab.splitview ? 2 : 1; - - if (tabCount > 1) { - this.toggleAttribute("hasmultipletabs", true); - } else { - overflowCountLabel.textContent = ""; - this.toggleAttribute("hasmultipletabs", false); + if (this.overflowContainer) { + let overflowCountLabel = this.overflowContainer.querySelector( + ".tab-group-overflow-count" + ); + let tabs = this.tabs; + let tabCount = tabs.length; + const overflowOffset = + this.hasActiveTab && gBrowser.selectedTab.splitview ? 2 : 1; + + this.toggleAttribute("hasmultipletabs", tabCount > overflowOffset); + + gBrowser.tabLocalization + .formatValue("tab-group-overflow-count", { + tabCount: tabCount - overflowOffset, + }) + .then(result => (overflowCountLabel.textContent = result)); + gBrowser.tabLocalization + .formatValue("tab-group-overflow-count-tooltip", { + tabCount: tabCount - overflowOffset, + }) + .then(result => { + overflowCountLabel.setAttribute("tooltiptext", result); + overflowCountLabel.setAttribute("aria-description", result); + }); } - - gBrowser.tabLocalization - .formatValue("tab-group-overflow-count", { - tabCount: tabCount - overflowOffset, - }) - .then(result => (overflowCountLabel.textContent = result)); - gBrowser.tabLocalization - .formatValue("tab-group-overflow-count-tooltip", { - tabCount: tabCount - overflowOffset, - }) - .then(result => { - overflowCountLabel.setAttribute("tooltiptext", result); - overflowCountLabel.setAttribute("aria-description", result); - }); } #updateLastTabOrSplitViewAttr() { diff --git a/browser/themes/shared/tabbrowser/tabs.css b/browser/themes/shared/tabbrowser/tabs.css @@ -131,6 +131,7 @@ min-height: var(--tabstrip-min-height); --tab-min-width: 76px; + --tab-max-width: 225px; :root[uidensity="touch"] & .tabbrowser-tab[fadein]:not([pinned]) { /* Touch mode needs additional space for the close button. */ min-width: max(var(--tab-min-width-pref, var(--tab-min-width)), 86px); @@ -141,6 +142,8 @@ padding-bottom: 15px; margin-bottom: -15px; } + + --tab-width-transition: min-width 100ms ease-out, max-width 100ms ease-out; } &[noshadowfortests] { @@ -204,10 +207,8 @@ &:not([pinned]) { flex: 100 100; - max-width: 225px; - transition: - min-width 100ms ease-out, - max-width 100ms ease-out; + max-width: var(--tab-max-width); + transition: var(--tab-width-transition); #tabbrowser-tabs[orient="horizontal"] &[fadein] { min-width: var(--tab-min-width-pref, var(--tab-min-width)); @@ -1157,9 +1158,6 @@ /* Split View */ tab-group > tab-split-view-wrapper { - &[aria-hidden="true"] { - display: none; - } #tabbrowser-tabs[orient="vertical"] & { margin-inline-end: var(--space-medium); @@ -1187,10 +1185,6 @@ tab-group > tab-split-view-wrapper { .tab-group-line { inset-inline-start: calc(var(--space-medium) * -1) !important; inset-block: calc(var(--space-xsmall) * -1); - - @container vertical-tabs-container (max-width: 210px) { - inset-inline-start: calc(var(--space-large) * -1) !important; - } } &:last-child { @@ -1210,12 +1204,25 @@ tab-group > tab-split-view-wrapper { margin-block: var(--tab-block-margin); margin-inline: 0; align-items: flex-end; + flex: 100 100; padding: 2px 0; + min-width: calc(var(--tab-min-width-pref, var(--tab-min-width)) * 2 + 6px); + max-width: var(--tab-max-width); + transition: var(--tab-width-transition); &[last-tab-or-split-view] .tabbrowser-tab:last-child .tab-group-line { inset-inline-end: calc(var(--tab-border-radius) / 2); } + tab-group[collapsed] &:not([hasactivetab]) { + min-width: 0 !important; + max-width: 0 !important; + max-height: 0 !important; + padding: 0; + margin: 0; + overflow: hidden; + } + .tabbrowser-tab { padding-inline: 2px; .tab-background {