commit fc3c63758b5d8a951a89e7b00f8b7b22e839e467
parent 0b9ec9c4945a008a00f1892267f8bf64af5f66de
Author: iulian moraru <imoraru@mozilla.com>
Date: Wed, 29 Oct 2025 18:29:46 +0200
Revert "Bug 1986950 - Implement footer for inactive tab/content area r=tabbrowser-reviewers,desktop-theme-reviewers,sclements,dao" for causing bc failures on browser_ext_chrome_settings_overrides_home.js.
This reverts commit da8b29b1ad4ecf62939e62a8fce8ca61bcab5d74.
Diffstat:
7 files changed, 17 insertions(+), 398 deletions(-)
diff --git a/browser/base/content/browser-main.js b/browser/base/content/browser-main.js
@@ -21,7 +21,6 @@
Services.scriptloader.loadSubScript("chrome://browser/content/browser-unified-extensions.js", this);
Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser/drag-and-drop.js", this);
Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser/tab-stacking.js", this);
- Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser/split-view-footer.js", this);
Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser/tab.js", this);
Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser/tabbrowser.js", this);
Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser/tabgroup.js", this);
diff --git a/browser/components/tabbrowser/content/split-view-footer.js b/browser/components/tabbrowser/content/split-view-footer.js
@@ -1,212 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-// This is loaded into chrome windows with the subscript loader. Wrap in
-// a block to prevent accidentally leaking globals onto `window`.
-{
- ChromeUtils.defineESModuleGetters(this, {
- BrowserUtils: "resource://gre/modules/BrowserUtils.sys.mjs",
- });
-
- /**
- * A footer which appears in the corner of the inactive panel in split view.
- *
- * The footer displays the favicon and domain name of the site.
- */
- class MozSplitViewFooter extends MozXULElement {
- #initialized = false;
-
- #isInsecure = false;
- /** @type {HTMLSpanElement} */
- securityElement = null;
-
- /** @type {HTMLImageElement} */
- iconElement = null;
- #iconSrc = "";
-
- /** @type {HTMLSpanElement} */
- uriElement = null;
- /** @type {nsIURI} */
- #uri = null;
-
- #browserProgressListener = {
- QueryInterface: ChromeUtils.generateQI([
- Ci.nsIWebProgressListener,
- Ci.nsISupportsWeakReference,
- ]),
- onLocationChange: (aWebProgress, aRequest, aLocation) => {
- if (aWebProgress?.isTopLevel && aLocation) {
- this.#updateUri(aLocation);
- }
- },
- onSecurityChange: (aWebProgress, aRequest, aState) =>
- this.#toggleInsecure(
- !!(
- aState & Ci.nsIWebProgressListener.STATE_IS_INSECURE ||
- aState & Ci.nsIWebProgressListener.STATE_IS_BROKEN
- )
- ),
- };
-
- /** @type {XULElement} */
- #tab = null;
-
- static markup = `
- <hbox class="split-view-security-warning" hidden="">
- <html:img role="presentation" src="chrome://global/skin/icons/security-broken.svg" />
- <html:span data-l10n-id="urlbar-trust-icon-notsecure-label"></html:span>
- </hbox>
- <html:img class="split-view-icon" hidden="" role="presentation"/>
- <html:span class="split-view-uri"></html:span>
- `;
-
- connectedCallback() {
- if (this.#initialized) {
- return;
- }
- this.appendChild(this.constructor.fragment);
-
- this.securityElement = this.querySelector(".split-view-security-warning");
- this.iconElement = this.querySelector(".split-view-icon");
- this.uriElement = this.querySelector(".split-view-uri");
-
- // Ensure these elements are up-to-date, as this info may have been set
- // prior to inserting this element into the DOM.
- this.#updateSecurityElement();
- this.#updateIconElement();
- this.#updateUriElement();
-
- this.#initialized = true;
- }
-
- disconnectedCallback() {
- this.#resetTab();
- }
-
- handleEvent(e) {
- switch (e.type) {
- case "TabAttrModified":
- for (const attribute of e.detail.changed) {
- this.#handleTabAttrModified(attribute);
- }
- break;
- }
- }
-
- #handleTabAttrModified(attribute) {
- switch (attribute) {
- case "image":
- this.#updateIconSrc(this.#tab.image);
- break;
- }
- }
-
- /**
- * Update the insecure flag and refresh the security warning visibility.
- *
- * @param {boolean} isInsecure
- */
- #toggleInsecure(isInsecure) {
- this.#isInsecure = isInsecure;
- if (this.securityElement) {
- this.#updateSecurityElement();
- }
- }
-
- #updateSecurityElement() {
- const isWebsite =
- this.#uri.schemeIs("http") || this.#uri.schemeIs("https");
- this.securityElement.hidden = !isWebsite || !this.#isInsecure;
- }
-
- /**
- * Update the footer icon to the given source URI.
- *
- * @param {string} iconSrc
- */
- #updateIconSrc(iconSrc) {
- this.#iconSrc = iconSrc;
- if (this.iconElement) {
- this.#updateIconElement();
- }
- }
-
- #updateIconElement() {
- if (this.#iconSrc) {
- this.iconElement.setAttribute("src", this.#iconSrc);
- } else {
- this.iconElement.removeAttribute("src");
- }
- this.iconElement.hidden = !this.#iconSrc;
- }
-
- /**
- * Update the footer URI display with the formatted domain string.
- *
- * @param {nsIURI} uri
- */
- #updateUri(uri) {
- this.#uri = uri;
- if (this.uriElement) {
- this.#updateUriElement();
- }
- if (this.securityElement) {
- this.#updateSecurityElement();
- }
- }
-
- #updateUriElement() {
- const uriString = this.#uri
- ? BrowserUtils.formatURIForDisplay(this.#uri)
- : "";
- this.uriElement.textContent = uriString;
- }
-
- /**
- * Link the footer to the provided tab so it stays in sync.
- *
- * @param {MozTabbrowserTab} tab
- */
- setTab(tab) {
- this.#resetTab();
-
- // Track favicon changes.
- this.#updateIconSrc(tab.image);
- tab.addEventListener("TabAttrModified", this);
-
- // Track URI and security changes.
- this.#updateUri(tab.linkedBrowser.currentURI);
- const securityState = tab.linkedBrowser.securityUI.state;
- this.#toggleInsecure(
- !!(
- securityState & Ci.nsIWebProgressListener.STATE_IS_INSECURE ||
- securityState & Ci.nsIWebProgressListener.STATE_IS_BROKEN
- )
- );
- tab.linkedBrowser.addProgressListener(
- this.#browserProgressListener,
- Ci.nsIWebProgress.NOTIFY_LOCATION | Ci.nsIWebProgress.NOTIFY_SECURITY
- );
-
- this.#tab = tab;
- }
-
- /**
- * Remove the footer's association with the current tab.
- */
- #resetTab() {
- if (this.#tab) {
- this.#tab.removeEventListener("TabAttrModified", this);
- this.#tab.linkedBrowser?.removeProgressListener(
- this.#browserProgressListener
- );
- }
- this.#tab = null;
- }
- }
-
- customElements.define("split-view-footer", MozSplitViewFooter);
-}
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
@@ -3255,7 +3255,6 @@
const panels = [];
for (const tab of tabs) {
this._insertBrowser(tab);
- this.#insertSplitViewFooter(tab);
tab.linkedBrowser.docShellIsActive = true;
panels.push(tab.linkedPanel);
}
@@ -3274,21 +3273,6 @@
}
/**
- * Ensures the split view footer exists for the given tab.
- *
- * @param {MozTabbrowserTab} tab
- */
- #insertSplitViewFooter(tab) {
- const panelEl = document.getElementById(tab.linkedPanel);
- if (panelEl.querySelector("split-view-footer")) {
- return;
- }
- const footer = document.createXULElement("split-view-footer");
- footer.setTab(tab);
- panelEl.appendChild(footer);
- }
-
- /**
* @param {string} id
* @param {string} color
* @param {boolean} collapsed
@@ -8602,6 +8586,10 @@
modifiedAttrs.push("progress");
}
+ if (modifiedAttrs.length) {
+ gBrowser._tabAttrModified(this.mTab, modifiedAttrs);
+ }
+
if (aWebProgress.isTopLevel) {
let isSuccessful = Components.isSuccessCode(aStatus);
if (!isSuccessful && !this.mTab.isEmpty) {
@@ -8646,7 +8634,6 @@
!(originalLocation.spec in FAVICON_DEFAULTS)
) {
this.mTab.removeAttribute("image");
- modifiedAttrs.push("image");
} else {
// Bug 1804166: Allow new tabs to set the favicon correctly if the
// new tabs behavior is set to open a blank page
@@ -8663,10 +8650,6 @@
if (this.mTab.selected) {
gBrowser._isBusy = false;
}
-
- if (modifiedAttrs.length) {
- gBrowser._tabAttrModified(this.mTab, modifiedAttrs);
- }
}
if (ignoreBlank) {
diff --git a/browser/components/tabbrowser/jar.mn b/browser/components/tabbrowser/jar.mn
@@ -8,7 +8,6 @@ browser.jar:
content/browser/tabbrowser/browser-fullZoom.js (content/browser-fullZoom.js)
content/browser/tabbrowser/drag-and-drop.js (content/drag-and-drop.js)
content/browser/tabbrowser/tab-stacking.js (content/tab-stacking.js)
- content/browser/tabbrowser/split-view-footer.js (content/split-view-footer.js)
content/browser/tabbrowser/tab.js (content/tab.js)
content/browser/tabbrowser/tab-hover-preview.mjs (content/tab-hover-preview.mjs)
content/browser/tabbrowser/tabbrowser.js (content/tabbrowser.js)
diff --git a/browser/components/tabbrowser/test/browser/tabs/browser_tab_splitview.js b/browser/components/tabbrowser/test/browser/tabs/browser_tab_splitview.js
@@ -4,18 +4,17 @@
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
- set: [
- ["sidebar.verticalTabs", true],
- ["dom.security.https_first", false],
- ],
+ set: [["sidebar.verticalTabs", true]],
});
});
registerCleanupFunction(async function () {
- Services.prefs.clearUserPref("sidebar.revamp");
- Services.prefs.clearUserPref(
- "browser.toolbarbuttons.introduced.sidebar-button"
- );
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["sidebar.verticalTabs", false],
+ ["sidebar.revamp", false],
+ ],
+ });
});
async function addTabAndLoadBrowser() {
@@ -240,100 +239,3 @@ add_task(async function test_resize_split_view_panels() {
splitView.close();
});
-
-add_task(async function test_split_view_panel_footers() {
- const tab1 = await addTabAndLoadBrowser();
- const tab2 = await addTabAndLoadBrowser();
- await BrowserTestUtils.switchTab(gBrowser, tab1);
-
- info("Activate split view.");
- const splitView = gBrowser.addTabSplitView([tab1, tab2]);
- await checkSplitViewPanelVisible(tab1, true);
- await checkSplitViewPanelVisible(tab2, true);
-
- const panel1 = document.getElementById(tab1.linkedPanel);
- const panel2 = document.getElementById(tab2.linkedPanel);
- const panel1Footer = panel1.querySelector("split-view-footer");
- const panel2Footer = panel2.querySelector("split-view-footer");
-
- info("Focus the first panel.");
- await SimpleTest.promiseFocus(tab1.linkedBrowser);
- Assert.ok(
- BrowserTestUtils.isHidden(panel1Footer),
- "First (active) panel does not contain a footer."
- );
- Assert.ok(
- BrowserTestUtils.isVisible(panel2Footer),
- "Second (inactive) panel contains a footer."
- );
- Assert.equal(
- panel2Footer.uriElement.textContent,
- "example.com",
- "Footer displays the domain name of the site."
- );
-
- info("Focus the second panel.");
- await SimpleTest.promiseFocus(tab2.linkedBrowser);
- Assert.ok(
- BrowserTestUtils.isVisible(panel1Footer),
- "First panel now contains a footer."
- );
- Assert.ok(
- BrowserTestUtils.isHidden(panel2Footer),
- "Second panel no longer contains a footer."
- );
-
- info("Navigate to a different location.");
- const promiseLoaded = BrowserTestUtils.browserLoaded(tab1.linkedBrowser);
- BrowserTestUtils.startLoadingURIString(tab1.linkedBrowser, "about:robots");
- await promiseLoaded;
- Assert.equal(
- panel1Footer.uriElement.textContent,
- "about:robots",
- "Footer displays the new location."
- );
-
- splitView.close();
-});
-
-add_task(async function test_split_view_security_warning() {
- const tab1 = await addTabAndLoadBrowser();
- const tab2 = await addTabAndLoadBrowser();
- await BrowserTestUtils.switchTab(gBrowser, tab1);
-
- info("Activate split view.");
- const splitView = gBrowser.addTabSplitView([tab1, tab2]);
- await checkSplitViewPanelVisible(tab1, true);
- await checkSplitViewPanelVisible(tab2, true);
- await SimpleTest.promiseFocus(tab1.linkedBrowser);
-
- const inactivePanel = document.getElementById(tab2.linkedPanel);
- const footer = inactivePanel.querySelector("split-view-footer");
- Assert.ok(
- BrowserTestUtils.isHidden(footer.securityElement),
- "No security warning for HTTPS."
- );
-
- info("Load an insecure website.");
- let promiseLoaded = BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
- BrowserTestUtils.startLoadingURIString(
- tab2.linkedBrowser,
- "http://example.com/" // eslint-disable-line @microsoft/sdl/no-insecure-url
- );
- await promiseLoaded;
- Assert.ok(
- BrowserTestUtils.isVisible(footer.securityElement),
- "Security warning for HTTP."
- );
-
- info("Load a local site.");
- promiseLoaded = BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
- BrowserTestUtils.startLoadingURIString(tab2.linkedBrowser, "about:robots");
- await promiseLoaded;
- Assert.ok(
- BrowserTestUtils.isHidden(footer.securityElement),
- "No security warning for local sites."
- );
-
- splitView.close();
-});
diff --git a/browser/themes/shared/tabbrowser/content-area.css b/browser/themes/shared/tabbrowser/content-area.css
@@ -155,7 +155,7 @@
--panel-min-width: 140px;
.split-view-panel {
- position: relative;
+ position: static;
flex: 1;
min-width: var(--panel-min-width);
max-width: calc(100% - var(--panel-min-width));
@@ -165,7 +165,6 @@
.browserStack {
border-radius: var(--border-radius-medium);
overflow: clip;
- outline: var(--border-width) solid var(--border-color);
.deck-selected > .browserContainer > & {
outline: var(--focus-outline);
@@ -191,51 +190,9 @@
.split-view-panel[width] {
flex: none;
}
-
- /* Display split view footer within inactive panels. */
- .split-view-panel:not(.deck-selected) > split-view-footer {
- display: inherit;
- }
}
}
-/* Split view */
-
-split-view-footer {
- max-width: calc(100% - var(--space-xsmall));
- display: none;
- position: absolute;
- inset-block-end: 0;
- inset-inline-end: 0;
-
- border-block-start: 1px solid var(--border-color);
- border-inline-start: 1px solid var(--border-color);
- border-start-start-radius: var(--border-radius-medium);
- border-start-end-radius: 0;
- border-end-end-radius: var(--border-radius-medium);
- border-end-start-radius: 0;
-
- padding-block: var(--space-xxsmall);
- padding-inline: var(--space-small) var(--space-xsmall);
-}
-
-.split-view-icon {
- width: var(--icon-size);
- height: var(--icon-size);
-}
-
-.split-view-uri {
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-split-view-footer,
-.split-view-security-warning {
- align-items: center;
- gap: var(--space-small);
- white-space: nowrap;
-}
-
/* Status panel */
#statuspanel {
@@ -295,11 +252,13 @@ split-view-footer,
}
}
-#statuspanel-label,
-split-view-footer {
+#statuspanel-label {
color-scheme: env(-moz-content-preferred-color-scheme);
+ margin: 0;
+ padding: 2px 4px;
background-color: -moz-dialog;
- border-color: ThreeDShadow;
+ border: 1px none ThreeDShadow;
+ border-top-style: solid;
color: -moz-dialogText;
text-shadow: none;
@@ -308,14 +267,6 @@ split-view-footer {
border-color: light-dark(#ddd, hsl(240, 1%, 40%));
color: light-dark(#444, rgb(249, 249, 250));
}
-}
-
-#statuspanel-label {
- margin: 0;
- padding: 2px 4px;
- border-width: 1px;
- border-style: none;
- border-top-style: solid;
#statuspanel:not([mirror]) > &:-moz-locale-dir(ltr),
#statuspanel[mirror] > &:-moz-locale-dir(rtl) {
diff --git a/toolkit/content/widgets/tabbox.js b/toolkit/content/widgets/tabbox.js
@@ -277,7 +277,6 @@
handleEvent(e) {
switch (e.type) {
- case "click":
case "focus": {
const browser = e.currentTarget;
const tab = browser.getTabBrowser().getTabForBrowser(browser);
@@ -362,7 +361,6 @@
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);
}
this.#splitViewPanels = newPanels;
@@ -384,7 +382,6 @@
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);
if (updateArray) {
const index = this.#splitViewPanels.indexOf(panel);