tor-browser

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

commit 18653126ab20f74f6445523e86cf9d6b0b813a67
parent f31037dc64adc9d507c0ebe2bbb6c8de82ffbde0
Author: Jonathan Sudiaman <jsudiaman@mozilla.com>
Date:   Thu,  6 Nov 2025 19:02:46 +0000

Bug 1996066 - Split View: Ensure that status panel shows up on the correct side. r=tabbrowser-reviewers,desktop-theme-reviewers,nsharpley

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

Diffstat:
Mbrowser/components/tabbrowser/content/tabbrowser.js | 8++++----
Mbrowser/components/tabbrowser/test/browser/statuspanel/browser.toml | 2++
Abrowser/components/tabbrowser/test/browser/statuspanel/browser_show_statuspanel_splitview.js | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mbrowser/themes/shared/tabbrowser/content-area.css | 5+++++
Mtoolkit/content/widgets/tabbox.js | 30++++++++++++++++++++++++------
5 files changed, 90 insertions(+), 10 deletions(-)

diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js @@ -628,7 +628,7 @@ this._tabForBrowser.set(browser, tab); - this._appendStatusPanel(); + this.appendStatusPanel(); // This is the initial browser, so it's usually active; the default is false // so we have to update it: @@ -851,8 +851,8 @@ return findBar; } - _appendStatusPanel() { - this.selectedBrowser.insertAdjacentElement("afterend", StatusPanel.panel); + appendStatusPanel(browser = this.selectedBrowser) { + browser.insertAdjacentElement("afterend", StatusPanel.panel); } _updateTabBarForPinnedTabs() { @@ -1401,7 +1401,7 @@ this._selectedTab = newTab; this.showTab(newTab); - this._appendStatusPanel(); + this.appendStatusPanel(); this._updateVisibleNotificationBox(newBrowser); diff --git a/browser/components/tabbrowser/test/browser/statuspanel/browser.toml b/browser/components/tabbrowser/test/browser/statuspanel/browser.toml @@ -3,4 +3,6 @@ support-files = ["head.js"] ["browser_show_statuspanel_idn.js"] +["browser_show_statuspanel_splitview.js"] + ["browser_show_statuspanel_twice.js"] diff --git a/browser/components/tabbrowser/test/browser/statuspanel/browser_show_statuspanel_splitview.js b/browser/components/tabbrowser/test/browser/statuspanel/browser_show_statuspanel_splitview.js @@ -0,0 +1,55 @@ +/* Any copyright is dedicated to the Public Domain. + https://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_URL = "https://example.com"; + +async function addTabAndLoadBrowser() { + const tab = BrowserTestUtils.addTab(gBrowser, TEST_URL); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser); + return tab; +} + +async function showStatusPanel() { + window.XULBrowserWindow.overLink = TEST_URL; + window.StatusPanel.update(); + return promiseStatusPanelShown(window, TEST_URL); +} + +async function hideStatusPanel() { + window.XULBrowserWindow.overLink = ""; + window.StatusPanel.update(); + return promiseStatusPanelHidden(window); +} + +add_task(async function test_show_statuspanel_in_split_view() { + const tab1 = await addTabAndLoadBrowser(); + const tab2 = await addTabAndLoadBrowser(); + await BrowserTestUtils.switchTab(gBrowser, tab1); + + info("Activate split view."); + const splitView = gBrowser.addTabSplitView([tab1, tab2]); + const panel1 = document.getElementById(tab1.linkedPanel); + const panel2 = document.getElementById(tab2.linkedPanel); + + info("Hover over the active panel."); + EventUtils.synthesizeMouseAtCenter(panel1, { type: "mousemove" }); + await showStatusPanel(); + Assert.ok( + panel1.contains(StatusPanel.panel), + "Hover link shown within the active panel." + ); + await hideStatusPanel(); + + info("Hover over the inactive panel."); + EventUtils.synthesizeMouseAtCenter(panel2, { type: "mousemove" }); + await showStatusPanel(); + Assert.ok( + panel2.contains(StatusPanel.panel), + "Hover link shown within the inactive panel." + ); + await hideStatusPanel(); + + splitView.close(); +}); diff --git a/browser/themes/shared/tabbrowser/content-area.css b/browser/themes/shared/tabbrowser/content-area.css @@ -293,6 +293,11 @@ split-view-footer, @media -moz-pref("browser.tabs.hideStatusPanel") { visibility: hidden; } + + /* Ensure that this appears on top of the split view footer. */ + .split-view-panel & { + z-index: 1; + } } #statuspanel-label, diff --git a/toolkit/content/widgets/tabbox.js b/toolkit/content/widgets/tabbox.js @@ -270,21 +270,35 @@ */ #splitViewSplitter = null; + static #SPLIT_VIEW_PANEL_EVENTS = Object.freeze([ + "click", + "focus", + "mouseover", + "mouseout", + ]); + constructor() { super(); this._tabbox = null; } handleEvent(e) { + const browser = e.currentTarget; + const tabbrowser = browser.getTabBrowser(); switch (e.type) { case "click": case "focus": { - const browser = e.currentTarget; - const tab = browser.getTabBrowser().getTabForBrowser(browser); + const tab = tabbrowser.getTabForBrowser(browser); const tabstrip = this.tabbox.tabs; tabstrip.selectedItem = tab; break; } + case "mouseover": + tabbrowser.appendStatusPanel(browser); + break; + case "mouseout": + tabbrowser.appendStatusPanel(); + break; } } @@ -362,8 +376,10 @@ const panelEl = document.getElementById(panel); panelEl?.classList.add("split-view-panel"); panelEl?.setAttribute("column", i); - panelEl?.querySelector("browser")?.addEventListener("click", this); - panelEl?.querySelector("browser")?.addEventListener("focus", this); + const browser = panelEl?.querySelector("browser"); + for (const eventType of MozTabpanels.#SPLIT_VIEW_PANEL_EVENTS) { + browser?.addEventListener(eventType, this); + } } this.#splitViewPanels = newPanels; this.#isSplitViewActive = !!newPanels.length; @@ -384,8 +400,10 @@ const panelEl = document.getElementById(panel); panelEl?.classList.remove("split-view-panel"); panelEl?.removeAttribute("column"); - panelEl?.querySelector("browser")?.removeEventListener("click", this); - panelEl?.querySelector("browser")?.removeEventListener("focus", this); + const browser = panelEl?.querySelector("browser"); + for (const eventType of MozTabpanels.#SPLIT_VIEW_PANEL_EVENTS) { + browser?.removeEventListener(eventType, this); + } if (updateArray) { const index = this.#splitViewPanels.indexOf(panel); if (index !== -1) {