no-bug: Finish patches

This commit is contained in:
mr. m
2026-06-14 22:54:32 +02:00
parent 690fff1ca0
commit 461b2a813f
69 changed files with 476 additions and 1759 deletions

View File

@@ -1 +1 @@
1.90
1.95

View File

@@ -1,12 +1,12 @@
diff --git a/browser/actors/WebRTCParent.sys.mjs b/browser/actors/WebRTCParent.sys.mjs
index b743bd83529c4cd01a6bc820967186dbe41b6144..e24c48bac0f4ae3d4b26087b7e0cac7910019d0e 100644
index 98b10b1d789c20b3463de4f703af102f6908318b..29534480fbeda6d66cb9dab81afdaed8d8a5c565 100644
--- a/browser/actors/WebRTCParent.sys.mjs
+++ b/browser/actors/WebRTCParent.sys.mjs
@@ -152,6 +152,7 @@ export class WebRTCParent extends JSWindowActorParent {
let tabbrowser = browser.ownerGlobal.gBrowser;
let tabbrowser = browser.documentGlobal.gBrowser;
if (tabbrowser) {
+ browser.ownerGlobal.gZenMediaController.updateMediaSharing(state);
+ browser.documentGlobal.gZenMediaController.updateMediaSharing(state);
tabbrowser.updateBrowserSharing(browser, {
webRTC: state,
});

View File

@@ -1,5 +1,5 @@
diff --git a/browser/base/content/browser-box.inc.xhtml b/browser/base/content/browser-box.inc.xhtml
index d58fcdf99843d110b708f3fbf9fb317787fadfcf..cfc2aad902641609c3804e615c4cb66ce65299b7 100644
index 31cd4f927c273573b38021f84417101c57377902..f293e1c61d3b7a80b7dc472d927893f0439d6af9 100644
--- a/browser/base/content/browser-box.inc.xhtml
+++ b/browser/base/content/browser-box.inc.xhtml
@@ -3,12 +3,22 @@
@@ -10,7 +10,7 @@ index d58fcdf99843d110b708f3fbf9fb317787fadfcf..cfc2aad902641609c3804e615c4cb66c
+ <html:div id="zen-browser-background" class="zen-browser-generic-background">
+ <html:div class="zen-browser-grain" />
+ </html:div>
<box context="sidebar-context-menu" id="sidebar-main" hidden="true">
<box context="sidebar-context-menu" id="sidebar-main" class="chrome-block" hidden="true">
<html:sidebar-main flex="1">
<box id="vertical-tabs" slot="tabstrip" customizable="true" contextmenu="toolbar-context-menu"></box>
</html:sidebar-main>
@@ -22,7 +22,7 @@ index d58fcdf99843d110b708f3fbf9fb317787fadfcf..cfc2aad902641609c3804e615c4cb66c
+ </html:div>
+<hbox id="zen-tabbox-wrapper" flex="1">
+ <tabbox id="tabbrowser-tabbox" flex="1" tabcontainer="tabbrowser-tabs">
<vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
<vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome chrome-block">
<box id="sidebar-header" align="center">
<toolbarbutton id="sidebar-switcher-target" class="tabbable" aria-expanded="false">
@@ -25,7 +35,7 @@

View File

@@ -1,12 +1,12 @@
diff --git a/browser/base/content/browser-fullScreenAndPointerLock.js b/browser/base/content/browser-fullScreenAndPointerLock.js
index 1eaf79a4f6788c518a4759bbce81175fd5fba220..6fde5e944ad4a847180ca83a9e6f4fde20aa7b42 100644
index d0d3b6fc57800b073bb1c75f6e55212749815b0a..f3d5790eed58f1cb9a36229582e0fa00f3668962 100644
--- a/browser/base/content/browser-fullScreenAndPointerLock.js
+++ b/browser/base/content/browser-fullScreenAndPointerLock.js
@@ -501,8 +501,6 @@ var FullScreen = {
// don't need that kind of precision in our CSS.
@@ -502,8 +502,6 @@ var FullScreen = {
shiftSize = shiftSize.toFixed(2);
let translate = shiftSize > 0 ? `0 ${shiftSize}px` : "";
- document.body.style.translate = translate;
gNavToolbox.classList.toggle("fullscreen-floating-toolbox", shiftSize > 0);
- gNavToolbox.style.translate = translate;
- gURLBar.style.translate = gURLBar.hasAttribute("breakout") ? translate : "";
let searchbar = document.getElementById("searchbar-new");
if (searchbar) {

View File

@@ -1,5 +1,5 @@
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index d1ab42d59f05513ec60a7578b7acab44875c544c..8c3cd75704991b8572d3f13a936fddd2616b2946 100644
index 1026474bb1bc026987be01a8c18fa0927cb911bc..60294e0587147d86ace8e6d6985d8c6eae8248b6 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -34,6 +34,7 @@ ChromeUtils.defineESModuleGetters(this, {
@@ -24,7 +24,7 @@ index d1ab42d59f05513ec60a7578b7acab44875c544c..8c3cd75704991b8572d3f13a936fddd2
if (backDisabled) {
backCommand.removeAttribute("disabled");
} else {
@@ -3715,7 +3721,7 @@ function warnAboutClosingWindow() {
@@ -3719,7 +3725,7 @@ function warnAboutClosingWindow() {
if (!isPBWindow && !toolbar.visible) {
return gBrowser.warnAboutClosingTabs(
@@ -33,7 +33,7 @@ index d1ab42d59f05513ec60a7578b7acab44875c544c..8c3cd75704991b8572d3f13a936fddd2
gBrowser.closingTabsEnum.ALL
);
}
@@ -3755,7 +3761,7 @@ function warnAboutClosingWindow() {
@@ -3759,7 +3765,7 @@ function warnAboutClosingWindow() {
return (
isPBWindow ||
gBrowser.warnAboutClosingTabs(
@@ -42,7 +42,7 @@ index d1ab42d59f05513ec60a7578b7acab44875c544c..8c3cd75704991b8572d3f13a936fddd2
gBrowser.closingTabsEnum.ALL
)
);
@@ -3780,7 +3786,7 @@ function warnAboutClosingWindow() {
@@ -3784,7 +3790,7 @@ function warnAboutClosingWindow() {
AppConstants.platform != "macosx" ||
isPBWindow ||
gBrowser.warnAboutClosingTabs(
@@ -51,13 +51,20 @@ index d1ab42d59f05513ec60a7578b7acab44875c544c..8c3cd75704991b8572d3f13a936fddd2
gBrowser.closingTabsEnum.ALL
)
);
@@ -4720,6 +4726,9 @@ var ConfirmationHint = {
@@ -4744,6 +4750,16 @@ var ConfirmationHint = {
}
document.l10n.setAttributes(this._message, messageId, options.l10nArgs);
document.l10n.setAttributes(this._message, messageId, l10nArgs);
+ if (window.gZenUIManager?.showToast) {
+ return window.gZenUIManager.showToast(messageId, options);
+ return window.gZenUIManager.showToast(messageId, {
+ hideCheckmark,
+ descriptionId,
+ l10nArgs,
+ showDescription,
+ position,
+ event,
+ });
+ }
if (options.descriptionId) {
document.l10n.setAttributes(this._description, options.descriptionId);
if (descriptionId) {
document.l10n.setAttributes(this._description, descriptionId);
this._description.hidden = false;

View File

@@ -1,13 +1,13 @@
diff --git a/browser/base/content/navigator-toolbox.inc.xhtml b/browser/base/content/navigator-toolbox.inc.xhtml
index b4abfb868fc7c13e789acb57b44e386de6d31bf0..ad917f5362ed4f3ba0149c214fb53d3f087bbfcf 100644
index e7e94e13a990c154fb54bda4a3420ca00bdac009..8253b7d403734973729a5982cceafc12bab24f54 100644
--- a/browser/base/content/navigator-toolbox.inc.xhtml
+++ b/browser/base/content/navigator-toolbox.inc.xhtml
@@ -2,7 +2,7 @@
# 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/.
-<toolbox id="navigator-toolbox">
+<toolbox id="navigator-toolbox" persist="width style">
-<toolbox id="navigator-toolbox" class="chrome-block">
+<toolbox id="navigator-toolbox" class="chrome-block" persist="width style">
<script src="chrome://browser/content/navigator-toolbox.js" />
<!-- Menu -->

View File

@@ -1,20 +1,20 @@
diff --git a/browser/components/aboutwelcome/content/aboutwelcome.css b/browser/components/aboutwelcome/content/aboutwelcome.css
index 98497769b135efd3200607ee2cf50e82d06ed3fd..68e0778cfc4dc70935a3d48e79542b4133b293d2 100644
index 4a568479995c43ec2801c5b2f9452610923233ed..857a4a0ed78f3d374ed45fc4ff73e8e51dfbc2b9 100644
--- a/browser/components/aboutwelcome/content/aboutwelcome.css
+++ b/browser/components/aboutwelcome/content/aboutwelcome.css
@@ -330,6 +330,11 @@ panel#feature-callout {
--panel-shadow-margin: 6px;
--panel-arrow-space: calc(var(--panel-shadow-margin) + var(--arrow-visible-height) - 1.5px);
--panel-margin-offset: calc(-1 * (var(--panel-shadow-margin) + var(--arrow-corner-distance) + (var(--arrow-width) / 2)));
--panel-box-shadow-margin: 6px;
--panel-arrow-space: calc(var(--panel-box-shadow-margin) + var(--arrow-visible-height) - 1.5px);
--panel-margin-offset: calc(-1 * (var(--panel-box-shadow-margin) + var(--arrow-corner-distance) + (var(--arrow-width) / 2)));
+
+ @media -moz-pref("widget.macos.native-popovers") and (-moz-platform: macos) {
+ --panel-shadow-margin: 0;
+ --panel-box-shadow-margin: 0;
+ --panel-arrow-space: 0;
+ }
}
panel#feature-callout::part(content) {
@@ -517,6 +522,12 @@ div#feature-callout.hidden {
@@ -518,6 +523,12 @@ div#feature-callout.hidden {
width: 25em;
gap: 16px;
background: var(--fc-background);
@@ -27,7 +27,7 @@ index 98497769b135efd3200607ee2cf50e82d06ed3fd..68e0778cfc4dc70935a3d48e79542b41
}
#feature-callout .screen[pos=callout] .section-main .main-content .main-content-inner {
gap: 12px;
@@ -933,6 +944,10 @@ panel#feature-callout::part(content) {
@@ -934,6 +945,10 @@ panel#feature-callout::part(content) {
overflow: visible;
transform: rotate(45deg);
transform-style: preserve-3d;

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/customizableui/CustomizableUI.sys.mjs b/browser/components/customizableui/CustomizableUI.sys.mjs
index 5905271a3343efa04b45f5d1a63bfca3de342755..37f57de0ad72271d4c6e188ab9841b23b95f08d0 100644
index d5d4596739cde5d3d49d6294867f5da122c526b8..126474de8a38a11948c437703c875e98ff7c5f86 100644
--- a/browser/components/customizableui/CustomizableUI.sys.mjs
+++ b/browser/components/customizableui/CustomizableUI.sys.mjs
@@ -13,6 +13,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
@@ -120,7 +120,7 @@ index 5905271a3343efa04b45f5d1a63bfca3de342755..37f57de0ad72271d4c6e188ab9841b23
* The identifier string of the area that aNode is being inserted into.
*/
insertWidgetBefore(aNode, aNextNode, aContainer, aAreaId) {
+ if (aAreaId === CustomizableUI.AREA_NAVBAR && aNode.ownerGlobal.gZenVerticalTabsManager._hasSetSingleToolbar) {
+ if (aAreaId === CustomizableUI.AREA_NAVBAR && aNode.documentGlobal.gZenVerticalTabsManager._hasSetSingleToolbar) {
+ aContainer = aNode.ownerDocument.getElementById("zen-sidebar-top-buttons-customization-target");
+ aAreaId = "zen-sidebar-top-buttons";
+ }
@@ -139,7 +139,7 @@ index 5905271a3343efa04b45f5d1a63bfca3de342755..37f57de0ad72271d4c6e188ab9841b23
@@ -4573,7 +4571,7 @@ var CustomizableUIInternal = {
if (area.get("type") == CustomizableUI.TYPE_TOOLBAR) {
let defaultCollapsed = area.get("defaultCollapsed");
let win = areaNode.ownerGlobal;
let win = areaNode.documentGlobal;
- if (defaultCollapsed !== null) {
+ if (defaultCollapsed !== null && !zenDontRebuildCollapsed) {
win.setToolbarVisibility(
@@ -258,7 +258,7 @@ index 5905271a3343efa04b45f5d1a63bfca3de342755..37f57de0ad72271d4c6e188ab9841b23
let targetID = this.#toolbar.getAttribute("addon-webext-overflowtarget");
if (!targetID) {
@@ -8161,6 +8199,9 @@ class OverflowableToolbar {
let win = this.#toolbar.ownerGlobal;
let win = this.#toolbar.documentGlobal;
let { panel } = win.gUnifiedExtensions;
this.#webExtListRef = panel.querySelector(`#${targetID}`);
+ if (!this.#webExtListRef) {

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/extensions/parent/ext-browser.js b/browser/components/extensions/parent/ext-browser.js
index d1209bc2c828a19ade8cc027cdea6f42007f0de6..0a2def2f3c32618304cd8a263906b0c6e040dcbc 100644
index aca5a23deda6b0f2316b0e108cff20ffd7feda67..a06c90937f97a4994b0807b54984089dbe627a71 100644
--- a/browser/components/extensions/parent/ext-browser.js
+++ b/browser/components/extensions/parent/ext-browser.js
@@ -352,6 +352,7 @@ class TabTracker extends TabTrackerBase {
@@ -11,7 +11,7 @@ index d1209bc2c828a19ade8cc027cdea6f42007f0de6..0a2def2f3c32618304cd8a263906b0c6
if (id) {
return id;
@@ -386,6 +387,7 @@ class TabTracker extends TabTrackerBase {
if (nativeTab.ownerGlobal.closed) {
if (nativeTab.documentGlobal.closed) {
throw new Error("Cannot attach ID to a tab in a closed window.");
}
+ if (nativeTab.hasAttribute("zen-empty-tab")) return;
@@ -27,5 +27,5 @@ index d1209bc2c828a19ade8cc027cdea6f42007f0de6..0a2def2f3c32618304cd8a263906b0c6
+ }
+
// Check private browsing access at browser window level.
if (!this.extension.canAccessWindow(nativeTab.ownerGlobal)) {
if (!this.extension.canAccessWindow(nativeTab.documentGlobal)) {
return false;

View File

@@ -1,10 +1,12 @@
diff --git a/browser/components/preferences/jar.mn b/browser/components/preferences/jar.mn
index 78e38f98c1f69df31459fd4b6a119c93f6509c02..33abd46566146272da9f561e11ffa290d7000111 100644
index aec7888f59eeb5dbffc62b861fe223159ac42586..a593f3015469c11c762ae01465964251a77ddb45 100644
--- a/browser/components/preferences/jar.mn
+++ b/browser/components/preferences/jar.mn
@@ -54,3 +54,5 @@ browser.jar:
content/browser/preferences/widgets/sync-device-name.mjs (widgets/sync-device-name/sync-device-name.mjs)
content/browser/preferences/widgets/sync-engines-list.mjs (widgets/sync-engine-list/sync-engines-list.mjs)
@@ -69,5 +69,7 @@ browser.jar:
content/browser/preferences/widgets/sync-engines-list.css (widgets/sync-engine-list/sync-engines-list.css)
content/browser/preferences/widgets/update-information.mjs (widgets/update-information/update-information.mjs)
content/browser/preferences/widgets/update-information.css (widgets/update-information/update-information.css)
+
+ content/browser/preferences/zen-settings.js
content/browser/preferences/widgets/update-state.mjs (widgets/update-state/update-state.mjs)
content/browser/preferences/widgets/update-state.css (widgets/update-state/update-state.css)

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/preferences/main.js b/browser/components/preferences/main.js
index 6f4cb34d1639ac76a6d4ca40f0d33ae6fb6bf565..1f336a09d6f2e367effdf26e8baf58b5686d252d 100644
index c86e54bb6f5e00d9d7bdd81154857a5be97f909c..4035f6a667a361ad106e816a172342724a770435 100644
--- a/browser/components/preferences/main.js
+++ b/browser/components/preferences/main.js
@@ -2537,6 +2537,11 @@ function createStartupConfig(hidden = false) {
@@ -643,6 +643,11 @@ function createStartupConfig(hidden = false) {
id: "browserRestoreSession",
l10nId: "startup-restore-windows-and-tabs",
},
@@ -14,16 +14,16 @@ index 6f4cb34d1639ac76a6d4ca40f0d33ae6fb6bf565..1f336a09d6f2e367effdf26e8baf58b5
{
id: "windowsLaunchOnLogin",
l10nId: "windows-launch-on-login",
@@ -2578,7 +2583,7 @@ function createStartupConfig(hidden = false) {
@@ -690,7 +695,7 @@ function createStartupConfig(hidden = false) {
SettingGroupManager.registerGroups({
defaultBrowser: createDefaultBrowserConfig(),
startup: createStartupConfig(
- Services.prefs.getBoolPref("browser.settings-redesign.enabled", false)
- Services.prefs.getBoolPref("browser-settings-redesign.enabled", false)
+ false
),
zoom: {
l10nId: "preferences-zoom-header2",
@@ -3393,7 +3398,7 @@ function getBundleForLocales(newLocales) {
});
@@ -743,7 +748,7 @@ function getBundleForLocales(newLocales) {
])
);
return new Localization(

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/preferences/preferences.js b/browser/components/preferences/preferences.js
index 9d13733318e7a147adee1e44f96570c94f4948df..fb625d8da021dc0cebd7a14ca47446a0632e8e7a 100644
index 57add34d876fb885275f1147209c6fbeee367a7c..d4c64b9ec8b6d1e6e0bd0b888c6e7351fbe299a4 100644
--- a/browser/components/preferences/preferences.js
+++ b/browser/components/preferences/preferences.js
@@ -121,6 +121,7 @@ ChromeUtils.defineLazyGetter(this, "gSubDialog", function () {
@@ -132,6 +132,7 @@ ChromeUtils.defineLazyGetter(this, "gSubDialog", function () {
styleSheets: [
"chrome://browser/skin/preferences/dialog.css",
"chrome://browser/skin/preferences/preferences.css",
@@ -10,7 +10,7 @@ index 9d13733318e7a147adee1e44f96570c94f4948df..fb625d8da021dc0cebd7a14ca47446a0
],
resizeCallback: async ({ title, frame }) => {
// Search within main document and highlight matched keyword.
@@ -398,6 +399,10 @@ function init_all() {
@@ -522,6 +523,10 @@ function init_all() {
register_module("paneSearch", gSearchPane);
register_module("panePrivacy", gPrivacyPane);
register_module("paneContainers", gContainersPane);
@@ -19,5 +19,5 @@ index 9d13733318e7a147adee1e44f96570c94f4948df..fb625d8da021dc0cebd7a14ca47446a0
+ register_module("paneZenCKS", gZenCKSSettings);
+ register_module("paneZenMarketplace", gZenMarketplaceManager);
if (ExperimentAPI.labsEnabled) {
// Set hidden based on previous load's hidden value or if Nimbus is
// Restore the cached Firefox Labs nav button visibility so it shows
// immediately when recipes are expected to be available, before

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/preferences/preferences.xhtml b/browser/components/preferences/preferences.xhtml
index 3c4b3225c672bcb172e7f946bc5f98d424e21e84..d10824470c564b6631333f197de897c21ccc19f5 100644
index 9760a4a35b0b3bd21edec07a70c10bccc23e4a09..9f22146c259ea5b45005be660bfcb9ea2c1297ee 100644
--- a/browser/components/preferences/preferences.xhtml
+++ b/browser/components/preferences/preferences.xhtml
@@ -42,6 +42,8 @@
@@ -11,7 +11,7 @@ index 3c4b3225c672bcb172e7f946bc5f98d424e21e84..d10824470c564b6631333f197de897c2
<link rel="localization" href="branding/brand.ftl"/>
<link rel="localization" href="browser/browser.ftl"/>
<!-- Used by fontbuilder.js -->
@@ -126,6 +128,26 @@
@@ -121,6 +123,26 @@
iconsrc="chrome://browser/skin/preferences/category-general.svg"
data-l10n-id="pane-general-title">
</html:moz-page-nav-button>
@@ -35,12 +35,12 @@ index 3c4b3225c672bcb172e7f946bc5f98d424e21e84..d10824470c564b6631333f197de897c2
+ iconsrc="chrome://mozapps/skin/extensions/category-themes.svg"
+ data-l10n-id="pane-zen-marketplace-title">
+ </html:moz-page-nav-button>
<html:moz-page-nav-button id="category-home"
view="paneHome"
iconsrc="chrome://browser/skin/home.svg"
@@ -218,6 +240,10 @@
<html:moz-page-nav-button id="category-sync"
hidden="true"
view="paneSync"
@@ -253,6 +275,10 @@
#include containers.inc.xhtml
#include sync.inc.xhtml
#include experimental.inc.xhtml
#include moreFromMozilla.inc.xhtml
+#include zenLooksAndFeel.inc.xhtml
+#include zenKeyboardShortcuts.inc.xhtml

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/sessionstore/TabState.sys.mjs b/browser/components/sessionstore/TabState.sys.mjs
index eb24c3ffdd2cfb33379aca993af5171fdb91ac2c..15d3fbff397df23f112355e22ca5dba5bf29528f 100644
index 4ba4dda363b602cb6f4445ef056f2f9abb1b0e1e..6b4b407e05e26faca69d9d7ac6f31510620898fe 100644
--- a/browser/components/sessionstore/TabState.sys.mjs
+++ b/browser/components/sessionstore/TabState.sys.mjs
@@ -99,7 +99,25 @@ class _TabState {
@@ -99,10 +99,28 @@ class _TabState {
}
}
@@ -21,8 +21,11 @@ index eb24c3ffdd2cfb33379aca993af5171fdb91ac2c..15d3fbff397df23f112355e22ca5dba5
+ tabData._zenIsActiveTab = tab._zenContentsVisible;
+ tabData.zenLiveFolderItemId = tab.getAttribute("zen-live-folder-item-id");
+
tabData.searchMode = tab.ownerGlobal.gURLBar.getSearchMode(browser, true);
+ if (tabData.searchMode?.source === tab.ownerGlobal.UrlbarUtils.RESULT_SOURCE.ZEN_ACTIONS) {
tabData.searchMode = tab.documentGlobal.gURLBar.getSearchMode(
browser,
true
);
+ if (tabData.searchMode?.source === tab.documentGlobal.UrlbarUtils.RESULT_SOURCE.ZEN_ACTIONS) {
+ delete tabData.searchMode;
+ }

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tab.js b/browser/components/tabbrowser/content/tab.js
index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d645641cd 100644
index 8f2ebf3a0bd4e2af01cf41024b16bd491e8ed961..27721e26c3cd8cb066b462dedfa4ce785ca5c2c3 100644
--- a/browser/components/tabbrowser/content/tab.js
+++ b/browser/components/tabbrowser/content/tab.js
@@ -21,6 +21,7 @@
@@ -10,10 +10,10 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
<stack class="tab-icon-stack">
<hbox class="tab-throbber"/>
<hbox class="tab-icon-pending"/>
@@ -38,9 +39,11 @@
<hbox class="tab-secondary-label">
<label class="tab-icon-sound-label tab-icon-sound-pip-label" data-l10n-id="browser-tab-audio-pip" role="presentation"/>
</hbox>
@@ -35,9 +36,11 @@
pack="center"
flex="1">
<label class="tab-text tab-label" role="presentation"/>
+ <label class="zen-tab-sublabel" data-l10n-id="zen-tab-sublabel" data-l10n-args='{"tabSubtitle": "zen-default-pinned"}' role="presentation"/>
</vbox>
<image class="tab-note-icon" role="presentation"/>
@@ -22,7 +22,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
</hbox>
</stack>
`;
@@ -87,7 +90,7 @@
@@ -84,7 +87,7 @@
".tab-content":
"pinned,selected=visuallyselected,multiselected,titlechanged,attention",
".tab-icon-stack":
@@ -31,7 +31,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
".tab-throbber":
"fadein,pinned,busy,progress,selected=visuallyselected",
".tab-icon-pending":
@@ -96,9 +99,9 @@
@@ -93,9 +96,9 @@
"src=image,requestcontextid,fadein,pinned,selected=visuallyselected,busy,crashed,sharing,pictureinpicture,pending,discarded",
".tab-sharing-icon-overlay": "sharing,selected=visuallyselected,pinned",
".tab-icon-overlay":
@@ -43,7 +43,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
".tab-label-container":
"pinned,selected=visuallyselected,labeldirection",
".tab-label":
@@ -189,7 +192,7 @@
@@ -184,7 +187,7 @@
}
set _visuallySelected(val) {
@@ -52,7 +52,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
return;
}
@@ -225,11 +228,25 @@
@@ -220,11 +223,25 @@
}
get visible() {
@@ -83,7 +83,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
}
get hidden() {
@@ -308,7 +325,7 @@
@@ -303,7 +320,7 @@
return false;
}
@@ -92,7 +92,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
}
get lastAccessed() {
@@ -393,7 +410,18 @@
@@ -388,7 +405,18 @@
}
get group() {
@@ -112,7 +112,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
}
get splitview() {
@@ -475,6 +503,10 @@
@@ -470,6 +498,10 @@
}
}
@@ -123,7 +123,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
// If the previous target wasn't part of this tab then this is a mouseenter event.
if (!this.contains(event.relatedTarget)) {
this._mouseenter();
@@ -504,6 +536,7 @@
@@ -499,6 +531,7 @@
if (!this.contains(event.relatedTarget)) {
this._mouseleave();
}
@@ -131,7 +131,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
}
on_dragstart(event) {
@@ -538,6 +571,8 @@
@@ -533,6 +566,8 @@
this.style.MozUserFocus = "ignore";
} else if (
event.target.classList.contains("tab-close-button") ||
@@ -140,7 +140,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
event.target.classList.contains("tab-icon-overlay") ||
event.target.classList.contains("tab-audio-button")
) {
@@ -572,7 +607,7 @@
@@ -567,7 +602,7 @@
}
} else if (
event.altKey &&
@@ -149,7 +149,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
) {
eventMaySelectTab = false;
} else if (!this.selected && this.multiselected) {
@@ -597,6 +632,10 @@
@@ -592,6 +627,10 @@
this.style.MozUserFocus = "";
}
@@ -160,7 +160,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
on_click(event) {
if (event.button != 0) {
return;
@@ -620,14 +659,31 @@
@@ -615,14 +654,31 @@
trigger: "alt_click",
});
}
@@ -193,7 +193,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
gBrowser.multiSelectedTabsCount > 0 &&
!event.target.classList.contains("tab-close-button") &&
!event.target.classList.contains("tab-icon-overlay") &&
@@ -639,8 +695,9 @@
@@ -634,8 +690,9 @@
}
if (
@@ -205,7 +205,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
) {
if (this.activeMediaBlocked) {
if (this.multiselected) {
@@ -658,7 +715,7 @@
@@ -653,7 +710,7 @@
return;
}
@@ -214,7 +214,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
if (this.multiselected) {
gBrowser.removeMultiSelectedTabs(
lazy.TabMetrics.userTriggeredContext(
@@ -678,6 +735,14 @@
@@ -673,6 +730,14 @@
// (see tabbrowser-tabs 'click' handler).
gBrowser.tabContainer._blockDblClick = true;
}
@@ -229,7 +229,7 @@ index b9381999a77ecacdb95c69494ac8972e9f13d14d..a210b53bb46373f8bab532a00b25301d
}
on_dblclick(event) {
@@ -701,6 +766,8 @@
@@ -696,6 +761,8 @@
animate: true,
triggeringEvent: event,
});

View File

@@ -1,8 +1,8 @@
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a70e59c10 100644
index 08b5b56e069d038d72c87355920c4ce8a55ed805..0448277f2300dc6c01028435f6e91cc206dd6be4 100644
--- a/browser/components/tabbrowser/content/tabbrowser.js
+++ b/browser/components/tabbrowser/content/tabbrowser.js
@@ -502,6 +502,7 @@
@@ -511,6 +511,7 @@
* @type {MozBrowser[]}
*/
get splitViewBrowsers() {
@@ -10,7 +10,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
const browsers = [];
if (this.#activeSplitView) {
for (const tab of this.#activeSplitView.tabs) {
@@ -575,15 +576,66 @@
@@ -584,15 +585,66 @@
return this.tabContainer.visibleTabs;
}
@@ -79,7 +79,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
set selectedTab(val) {
if (
gSharedTabWarning.willShowSharedTabWarning(val) ||
@@ -592,6 +644,7 @@
@@ -601,6 +653,7 @@
) {
return;
}
@@ -87,7 +87,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
// Update the tab
this.tabbox.selectedTab = val;
}
@@ -659,6 +712,10 @@
@@ -668,6 +721,10 @@
userContextId = parseInt(tabArgument.getAttribute("usercontextid"), 10);
}
@@ -98,7 +98,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (tabArgument && tabArgument.linkedBrowser) {
remoteType = tabArgument.linkedBrowser.remoteType;
initialBrowsingContextGroupId =
@@ -751,6 +808,8 @@
@@ -760,6 +817,8 @@
this.tabpanels.appendChild(panel);
let tab = this.tabs[0];
@@ -107,7 +107,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
tab.linkedPanel = uniqueId;
this._selectedTab = tab;
this._selectedBrowser = browser;
@@ -1121,13 +1180,18 @@
@@ -1131,13 +1190,18 @@
}
this.showTab(aTab);
@@ -127,7 +127,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
aTab.setAttribute("pinned", "true");
this._updateTabBarForPinnedTabs();
@@ -1140,11 +1204,19 @@
@@ -1150,11 +1214,19 @@
}
this.#handleTabMove(aTab, () => {
@@ -148,7 +148,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
});
aTab.style.marginInlineStart = "";
@@ -1321,6 +1393,9 @@
@@ -1369,6 +1441,9 @@
let LOCAL_PROTOCOLS = ["chrome:", "about:", "resource:", "data:"];
@@ -158,7 +158,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (
aIconURL &&
!LOCAL_PROTOCOLS.some(protocol => aIconURL.startsWith(protocol))
@@ -1330,6 +1405,9 @@
@@ -1378,6 +1453,9 @@
);
return;
}
@@ -168,7 +168,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
let browser = this.getBrowserForTab(aTab);
browser.mIconURL = aIconURL;
@@ -1652,7 +1730,6 @@
@@ -1700,7 +1778,6 @@
// Preview mode should not reset the owner
if (!this._previewMode && !oldTab.selected) {
@@ -176,15 +176,15 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
}
let lastRelatedTab = this._lastRelatedTabMap.get(oldTab);
@@ -1743,6 +1820,7 @@
@@ -1791,6 +1868,7 @@
if (!this._previewMode) {
newTab.recordTimeFromUnloadToReload();
newTab.updateLastAccessed();
+ newTab.removeAttribute("unread");
oldTab.updateLastAccessed();
// if this is the foreground window, update the last-seen timestamps.
if (this.ownerGlobal == BrowserWindowTracker.getTopWindow()) {
@@ -1957,6 +2035,9 @@
if (this.documentGlobal == BrowserWindowTracker.getTopWindow()) {
@@ -2005,6 +2083,9 @@
}
let activeEl = document.activeElement;
@@ -194,7 +194,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
// If focus is on the old tab, move it to the new tab.
if (activeEl == oldTab) {
newTab.focus();
@@ -1995,7 +2076,7 @@
@@ -2043,7 +2124,7 @@
// Focus the location bar if it was previously focused for that tab.
// In full screen mode, only bother making the location bar visible
// if the tab is a blank one.
@@ -203,7 +203,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
let selectURL = () => {
if (this._asyncTabSwitching) {
// Set _awaitingSetURI flag to suppress popup notification
@@ -2283,7 +2364,12 @@
@@ -2331,7 +2412,12 @@
return this._setTabLabel(aTab, aLabel);
}
@@ -217,7 +217,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (!aLabel || (isURL && /^about:reader\?url=/.test(aLabel))) {
return false;
}
@@ -2408,7 +2494,7 @@
@@ -2457,7 +2543,7 @@
newIndex = this.selectedTab._tPos + 1;
}
@@ -226,7 +226,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (this.isTabGroupLabel(targetTab)) {
throw new Error(
"Replacing a tab group label with a tab is not supported"
@@ -2685,6 +2771,7 @@
@@ -2737,6 +2823,7 @@
uriIsAboutBlank,
userContextId,
skipLoad,
@@ -234,7 +234,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
} = {}) {
let b = document.createXULElement("browser");
// Use the JSM global to create the permanentKey, so that if the
@@ -2758,8 +2845,7 @@
@@ -2810,8 +2897,7 @@
// we use a different attribute name for this?
b.setAttribute("name", name);
}
@@ -244,7 +244,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
b.setAttribute("transparent", "true");
}
@@ -2929,7 +3015,7 @@
@@ -2981,7 +3067,7 @@
let panel = this.getPanel(browser);
let uniqueId = this._generateUniquePanelID();
@@ -253,7 +253,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
aTab.linkedPanel = uniqueId;
// Inject the <browser> into the DOM if necessary.
@@ -2989,8 +3075,8 @@
@@ -3041,8 +3127,8 @@
// If we transitioned from one browser to two browsers, we need to set
// hasSiblings=false on both the existing browser and the new browser.
if (this.tabs.length == 2) {
@@ -264,7 +264,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
} else {
aTab.linkedBrowser.browsingContext.hasSiblings = this.tabs.length > 1;
}
@@ -3175,7 +3261,6 @@
@@ -3227,7 +3313,6 @@
this.selectedTab = this.addTrustedTab(BROWSER_NEW_TAB_URL, {
tabIndex: tab._tPos + 1,
userContextId: tab.userContextId,
@@ -272,7 +272,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
focusUrlBar: true,
});
resolve(this.selectedBrowser);
@@ -3285,6 +3370,10 @@
@@ -3337,6 +3422,10 @@
schemelessInput,
hasValidUserGestureActivation = false,
textDirectiveUserActivation = false,
@@ -283,7 +283,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
} = {}
) {
// all callers of addTab that pass a params object need to pass
@@ -3295,10 +3384,25 @@
@@ -3347,10 +3436,25 @@
);
}
@@ -309,7 +309,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
// If we're opening a foreground tab, set the owner by default.
ownerTab ??= inBackground ? null : this.selectedTab;
@@ -3306,6 +3410,7 @@
@@ -3358,6 +3462,7 @@
if (this.selectedTab.owner) {
this.selectedTab.owner = null;
}
@@ -317,7 +317,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
// Find the tab that opened this one, if any. This is used for
// determining positioning, and inherited attributes such as the
@@ -3358,6 +3463,22 @@
@@ -3410,6 +3515,22 @@
noInitialLabel,
skipBackgroundNotify,
});
@@ -340,7 +340,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (insertTab) {
// Insert the tab into the tab container in the correct position.
this.#insertTabAtIndex(t, {
@@ -3366,6 +3487,7 @@
@@ -3418,6 +3539,7 @@
ownerTab,
openerTab,
pinned,
@@ -348,7 +348,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
bulkOrderedOpen,
tabGroup: tabGroup ?? openerTab?.group,
});
@@ -3384,6 +3506,7 @@
@@ -3436,6 +3558,7 @@
openWindowInfo,
skipLoad,
triggeringRemoteType,
@@ -356,7 +356,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
}));
if (focusUrlBar) {
@@ -3508,6 +3631,12 @@
@@ -3560,6 +3683,12 @@
}
}
@@ -369,7 +369,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
// Additionally send pinned tab events
if (pinned) {
this.#notifyPinnedStatus(t);
@@ -3518,6 +3647,9 @@
@@ -3570,6 +3699,9 @@
if (!inBackground) {
this.selectedTab = t;
}
@@ -379,7 +379,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
return t;
}
@@ -3750,6 +3882,7 @@
@@ -3802,6 +3934,7 @@
isAdoptingGroup = false,
isUserTriggered = false,
telemetryUserCreateSource = "unknown",
@@ -387,7 +387,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
} = {}
) {
if (
@@ -3760,9 +3893,6 @@
@@ -3812,9 +3945,6 @@
!this.isSplitViewWrapper(tabOrSplitView)
)
) {
@@ -397,7 +397,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
}
if (!color) {
@@ -3783,9 +3913,14 @@
@@ -3835,9 +3965,14 @@
label,
isAdoptingGroup
);
@@ -414,7 +414,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
);
group.addTabs(tabsAndSplitViews);
@@ -3906,7 +4041,7 @@
@@ -3958,7 +4093,7 @@
}
this.#handleTabMove(tab, () =>
@@ -423,7 +423,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
);
}
@@ -3990,6 +4125,7 @@
@@ -4044,6 +4179,7 @@
color: group.color,
insertBefore: newTabs[0],
isAdoptingGroup: true,
@@ -431,7 +431,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
});
}
@@ -4200,6 +4336,7 @@
@@ -4254,6 +4390,7 @@
openWindowInfo,
skipLoad,
triggeringRemoteType,
@@ -439,7 +439,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
}
) {
// If we don't have a preferred remote type (or it is `NOT_REMOTE`), and
@@ -4269,6 +4406,7 @@
@@ -4323,6 +4460,7 @@
openWindowInfo,
name,
skipLoad,
@@ -447,7 +447,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
});
}
@@ -4482,9 +4620,9 @@
@@ -4536,9 +4674,9 @@
}
// Add a new tab if needed.
@@ -459,7 +459,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
let url = "about:blank";
if (tabData.entries?.length) {
@@ -4521,8 +4659,10 @@
@@ -4575,8 +4713,10 @@
insertTab: false,
skipLoad: true,
preferredRemoteType,
@@ -471,7 +471,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (select) {
tabToSelect = tab;
}
@@ -4544,7 +4684,8 @@
@@ -4598,7 +4738,8 @@
this.pinTab(tab);
// Then ensure all the tab open/pinning information is sent.
this._fireTabOpen(tab, {});
@@ -481,7 +481,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
let { groupId } = tabData;
const tabGroup = tabGroupWorkingData.get(groupId);
// if a tab refers to a tab group we don't know, skip any group
@@ -4564,7 +4705,10 @@
@@ -4618,7 +4759,10 @@
tabGroup.stateData.id,
tabGroup.stateData.color,
tabGroup.stateData.collapsed,
@@ -493,7 +493,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
);
tabsFragment.appendChild(tabGroup.node);
}
@@ -4619,9 +4763,21 @@
@@ -4673,9 +4817,21 @@
// to remove the old selected tab.
if (tabToSelect) {
let leftoverTab = this.selectedTab;
@@ -515,7 +515,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (tabs.length > 1 || !tabs[0].selected) {
this._updateTabsAfterInsert();
@@ -4812,11 +4968,14 @@
@@ -4866,11 +5022,14 @@
if (ownerTab) {
tab.owner = ownerTab;
}
@@ -531,7 +531,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (
!bulkOrderedOpen &&
((openerTab &&
@@ -4828,7 +4987,7 @@
@@ -4882,7 +5041,7 @@
let lastRelatedTab =
openerTab && this._lastRelatedTabMap.get(openerTab);
let previousTab = lastRelatedTab || openerTab || this.selectedTab;
@@ -540,7 +540,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
tabGroup = previousTab.group;
}
if (
@@ -4844,7 +5003,7 @@
@@ -4898,7 +5057,7 @@
previousTab.splitview
) + 1;
} else if (previousTab.visible) {
@@ -549,7 +549,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
} else if (previousTab == FirefoxViewHandler.tab) {
elementIndex = 0;
}
@@ -4872,14 +5031,14 @@
@@ -4926,14 +5085,14 @@
}
// Ensure index is within bounds.
if (tab.pinned) {
@@ -568,7 +568,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (pinned && !itemAfter?.pinned) {
itemAfter = null;
@@ -4896,7 +5055,7 @@
@@ -4950,7 +5109,7 @@
this.tabContainer._invalidateCachedTabs();
@@ -577,7 +577,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (
(this.isTab(itemAfter) && itemAfter.group == tabGroup) ||
this.isSplitViewWrapper(itemAfter)
@@ -4927,7 +5086,11 @@
@@ -4981,7 +5140,11 @@
const tabContainer = pinned
? this.tabContainer.pinnedTabsContainer
: this.tabContainer;
@@ -589,7 +589,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
}
if (tab.group?.collapsed) {
@@ -4942,6 +5105,7 @@
@@ -4996,6 +5159,7 @@
if (pinned) {
this._updateTabBarForPinnedTabs();
}
@@ -597,7 +597,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
TabBarVisibility.update();
}
@@ -5490,6 +5654,7 @@
@@ -5544,6 +5708,7 @@
telemetrySource,
} = {}
) {
@@ -605,7 +605,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
// When 'closeWindowWithLastTab' pref is enabled, closing all tabs
// can be considered equivalent to closing the window.
if (
@@ -5579,6 +5744,7 @@
@@ -5633,6 +5798,7 @@
if (lastToClose) {
this.removeTab(lastToClose, aParams);
}
@@ -613,7 +613,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
} catch (e) {
console.error(e);
}
@@ -5624,6 +5790,14 @@
@@ -5678,6 +5844,14 @@
return;
}
@@ -628,7 +628,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
let isVisibleTab = aTab.visible;
// We have to sample the tab width now, since _beginRemoveTab might
// end up modifying the DOM in such a way that aTab gets a new
@@ -5631,6 +5805,9 @@
@@ -5685,6 +5859,9 @@
// state).
let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width;
let isLastTab = this.#isLastTabInWindow(aTab);
@@ -638,7 +638,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (
!this._beginRemoveTab(aTab, {
closeWindowFastpath: true,
@@ -5642,13 +5819,14 @@
@@ -5696,13 +5873,14 @@
telemetrySource,
})
) {
@@ -654,7 +654,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
let lockTabSizing =
!this.tabContainer.verticalMode &&
!aTab.pinned &&
@@ -5679,7 +5857,13 @@
@@ -5733,7 +5911,13 @@
// We're not animating, so we can cancel the animation stopwatch.
Glean.browserTabclose.timeAnim.cancel(aTab._closeTimeAnimTimerId);
aTab._closeTimeAnimTimerId = null;
@@ -669,7 +669,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
return;
}
@@ -5813,7 +5997,7 @@
@@ -5867,7 +6051,7 @@
closeWindowWithLastTab != null
? closeWindowWithLastTab
: !window.toolbar.visible ||
@@ -678,7 +678,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (closeWindow) {
// We've already called beforeunload on all the relevant tabs if we get here,
@@ -5837,6 +6021,7 @@
@@ -5891,6 +6075,7 @@
newTab = true;
}
@@ -686,7 +686,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
aTab._endRemoveArgs = [closeWindow, newTab];
// swapBrowsersAndCloseOther will take care of closing the window without animation.
@@ -5877,13 +6062,7 @@
@@ -5931,13 +6116,7 @@
aTab._mouseleave();
if (newTab) {
@@ -701,7 +701,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
} else {
TabBarVisibility.update();
}
@@ -6016,6 +6195,7 @@
@@ -6070,6 +6249,7 @@
this.tabs[i]._tPos = i;
}
@@ -709,7 +709,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (!this._windowIsClosing) {
// update tab close buttons state
this.tabContainer._updateCloseButtons();
@@ -6201,6 +6381,7 @@
@@ -6255,6 +6435,7 @@
memory_after: await getTotalMemoryUsage(),
time_to_unload_in_ms: timeElapsed,
});
@@ -717,7 +717,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
}
/**
@@ -6246,6 +6427,7 @@
@@ -6300,6 +6481,7 @@
}
let excludeTabs = new Set(aExcludeTabs);
@@ -725,7 +725,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
// If this tab has a successor, it should be selectable, since
// hiding or closing a tab removes that tab as a successor.
@@ -6258,15 +6440,22 @@
@@ -6312,15 +6494,22 @@
!excludeTabs.has(aTab.owner) &&
Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose")
) {
@@ -750,7 +750,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
let tab = this.tabContainer.findNextTab(aTab, {
direction: 1,
filter: _tab => remainingTabs.includes(_tab),
@@ -6280,7 +6469,7 @@
@@ -6334,7 +6523,7 @@
}
if (tab) {
@@ -759,7 +759,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
}
// If no qualifying visible tab was found, see if there is a tab in
@@ -6301,7 +6490,7 @@
@@ -6355,7 +6544,7 @@
});
}
@@ -768,7 +768,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
}
_blurTab(aTab) {
@@ -6312,7 +6501,7 @@
@@ -6366,7 +6555,7 @@
* @returns {boolean}
* False if swapping isn't permitted, true otherwise.
*/
@@ -777,7 +777,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
// Do not allow transfering a private tab to a non-private window
// and vice versa.
if (
@@ -6366,6 +6555,7 @@
@@ -6420,6 +6609,7 @@
// fire the beforeunload event in the process. Close the other
// window if this was its last tab.
if (
@@ -785,22 +785,22 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
!remoteBrowser._beginRemoveTab(aOtherTab, {
adoptedByTab: aOurTab,
closeWindowWithLastTab: true,
@@ -6377,7 +6567,7 @@
@@ -6431,7 +6621,7 @@
// If this is the last tab of the window, hide the window
// immediately without animation before the docshell swap, to avoid
// about:blank being painted.
- let [closeWindow] = aOtherTab._endRemoveArgs;
+ let [closeWindow] = !zenCloseOther ? [false] : aOtherTab._endRemoveArgs;
if (closeWindow) {
let win = aOtherTab.ownerGlobal;
let win = aOtherTab.documentGlobal;
win.windowUtils.suppressAnimation(true);
@@ -6511,11 +6701,13 @@
@@ -6565,11 +6755,13 @@
}
// Finish tearing down the tab that's going away.
+ if (zenCloseOther) {
if (closeWindow) {
aOtherTab.ownerGlobal.close();
aOtherTab.documentGlobal.close();
} else {
remoteBrowser._endRemoveTab(aOtherTab);
}
@@ -808,7 +808,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
this.setTabTitle(aOurTab);
@@ -6717,10 +6909,10 @@
@@ -6771,10 +6963,10 @@
SessionStore.deleteCustomTabValue(aTab, "hiddenBy");
}
@@ -821,7 +821,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
aTab.selected ||
aTab.closing ||
// Tabs that are sharing the screen, microphone or camera cannot be hidden.
@@ -6780,7 +6972,8 @@
@@ -6834,7 +7026,8 @@
* @param {object} [aOptions={}]
* Key-value pairs that will be serialized into the features string.
*/
@@ -831,7 +831,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (this.tabs.length == 1) {
return null;
}
@@ -6797,7 +6990,7 @@
@@ -6851,7 +7044,7 @@
// tell a new window to take the "dropped" tab
let args = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
args.appendElement(aTab.splitview ?? aTab);
@@ -840,7 +840,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
private: PrivateBrowsingUtils.isWindowPrivate(window),
features: Object.entries(aOptions)
.map(([key, value]) => `${key}=${value}`)
@@ -6805,6 +6998,8 @@
@@ -6859,6 +7052,8 @@
openerWindow: window,
args,
});
@@ -849,7 +849,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
}
/**
@@ -6917,7 +7112,7 @@
@@ -6971,7 +7166,7 @@
* `true` if element is a `<tab-group>`
*/
isTabGroup(element) {
@@ -858,7 +858,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
}
/**
@@ -7002,8 +7197,8 @@
@@ -7056,8 +7251,8 @@
}
// Don't allow mixing pinned and unpinned tabs.
@@ -869,7 +869,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
} else {
tabIndex = Math.max(tabIndex, this.pinnedTabCount);
}
@@ -7049,8 +7244,8 @@
@@ -7103,8 +7298,8 @@
this.#handleTabMove(
element,
() => {
@@ -880,7 +880,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
neighbor = neighbor.group;
}
if (neighbor?.splitview) {
@@ -7061,6 +7256,12 @@
@@ -7115,6 +7310,12 @@
return;
}
}
@@ -893,7 +893,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
if (movingForwards && neighbor) {
neighbor.after(element);
@@ -7119,23 +7320,31 @@
@@ -7173,23 +7374,31 @@
#moveTabNextTo(element, targetElement, moveBefore = false, metricsContext) {
if (this.isTabGroupLabel(targetElement)) {
targetElement = targetElement.group;
@@ -931,7 +931,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
} else if (!element.pinned && targetElement && targetElement.pinned) {
// If the caller asks to move an unpinned element next to a pinned
// tab, move the unpinned element to be the first unpinned element
@@ -7148,12 +7357,35 @@
@@ -7202,12 +7411,35 @@
// move the tab group right before the first unpinned tab.
// 4. Moving a tab group and the first unpinned tab is grouped:
// move the tab group right before the first unpinned tab's tab group.
@@ -968,7 +968,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
// We want to include the splitview wrapper if it's the targetElement, but
// not in the case where we want to reverse tabs within the same splitview.
@@ -7162,6 +7394,7 @@
@@ -7216,6 +7448,7 @@
}
let getContainer = () =>
@@ -976,7 +976,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
element.pinned
? this.tabContainer.pinnedTabsContainer
: this.tabContainer;
@@ -7170,11 +7403,15 @@
@@ -7224,11 +7457,15 @@
element,
() => {
if (moveBefore) {
@@ -993,7 +993,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
}
},
metricsContext
@@ -7248,11 +7485,15 @@
@@ -7302,11 +7539,15 @@
* @param {TabMetricsContext} [metricsContext]
*/
moveTabToExistingGroup(aTab, aGroup, metricsContext) {
@@ -1012,7 +1012,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
}
if (aTab.group && aTab.group.id === aGroup.id) {
return;
@@ -7324,6 +7565,7 @@
@@ -7378,6 +7619,7 @@
let state = {
tabIndex: tab._tPos,
@@ -1020,7 +1020,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
};
if (tab.visible) {
state.elementIndex = tab.elementIndex;
@@ -7355,7 +7597,7 @@
@@ -7409,7 +7651,7 @@
let changedSplitView =
previousTabState.splitViewId != currentTabState.splitViewId;
@@ -1029,7 +1029,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
tab.dispatchEvent(
new CustomEvent("TabMove", {
bubbles: true,
@@ -7402,6 +7644,10 @@
@@ -7456,6 +7698,10 @@
moveActionCallback();
@@ -1040,13 +1040,13 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
// Clear tabs cache after moving nodes because the order of tabs may have
// changed.
this.tabContainer._invalidateCachedTabs();
@@ -7452,7 +7698,22 @@
@@ -7506,7 +7752,22 @@
* @returns {object}
* The new tab in the current window, null if the tab couldn't be adopted.
*/
- adoptTab(aTab, { elementIndex, tabIndex, selectTab = false } = {}) {
+ adoptTab(aTab, { elementIndex, tabIndex, selectTab = false, spaceId = null } = {}) {
+ if (window.gZenWorkspaces.currentWindowIsSyncing && aTab.ownerGlobal.gZenWorkspaces?.currentWindowIsSyncing) {
+ if (window.gZenWorkspaces.currentWindowIsSyncing && aTab.documentGlobal.gZenWorkspaces?.currentWindowIsSyncing) {
+ const tabId = aTab.id;
+ const thisTab = window.gZenWindowSync.getItemFromWindow(window, tabId);
+ if (thisTab) {
@@ -1064,7 +1064,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
// Swap the dropped tab with a new one we create and then close
// it in the other window (making it seem to have moved between
// windows). We also ensure that the tab we create to swap into has
@@ -7495,6 +7756,8 @@
@@ -7549,6 +7810,8 @@
}
params.skipLoad = true;
let newTab = this.addWebTab("about:blank", params);
@@ -1073,7 +1073,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
aTab.container.tabDragAndDrop.finishAnimateTabMove();
@@ -8205,7 +8468,7 @@
@@ -8259,7 +8522,7 @@
// preventDefault(). It will still raise the window if appropriate.
return;
}
@@ -1082,7 +1082,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
window.focus();
aEvent.preventDefault();
}
@@ -8222,7 +8485,6 @@
@@ -8276,7 +8539,6 @@
on_TabGroupCollapse(aEvent) {
aEvent.target.tabs.forEach(tab => {
@@ -1090,7 +1090,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
});
}
@@ -8556,7 +8818,9 @@
@@ -8630,7 +8892,9 @@
let filter = this._tabFilters.get(tab);
if (filter) {
@@ -1100,7 +1100,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
let listener = this._tabListeners.get(tab);
if (listener) {
@@ -9359,6 +9623,7 @@
@@ -9435,6 +9699,7 @@
aWebProgress.isTopLevel
) {
this.mTab.setAttribute("busy", "true");
@@ -1108,7 +1108,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
gBrowser._tabAttrModified(this.mTab, ["busy"]);
this.mTab._notselectedsinceload = !this.mTab.selected;
}
@@ -9439,6 +9704,7 @@
@@ -9515,6 +9780,7 @@
// known defaults. Note we use the original URL since about:newtab
// redirects to a prerendered page.
const shouldRemoveFavicon =
@@ -1116,7 +1116,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
!this.mBrowser.mIconURL &&
!ignoreBlank &&
!(originalLocation.spec in FAVICON_DEFAULTS);
@@ -9613,13 +9879,6 @@
@@ -9689,13 +9955,6 @@
this.mBrowser.originalURI = aRequest.originalURI;
}
@@ -1130,7 +1130,7 @@ index 43fb79a3060e20f671ae6ffc26350c7abf497702..028dfcba9e23a17e4152071dd58eb97a
}
let userContextId = this.mBrowser.getAttribute("usercontextid") || 0;
@@ -10507,7 +10766,8 @@ var TabContextMenu = {
@@ -10587,7 +10846,8 @@ var TabContextMenu = {
);
contextUnpinSelectedTabs.hidden =
!this.contextTab.pinned || !this.multiselected;

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tabgroup.js b/browser/components/tabbrowser/content/tabgroup.js
index d1be14df27d76a191eaff05502c030fd68c46738..e9b5e90e39b594a6119081c8d707fb4a064fea9b 100644
index e78fa0dec83424c0059c081f83fda0d23bdb5a94..a7de584d9029ff9e55d809d50377593e398ee999 100644
--- a/browser/components/tabbrowser/content/tabgroup.js
+++ b/browser/components/tabbrowser/content/tabgroup.js
@@ -14,11 +14,11 @@
@@ -49,7 +49,7 @@ index d1be14df27d76a191eaff05502c030fd68c46738..e9b5e90e39b594a6119081c8d707fb4a
// Similar to above, always set up TabSelect listener, as this gets
// removed in disconnectedCallback
this.ownerGlobal.addEventListener("TabSelect", this);
this.documentGlobal.addEventListener("TabSelect", this);
this.addEventListener("SplitViewTabChange", this);
- if (this._initialized) {
@@ -129,7 +129,7 @@ index d1be14df27d76a191eaff05502c030fd68c46738..e9b5e90e39b594a6119081c8d707fb4a
}
get color() {
@@ -317,6 +348,9 @@
@@ -335,6 +366,9 @@
}
set collapsed(val) {
@@ -139,7 +139,7 @@ index d1be14df27d76a191eaff05502c030fd68c46738..e9b5e90e39b594a6119081c8d707fb4a
if (!!val == this.collapsed) {
return;
}
@@ -403,7 +437,6 @@
@@ -421,7 +455,6 @@
tabGroupName,
})
.then(result => {
@@ -147,7 +147,7 @@ index d1be14df27d76a191eaff05502c030fd68c46738..e9b5e90e39b594a6119081c8d707fb4a
});
}
@@ -478,13 +511,68 @@
@@ -496,13 +529,68 @@
* @returns {MozTabbrowserTab[]}
*/
get tabs() {
@@ -221,15 +221,15 @@ index d1be14df27d76a191eaff05502c030fd68c46738..e9b5e90e39b594a6119081c8d707fb4a
}
/**
@@ -592,7 +680,6 @@
@@ -610,7 +698,6 @@
);
} else {
if (tabOrSplitView.pinned) {
- tabOrSplitView.ownerGlobal.gBrowser.unpinTab(tabOrSplitView);
- tabOrSplitView.documentGlobal.gBrowser.unpinTab(tabOrSplitView);
}
let tabToMove =
this.ownerGlobal === tabOrSplitView.ownerGlobal
@@ -661,7 +748,7 @@
this.documentGlobal === tabOrSplitView.documentGlobal
@@ -679,7 +766,7 @@
*/
on_click(event) {
let isToggleElement =
@@ -238,7 +238,7 @@ index d1be14df27d76a191eaff05502c030fd68c46738..e9b5e90e39b594a6119081c8d707fb4a
event.target === this.#overflowCountLabel;
if (isToggleElement && event.button === 0) {
event.preventDefault();
@@ -740,5 +827,6 @@
@@ -758,5 +845,6 @@
}
}

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/urlbar/content/UrlbarInput.mjs b/browser/components/urlbar/content/UrlbarInput.mjs
index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f771f0a75a8 100644
index 0fba59d62af9d3cd05bfee2cf84cd8b7cf9bfd6e..6af2ceed93a6c2799040512cbe646ddb7f629ab6 100644
--- a/browser/components/urlbar/content/UrlbarInput.mjs
+++ b/browser/components/urlbar/content/UrlbarInput.mjs
@@ -98,6 +98,13 @@ const lazy = XPCOMUtils.declareLazy({
@@ -16,7 +16,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
const UNLIMITED_MAX_RESULTS = 99;
let getBoundsWithoutFlushing = element =>
@@ -743,7 +750,16 @@ ${
@@ -770,7 +777,16 @@ ${
// See _on_select(). HTMLInputElement.select() dispatches a "select"
// event but does not set the primary selection.
this._suppressPrimaryAdjustment = true;
@@ -27,13 +27,13 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
+ zenToolbox.hasAttribute("zen-user-show")
+ ));
this.inputField.select();
+ this.document.ownerGlobal.setTimeout(() => {
+ this.document.documentGlobal.setTimeout(() => {
+ this.window.document.documentElement.removeAttribute("supress-primary-adjustment");
+ }, 0);
this._suppressPrimaryAdjustment = false;
}
@@ -817,6 +833,10 @@ ${
@@ -844,6 +860,10 @@ ${
hideSearchTerms = false,
isSameDocument = false,
} = {}) {
@@ -44,11 +44,10 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
if (!this.#isAddressbar) {
throw new Error(
"Cannot set URI for UrlbarInput that is not an address bar"
@@ -1106,8 +1126,16 @@ ${
return;
}
@@ -1138,7 +1158,16 @@ ${
this.searchModeSwitcher?.updateSearchIcon();
}
-
+ const zenToolbox = this.document.getElementById("navigator-toolbox");
+ this.window.document.documentElement.setAttribute("supress-primary-adjustment", !(
+ zenToolbox.hasAttribute("zen-has-hover") ||
@@ -56,13 +55,13 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
+ zenToolbox.hasAttribute("zen-user-show")
+ ));
this.handleNavigation({ event });
+ this.document.ownerGlobal.setTimeout(() => {
+ this.document.documentGlobal.setTimeout(() => {
+ this.window.document.documentElement.removeAttribute("supress-primary-adjustment");
+ }, 100);
}
/**
@@ -1551,7 +1579,11 @@ ${
@@ -1627,7 +1656,11 @@ ${
}
if (!this.#providesSearchMode(result)) {
@@ -75,7 +74,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
}
if (isCanonized) {
@@ -2858,6 +2890,42 @@ ${
@@ -2936,6 +2969,42 @@ ${
await this.#updateLayoutBreakoutDimensions();
}
@@ -118,9 +117,9 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
startLayoutExtend() {
if (!this.#allowBreakout || this.hasAttribute("breakout-extend")) {
// Do not expand if the Urlbar does not support being expanded or it is
@@ -2872,6 +2940,13 @@ ${
@@ -2954,6 +3023,13 @@ ${
this.setAttribute("breakout-extend", "true");
this.toggleAttribute("breakout-extend", true);
+ this.window.gZenUIManager.onUrlbarOpen();
+ if (this.zenUrlbarBehavior == 'float' || (this.zenUrlbarBehavior == 'floating-on-type' && !this.focusedViaMousedown)) {
@@ -132,7 +131,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
// Enable the animation only after the first extend call to ensure it
// doesn't run when opening a new window.
if (!this.hasAttribute("breakout-extend-animate")) {
@@ -2891,6 +2966,29 @@ ${
@@ -2981,6 +3057,29 @@ ${
return;
}
@@ -153,16 +152,16 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
+ zenToolbox.hasAttribute("zen-user-show")
+ ));
+ this.window.gBrowser.selectedBrowser.focus();
+ this.document.ownerGlobal.setTimeout(() => {
+ this.document.documentGlobal.setTimeout(() => {
+ this.window.document.documentElement.removeAttribute("supress-primary-adjustment");
+ }, 100);
+ this.window.gZenUIManager.onUrlbarClose();
+ this.removeAttribute("zen-floating-urlbar");
+
this.removeAttribute("breakout-extend");
this.toggleAttribute("breakout-extend", false);
this.#updateTextboxPosition();
}
@@ -2921,7 +3019,7 @@ ${
@@ -3028,7 +3127,7 @@ ${
forceUnifiedSearchButtonAvailable = false
) {
let prevState = this.getAttribute("pageproxystate");
@@ -171,9 +170,9 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
this.setAttribute("pageproxystate", state);
this._inputContainer.setAttribute("pageproxystate", state);
this._identityBox?.setAttribute("pageproxystate", state);
@@ -3198,10 +3296,12 @@ ${
return;
@@ -3309,10 +3408,12 @@ ${
}
this.style.top = px(
+ this.window.gZenVerticalTabsManager._hasSetSingleToolbar ?
this.parentNode.getBoxQuads({
@@ -184,7 +183,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
);
}
@@ -3260,9 +3360,10 @@ ${
@@ -3371,9 +3472,10 @@ ${
return;
}
@@ -196,7 +195,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
);
this.style.setProperty(
"--urlbar-height",
@@ -3768,6 +3869,7 @@ ${
@@ -3878,6 +3980,7 @@ ${
}
_toggleActionOverride(event) {
@@ -204,7 +203,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
if (
event.keyCode == KeyEvent.DOM_VK_SHIFT ||
event.keyCode == KeyEvent.DOM_VK_ALT ||
@@ -3880,8 +3982,8 @@ ${
@@ -3990,8 +4093,8 @@ ${
if (!this.#isAddressbar) {
return val;
}
@@ -215,7 +214,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
: val;
// Only trim value if the directionality doesn't change to RTL and we're not
// showing a strikeout https protocol.
@@ -4180,6 +4282,7 @@ ${
@@ -4290,6 +4393,7 @@ ${
resultDetails = null,
browser = this.window.gBrowser.selectedBrowser
) {
@@ -223,7 +222,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
if (this.#isAddressbar) {
this.#prepareAddressbarLoad(
url,
@@ -4291,6 +4394,10 @@ ${
@@ -4401,6 +4505,10 @@ ${
}
reuseEmpty = true;
}
@@ -234,7 +233,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
if (
where == "tab" &&
reuseEmpty &&
@@ -4298,6 +4405,9 @@ ${
@@ -4408,6 +4516,9 @@ ${
) {
where = "current";
}
@@ -244,7 +243,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
return where;
}
@@ -4552,6 +4662,7 @@ ${
@@ -4662,6 +4773,7 @@ ${
this.setResultForCurrentValue(null);
this.handleCommand();
this.controller.clearLastQueryContextCache();
@@ -252,7 +251,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
this._suppressStartQuery = false;
});
@@ -4559,7 +4670,6 @@ ${
@@ -4669,7 +4781,6 @@ ${
contextMenu.addEventListener("popupshowing", () => {
// Close the results pane when the input field contextual menu is open,
// because paste and go doesn't want a result selection.
@@ -260,7 +259,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
let controller =
this.document.commandDispatcher.getControllerForCommand("cmd_paste");
@@ -4715,7 +4825,11 @@ ${
@@ -4825,7 +4936,11 @@ ${
if (!engineName && !source && !this.hasAttribute("searchmode")) {
return;
}
@@ -273,7 +272,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
if (this._searchModeIndicatorTitle) {
this._searchModeIndicatorTitle.textContent = "";
this._searchModeIndicatorTitle.removeAttribute("data-l10n-id");
@@ -5031,6 +5145,7 @@ ${
@@ -5141,6 +5256,7 @@ ${
this.document.l10n.setAttributes(
this.inputField,
@@ -281,7 +280,20 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
l10nId,
l10nId == "urlbar-placeholder-with-name"
? { name: engineName }
@@ -5156,6 +5271,11 @@ ${
@@ -5187,6 +5303,12 @@ ${
_on_blur(event) {
lazy.logger.debug("Blur Event");
+ if (
+ this.document.commandDispatcher.focusedElement == this.inputField &&
+ !lazy.UrlbarPrefs.get("closeOnWindowBlur")
+ ) {
+ return;
+ }
// We cannot count every blur events after a missed engagement as abandoment
// because the user may have clicked on some view element that executes
// a command causing a focus change. For example opening preferences from
@@ -5264,6 +5386,11 @@ ${
}
_on_click(event) {
@@ -293,7 +305,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
switch (event.target) {
case this.inputField:
case this._inputContainer:
@@ -5242,7 +5362,7 @@ ${
@@ -5356,7 +5483,7 @@ ${
}
}
@@ -302,7 +314,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
this.view.autoOpen({ event });
} else {
if (this._untrimOnFocusAfterKeydown) {
@@ -5282,9 +5402,16 @@ ${
@@ -5396,9 +5523,16 @@ ${
}
_on_mousedown(event) {
@@ -320,7 +332,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
if (
event.composedTarget != this.inputField &&
event.composedTarget != this._inputContainer
@@ -5294,6 +5421,10 @@ ${
@@ -5408,6 +5542,10 @@ ${
this.focusedViaMousedown = !this.focused;
this.#preventClickSelectsAll = this.focused;
@@ -331,7 +343,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
// Keep the focus status, since the attribute may be changed
// upon calling this.focus().
@@ -5329,7 +5460,7 @@ ${
@@ -5443,7 +5581,7 @@ ${
}
// Don't close the view when clicking on a tab; we may want to keep the
// view open on tab switch, and the TabSelect event arrived earlier.
@@ -340,7 +352,7 @@ index d6615ec5a29f3e3327ac4171f3fc5d9a69bd09fe..c166b7de23c35716bf8c51b6b9c72f77
break;
}
@@ -5636,7 +5767,7 @@ ${
@@ -5732,7 +5870,7 @@ ${
// When we are in actions search mode we can show more results so
// increase the limit.
let maxResults =

View File

@@ -1,8 +1,8 @@
diff --git a/browser/modules/URILoadingHelper.sys.mjs b/browser/modules/URILoadingHelper.sys.mjs
index bd2e54e914b171df9b8bcc7dcbc2388e9641f6c6..8b3cb6542bea3fb89e47adc93cb13f94447450e2 100644
index b60820ef0cc62c27a8bab127218d625012153791..04cdd58ed4426af802f2868310140a8a33ec092b 100644
--- a/browser/modules/URILoadingHelper.sys.mjs
+++ b/browser/modules/URILoadingHelper.sys.mjs
@@ -228,6 +228,7 @@ function openInWindow(url, params, sourceWindow) {
@@ -231,6 +231,7 @@ function openInWindow(url, params, sourceWindow) {
features,
sa
);
@@ -10,7 +10,7 @@ index bd2e54e914b171df9b8bcc7dcbc2388e9641f6c6..8b3cb6542bea3fb89e47adc93cb13f94
}
function openInCurrentTab(targetBrowser, url, uriObj, params) {
@@ -545,7 +546,7 @@ export const URILoadingHelper = {
@@ -548,7 +549,7 @@ export const URILoadingHelper = {
// page. If a load request bounces off for the currently selected tab,
// we'll open a new tab instead.
let tab = w.gBrowser.getTabForBrowser(targetBrowser);
@@ -19,7 +19,7 @@ index bd2e54e914b171df9b8bcc7dcbc2388e9641f6c6..8b3cb6542bea3fb89e47adc93cb13f94
where = "tab";
targetBrowser = null;
} else if (
@@ -978,7 +979,7 @@ export const URILoadingHelper = {
@@ -981,7 +982,7 @@ export const URILoadingHelper = {
ignoreQueryString || replaceQueryString,
ignoreFragmentWhenComparing
);
@@ -28,9 +28,9 @@ index bd2e54e914b171df9b8bcc7dcbc2388e9641f6c6..8b3cb6542bea3fb89e47adc93cb13f94
for (let i = 0; i < browsers.length; i++) {
let browser = browsers[i];
let browserCompare = cleanURL(
@@ -1034,7 +1035,7 @@ export const URILoadingHelper = {
@@ -1037,7 +1038,7 @@ export const URILoadingHelper = {
}
aSplitView.ownerGlobal.focus();
aSplitView.documentGlobal.focus();
} else {
- aWindow.gBrowser.tabContainer.selectedIndex = i;
+ aWindow.gZenWorkspaces.switchIfNeeded(browser);

View File

@@ -1,8 +1,8 @@
diff --git a/browser/themes/shared/tabbrowser/tabs.css b/browser/themes/shared/tabbrowser/tabs.css
index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22c000e105 100644
index b70af17781a4128593e3c092cf0f6aec81ab5f9a..1c11c2bf9dcde9d468959e9115a48cf272870987 100644
--- a/browser/themes/shared/tabbrowser/tabs.css
+++ b/browser/themes/shared/tabbrowser/tabs.css
@@ -25,7 +25,7 @@
@@ -34,7 +34,7 @@
--tab-group-line-thickness: 2px;
--tab-group-line-toolbar-border-distance: 1px;
/* Collapsed tabs should be square, so set width to match the min height */
@@ -11,15 +11,15 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
--tab-collapsed-width: calc(var(--tab-collapsed-background-width) + 2 * var(--tab-inner-inline-margin));
--tab-pinned-min-width-expanded: calc(var(--tab-pinned-expanded-background-width) + 2 * var(--tab-pinned-margin-inline-expanded));
--tab-note-icon-end-margin: var(--dimension-4);
@@ -276,7 +276,6 @@ tab-split-view-wrapper[dragtarget] {
@@ -285,7 +285,6 @@ tab-split-view-wrapper[dragtarget] {
}
:root:not([uidensity="compact"], [sidebar-expand-on-hover]) &[pinned] {
- padding: 0 10px;
- padding: 0 calc((var(--tab-min-height) - var(--icon-size)) / 2);
}
&:is([selected], [multiselected]) {
@@ -290,6 +289,7 @@ tab-split-view-wrapper[dragtarget] {
@@ -299,6 +298,7 @@ tab-split-view-wrapper[dragtarget] {
border-radius: inherit;
position: relative;
overflow: hidden;
@@ -27,7 +27,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
&::before {
position: absolute;
@@ -489,10 +489,6 @@ tab-split-view-wrapper[dragtarget] {
@@ -498,10 +498,6 @@ tab-split-view-wrapper[dragtarget] {
/* stylelint-disable-next-line media-query-no-invalid */
@media -moz-pref("browser.tabs.fadeOutUnloadedTabs") {
&[pending] {
@@ -38,7 +38,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
opacity: 0.5;
/* Fade the favicon out */
transition-property: filter, opacity;
@@ -509,10 +505,6 @@ tab-split-view-wrapper[dragtarget] {
@@ -518,10 +514,6 @@ tab-split-view-wrapper[dragtarget] {
/* stylelint-disable-next-line media-query-no-invalid */
@media -moz-pref("browser.tabs.fadeOutExplicitlyUnloadedTabs") {
&[pending][discarded] {
@@ -49,8 +49,8 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
opacity: 0.5;
/* Fade the favicon out */
transition-property: filter, opacity;
@@ -581,7 +573,7 @@ tab-split-view-wrapper[dragtarget] {
z-index: 1; /* Overlay tab title */
@@ -596,7 +588,7 @@ tab-split-view-wrapper[dragtarget] {
}
#tabbrowser-tabs[orient="vertical"] & {
- top: 7px;
@@ -58,7 +58,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
}
&[crashed] {
@@ -589,7 +581,7 @@ tab-split-view-wrapper[dragtarget] {
@@ -604,7 +596,7 @@ tab-split-view-wrapper[dragtarget] {
}
#tabbrowser-tabs[orient="vertical"]:not([expanded]) &:not([crashed]),
@@ -67,7 +67,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
&[soundplaying] {
list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio-playing-small.svg");
}
@@ -644,7 +636,7 @@ tab-split-view-wrapper[dragtarget] {
@@ -661,7 +653,7 @@ tab-split-view-wrapper[dragtarget] {
}
}
@@ -76,7 +76,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
&[crashed] {
display: revert;
}
@@ -810,7 +802,7 @@ tab-split-view-wrapper[dragtarget] {
@@ -829,7 +821,7 @@ tab-split-view-wrapper[dragtarget] {
has not been added to root. There are certain scenarios when that attribute is temporarily
removed from root such as when toggling the sidebar to expand with the toolbar button. */
#tabbrowser-tabs[orient="horizontal"] &:not([pinned]):not([crashed]),
@@ -85,7 +85,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
&:is([soundplaying], [muted], [activemedia-blocked]) {
display: flex;
}
@@ -1026,7 +1018,6 @@ tab-split-view-wrapper[dragtarget] {
@@ -1053,7 +1045,6 @@ tab-split-view-wrapper[dragtarget] {
.tabbrowser-tab:is([image], [pinned]) > .tab-stack > .tab-content[attention]:not([selected]),
.tabbrowser-tab > .tab-stack > .tab-content[pinned][titlechanged]:not([selected]),
#tabbrowser-tabs[orient="vertical"] .tabbrowser-tab > .tab-stack > .tab-content[titlechanged]:not([selected]) {
@@ -93,7 +93,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
background-position: center bottom 6.5px;
background-size: 4px 4px;
background-repeat: no-repeat;
@@ -1635,7 +1626,7 @@ tab-group {
@@ -1813,7 +1804,7 @@ tab-group {
}
#tabbrowser-tabs[orient="vertical"][expanded] {
@@ -102,7 +102,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
&[movingtab][movingtab-addToGroup]:not([movingtab-group], [movingtab-ungroup]) .tabbrowser-tab:is(:active, [multiselected]) {
margin-inline-start: var(--space-medium);
}
@@ -2128,7 +2119,7 @@ tab-group {
@@ -2378,7 +2369,7 @@ tab-group {
}
}
@@ -111,7 +111,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
#vertical-tabs-newtab-button {
appearance: none;
min-height: var(--tab-min-height);
@@ -2139,7 +2130,7 @@ tab-group {
@@ -2389,7 +2380,7 @@ tab-group {
margin-inline: var(--tab-inner-inline-margin);
#tabbrowser-tabs[orient="vertical"]:not([expanded]) & > .toolbarbutton-text {
@@ -120,7 +120,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
}
&:hover {
@@ -2163,7 +2154,7 @@ tab-group {
@@ -2413,7 +2404,7 @@ tab-group {
* flex container. #tabs-newtab-button is a child of the arrowscrollbox where
* we don't want a gap (between tabs), so we have to add some margin.
*/
@@ -129,7 +129,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
margin-block: var(--tab-block-margin);
}
@@ -2351,7 +2342,6 @@ tab-group {
@@ -2610,7 +2601,6 @@ tab-group {
&:not([expanded]) {
.tabbrowser-tab[pinned] {
@@ -137,7 +137,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
}
.tab-background {
@@ -2391,8 +2381,8 @@ tab-group {
@@ -2651,8 +2641,8 @@ tab-group {
display: block;
position: absolute;
inset: auto;
@@ -148,7 +148,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
&:-moz-window-inactive {
background-image:
@@ -2480,9 +2470,6 @@ tab-group {
@@ -2753,9 +2743,6 @@ tab-group {
~ #tabbrowser-tabs[orient="horizontal"]::before {
display: flex;
content: "";
@@ -158,7 +158,7 @@ index 2ce8b135dcf087a2e2cb75c3417be8c9ba4178e6..3c297614afd323e210ebf0018d4aca22
}
}
@@ -2515,7 +2502,6 @@ toolbar:not(#TabsToolbar) #firefox-view-button {
@@ -2788,7 +2775,6 @@ toolbar:not(#TabsToolbar) #firefox-view-button {
list-style-image: url(chrome://global/skin/icons/plus.svg);
}

View File

@@ -1,59 +1,59 @@
diff --git a/browser/themes/shared/toolbarbuttons.css b/browser/themes/shared/toolbarbuttons.css
index 829501008d7b6fd6bddf899f3cf599a68ff216a0..cbdc770d56c4053d0b9afc13322f072c3376eb30 100644
index 94b1a2a841d8fd47a491616d52e5bf544f0c0bf9..9e98266b98c6b66fed26fec12fa3391fc5fcc79b 100644
--- a/browser/themes/shared/toolbarbuttons.css
+++ b/browser/themes/shared/toolbarbuttons.css
@@ -13,20 +13,6 @@
--toolbarbutton-inner-padding: var(--toolbarbutton-inner-padding-touch);
--toolbarbutton-padding-inner: var(--toolbarbutton-padding-inner-touch);
--bookmark-block-padding: 7px;
}
- @media (width <= 900px) {
- --toolbarbutton-outer-padding: var(--toolbarbutton-outer-padding-narrow);
- --toolbarbutton-padding-outer: var(--toolbarbutton-padding-outer-narrow);
- }
- @media (width <= 800px) {
- --toolbarbutton-inner-padding: var(--toolbarbutton-inner-padding-narrow);
- --toolbarbutton-padding-inner: var(--toolbarbutton-padding-inner-narrow);
- &:where([uidensity="touch"]) {
- --toolbarbutton-inner-padding: var(--toolbarbutton-inner-padding-touch-narrow);
- --toolbarbutton-padding-inner: var(--toolbarbutton-padding-inner-touch-narrow);
- }
- }
- /* 700px is just above half of the popular 1366px screen width, so two browser
- windows put next to each other will be below this threshold. */
- @media (width <= 700px) {
- --toolbarbutton-inner-padding: var(--toolbarbutton-inner-padding-compact);
- --toolbarbutton-padding-inner: var(--toolbarbutton-padding-inner-compact);
- }
&:where([uidensity="compact"]) {
--toolbarbutton-inner-padding: var(--toolbarbutton-inner-padding-compact);
--toolbarbutton-padding-inner: var(--toolbarbutton-padding-inner-compact);
--bookmark-block-padding: 1px;
@@ -123,9 +109,7 @@
#TabsToolbar {
/* Override the inner padding to ensure the dimensions match the tabs, but also making sure
different types of buttons (combined-buttons-dropmarker or text) still look correct. */
- @media (width > 900px) {
--toolbarbutton-inner-padding: calc((var(--tab-min-height) - 16px) / 2);
--toolbarbutton-padding-inner: calc((var(--tab-min-height) - 16px) / 2);
- }
}
/* Primary toolbar buttons */
@@ -204,8 +188,8 @@ toolbar .toolbarbutton-1 {
@@ -205,8 +189,8 @@ toolbar .toolbarbutton-1 {
> .toolbarbutton-icon {
/* horizontal padding + actual icon width */
- width: calc(2 * var(--toolbarbutton-inner-padding) + 16px);
- height: calc(2 * var(--toolbarbutton-inner-padding) + 16px);
+ width: calc(2 * var(--toolbarbutton-inner-padding) + var(--zen-toolbar-button-size, 16px));
+ height: calc(2 * var(--toolbarbutton-inner-padding) + var(--zen-toolbar-button-size, 16px));
- width: calc(2 * var(--toolbarbutton-padding-inner) + 16px);
- height: calc(2 * var(--toolbarbutton-padding-inner) + 16px);
+ width: calc(2 * var(--toolbarbutton-padding-inner) + var(--zen-toolbar-button-size, 16px));
+ height: calc(2 * var(--toolbarbutton-padding-inner) + var(--zen-toolbar-button-size, 16px));
}
> .toolbarbutton-text {
@@ -215,7 +199,7 @@ toolbar .toolbarbutton-1 {
@@ -216,7 +200,7 @@ toolbar .toolbarbutton-1 {
* height as the button icons and the same vertical padding, but as a minimum,
* because otherwise an increase in text sizes would break things.
*/
- min-height: calc(16px + 2 * var(--toolbarbutton-inner-padding));
+ min-height: calc(var(--zen-toolbar-button-size, 16px) + 2 * var(--toolbarbutton-inner-padding));
- min-height: calc(16px + 2 * var(--toolbarbutton-padding-inner));
+ min-height: calc(var(--zen-toolbar-button-size, 16px) + 2 * var(--toolbarbutton-padding-inner));
@media (-moz-platform: macos) {
padding-top: calc(var(--toolbarbutton-inner-padding) + 1px);
@@ -325,7 +309,7 @@ toolbar .toolbaritem-combined-buttons {
padding-top: calc(var(--toolbarbutton-padding-inner) + 1px);
@@ -326,7 +310,7 @@ toolbar .toolbaritem-combined-buttons {
#nav-bar-overflow-button {
list-style-image: url("chrome://global/skin/icons/chevron.svg");
@@ -62,7 +62,7 @@ index 829501008d7b6fd6bddf899f3cf599a68ff216a0..cbdc770d56c4053d0b9afc13322f072c
display: none;
}
@@ -535,7 +519,7 @@ toolbarbutton.bookmark-item:not(.subviewbutton) {
@@ -536,7 +520,7 @@ toolbarbutton.bookmark-item:not(.subviewbutton) {
*/
align-items: stretch;
> .toolbarbutton-icon {

View File

@@ -1,8 +1,8 @@
diff --git a/browser/themes/shared/urlbar-searchbar.css b/browser/themes/shared/urlbar-searchbar.css
index 3f46c918e125f9531a536a09358c980b2c923864..cba6f00318ce5dc7b6717b6c9afd2ee916715f8f 100644
index cbd074b9bacfbf7cc82a67ad586ebc31c4d85970..993c61ba389cb9d912b2cebee9d71bec772e3a7d 100644
--- a/browser/themes/shared/urlbar-searchbar.css
+++ b/browser/themes/shared/urlbar-searchbar.css
@@ -11,7 +11,7 @@
@@ -12,7 +12,7 @@
/* Usually we wouldn't need snapping border widths manually, but we use this
* for other layout calculations too */
--urlbar-container-border-width: max(env(hairline), round(down, 1px, env(hairline)));
@@ -11,7 +11,7 @@ index 3f46c918e125f9531a536a09358c980b2c923864..cba6f00318ce5dc7b6717b6c9afd2ee9
--urlbar-container-inset: calc(var(--urlbar-container-border-width) + var(--urlbar-container-padding));
@media (max-width: 770px) {
@@ -54,7 +54,7 @@ toolbar[inactive="true"] .urlbar,
@@ -55,7 +55,7 @@ toolbar[inactive="true"] .urlbar,
.urlbar:not([usertyping]) > .urlbar-input-container > .urlbar-go-button,
.urlbar:not(#searchbar-new, [focused]) > .urlbar-input-container > .urlbar-go-button,
#urlbar-revert-button-container {
@@ -20,7 +20,7 @@ index 3f46c918e125f9531a536a09358c980b2c923864..cba6f00318ce5dc7b6717b6c9afd2ee9
}
/* Document Picture-in-Picture API window */
@@ -201,6 +201,10 @@ toolbar[inactive="true"] .urlbar,
@@ -205,6 +205,10 @@ toolbar[inactive="true"] .urlbar,
mask-image: linear-gradient(to right, transparent var(--urlbar-scheme-size), black calc(var(--urlbar-scheme-size) + 3ch));
}
@@ -31,18 +31,18 @@ index 3f46c918e125f9531a536a09358c980b2c923864..cba6f00318ce5dc7b6717b6c9afd2ee9
/* stylelint-disable-next-line media-query-no-invalid */
@media -moz-pref("browser.nova.enabled") {
&::selection {
@@ -343,10 +347,14 @@ toolbar[inactive="true"] .urlbar,
@@ -429,10 +433,14 @@ toolbar[inactive="true"] .urlbar,
.urlbar[breakout][breakout-extend] {
height: auto;
+ align-items: center;
+ :root:not([zen-single-toolbar='true']) & {
margin-left: calc(-1 * var(--urlbar-margin-inline));
+ }
width: calc(var(--urlbar-width) + 2 * var(--urlbar-margin-inline));
> .urlbar-input-container {
.urlbar[breakout][breakout-extend] {
height: auto;
+ align-items: center;
height: var(--urlbar-container-height);
padding-block: calc((var(--urlbar-container-height) - var(--urlbar-height)) / 2 + var(--urlbar-container-padding));
padding-inline: calc(var(--urlbar-margin-inline) + var(--urlbar-container-padding));
+ :root:not([zen-single-toolbar='true']) & {
margin-left: calc(-1 * var(--urlbar-margin-inline));
+ }
width: calc(var(--urlbar-width) + 2 * var(--urlbar-margin-inline));
> .urlbar-input-container {
+ align-items: center;
height: var(--urlbar-container-height);
padding-block: calc((var(--urlbar-container-height) - var(--urlbar-height)) / 2 + var(--urlbar-container-padding));
padding-inline: calc(var(--urlbar-margin-inline) + var(--urlbar-container-padding));

View File

@@ -1,5 +1,5 @@
diff --git a/browser/themes/shared/urlbar/view-proton.css b/browser/themes/shared/urlbar/view-proton.css
index 9e041b67988f590bdbea48514937b1fa25c9785c..05507782b91858dff3e181843314af7956528ba9 100644
index 0b10c077a555e5d0fc488a3bb1b1b920f433204c..38e9d14e9838f2b8de6f654ff4e0700bb65506f0 100644
--- a/browser/themes/shared/urlbar/view-proton.css
+++ b/browser/themes/shared/urlbar/view-proton.css
@@ -14,7 +14,7 @@
@@ -9,10 +9,10 @@ index 9e041b67988f590bdbea48514937b1fa25c9785c..05507782b91858dff3e181843314af79
- --urlbarView-results-padding: 7px;
+ --urlbarView-results-padding: 8px;
--urlbarView-row-gutter: var(--space-xxsmall);
--urlbarView-item-inline-padding: var(--urlbar-icon-padding);
--urlbarView-item-block-padding: 6px;
@@ -168,7 +168,6 @@
min-height: 32px;
--urlbarView-row-padding-inline: var(--urlbar-icon-padding);
--urlbarView-row-padding-block: 6px;
@@ -174,7 +174,6 @@
min-height: var(--urlbarView-row-min-height);
}
:root[uidensity="touch"] & {
- padding-block: 11px;

View File

@@ -1,12 +1,12 @@
diff --git a/devtools/startup/DevToolsStartup.sys.mjs b/devtools/startup/DevToolsStartup.sys.mjs
index d604d0e00c623026928d72b1bcb1ce82e6bb6d4a..e3341c9ffc6db9b4bf360445ea031fc558e6076b 100644
index ab008a13b4a6a31b18d5587e93e1ff589693cdac..946d1c70600fcfda5452d130dd1924c92d502562 100644
--- a/devtools/startup/DevToolsStartup.sys.mjs
+++ b/devtools/startup/DevToolsStartup.sys.mjs
@@ -836,6 +836,9 @@ export class DevToolsStartup {
// account (see bug 832984).
const mainKeyset = doc.getElementById("mainKeyset");
mainKeyset.parentNode.insertBefore(keyset, mainKeyset);
+ mainKeyset.ownerGlobal.setTimeout(() => {
+ mainKeyset.documentGlobal.setTimeout(() => {
+ window.dispatchEvent(new window.Event("zen-devtools-keyset-added"));
+ }, 0);
}

View File

@@ -1,5 +1,5 @@
diff --git a/dom/media/mediacontrol/MediaController.h b/dom/media/mediacontrol/MediaController.h
index ea05df396bcaa8f5e236105585c0a177496c8bd9..e064f279383004bdbdb030ecb23289a893c11a8c 100644
index 101c952b23cb67b9fe911eefa3f78a88f5b6378c..e2c3d511f505bd9739bba7315f4f248effb77400 100644
--- a/dom/media/mediacontrol/MediaController.h
+++ b/dom/media/mediacontrol/MediaController.h
@@ -91,6 +91,7 @@ class MediaController final : public DOMEventTargetHelper,
@@ -9,4 +9,4 @@ index ea05df396bcaa8f5e236105585c0a177496c8bd9..e064f279383004bdbdb030ecb23289a8
+ void GetPositionState(MediaControllerPositionState& aPositionState, ErrorResult& aRv);
IMPL_EVENT_HANDLER(activated);
IMPL_EVENT_HANDLER(deactivated);
IMPL_EVENT_HANDLER(metadatachange);
IMPL_EVENT_HANDLER(audiblechange);

View File

@@ -64,7 +64,7 @@ diff --git a/gfx/wr/webrender/src/device/gl.rs b/gfx/wr/webrender/src/device/gl.
diff --git a/gfx/wr/webrender/src/renderer/init.rs b/gfx/wr/webrender/src/renderer/init.rs
--- a/gfx/wr/webrender/src/renderer/init.rs
+++ b/gfx/wr/webrender/src/renderer/init.rs
@@ -204,10 +204,12 @@
@@ -204,6 +204,8 @@
pub low_quality_pinch_zoom: bool,
pub max_shared_surface_size: i32,
/// If true, open a debug socket to listen for remote debugger.
@@ -72,19 +72,14 @@ diff --git a/gfx/wr/webrender/src/renderer/init.rs b/gfx/wr/webrender/src/render
pub enable_debugger: bool,
+ /// See explanation of `gfx.webrender.opaque-backdrop-fallback`.
+ pub opaque_backdrop_fallback: bool,
/// Use the new quad primitive path for box-shadow blur rendering.
pub use_quad_box_shadow: bool,
}
@@ -277,10 +279,11 @@
@@ -277,9 +279,10 @@
enable_instancing: true,
reject_software_rasterizer: false,
low_quality_pinch_zoom: false,
max_shared_surface_size: 2048,
enable_debugger: true,
+ opaque_backdrop_fallback: false,
use_quad_box_shadow: true,
}
}
}

View File

@@ -1,104 +0,0 @@
diff --git a/gfx/wr/webrender/src/clip.rs b/gfx/wr/webrender/src/clip.rs
--- a/gfx/wr/webrender/src/clip.rs
+++ b/gfx/wr/webrender/src/clip.rs
@@ -97,11 +97,11 @@
use api::units::*;
use crate::image_tiling::{self, Repetition};
use crate::border::{ensure_no_corner_overlap, BorderRadiusAu};
use crate::box_shadow::{BLUR_SAMPLE_SCALE, BoxShadowClipSource, BoxShadowCacheKey};
use crate::renderer::GpuBufferBuilderF;
-use crate::spatial_tree::{SpatialTree, SpatialNodeIndex};
+use crate::spatial_tree::{SceneSpatialTree, SpatialTree, SpatialNodeIndex};
use crate::ellipse::Ellipse;
use crate::gpu_types::{BoxShadowStretchMode};
use crate::intern;
use crate::internal_types::{FastHashMap, FastHashSet, LayoutPrimitiveInfo};
use crate::prim_store::{VisibleMaskImageTile};
@@ -745,10 +745,56 @@
) -> bool {
let clip_chain_index = self.clip_chain_map[&clip_chain_id];
self.has_complex_clips_impl(clip_chain_index, interners)
}
+ /// Check if all complex clips in a clip chain are fixed-position rounded
+ /// rectangles (in Clip mode). When true, the intermediate surface for a
+ /// root-level stacking context can be skipped because the clips will be
+ /// promoted to compositor clips on the tile cache slices.
+ pub fn clip_chain_complex_clips_are_promotable(
+ &self,
+ clip_chain_id: ClipChainId,
+ interners: &Interners,
+ spatial_tree: &SceneSpatialTree,
+ ) -> bool {
+ let clip_chain_index = self.clip_chain_map[&clip_chain_id];
+ self.complex_clips_are_promotable_impl(clip_chain_index, interners, spatial_tree)
+ }
+
+ fn complex_clips_are_promotable_impl(
+ &self,
+ clip_chain_index: usize,
+ interners: &Interners,
+ spatial_tree: &SceneSpatialTree,
+ ) -> bool {
+ let mut index = clip_chain_index;
+
+ loop {
+ let clip_chain = &self.clip_chains[index];
+
+ for clip_entry in &clip_chain.clips {
+ let clip_info = &interners.clip[clip_entry.handle];
+
+ match clip_info.key.kind {
+ ClipItemKeyKind::Rectangle(_, ClipMode::Clip) => {}
+ ClipItemKeyKind::RoundedRectangle(_, _, ClipMode::Clip) => {
+ if !spatial_tree.is_root_coord_system(clip_entry.spatial_node_index) {
+ return false;
+ }
+ }
+ _ => return false,
+ }
+ }
+
+ match clip_chain.parent {
+ Some(parent) => index = parent,
+ None => return true,
+ }
+ }
+ }
+
/// Check if a clip-node has complex (non-rectangular) clips
pub fn clip_node_has_complex_clips(
&self,
clip_node_id: ClipNodeId,
interners: &Interners,
diff --git a/gfx/wr/webrender/src/scene_building.rs b/gfx/wr/webrender/src/scene_building.rs
--- a/gfx/wr/webrender/src/scene_building.rs
+++ b/gfx/wr/webrender/src/scene_building.rs
@@ -2369,11 +2369,26 @@
// If this stacking context has any complex clips, we need to draw it
// to an off-screen surface.
if let Some(clip_chain_id) = clip_chain_id {
if self.clip_tree_builder.clip_chain_has_complex_clips(clip_chain_id, &self.interners) {
- blit_reason |= BlitReason::CLIP;
+ // At the root level, if all complex clips are fixed-position
+ // rounded rectangles, we can skip the intermediate surface.
+ // The clips will be promoted to compositor clips on the tile
+ // cache slices, which applies them once to the composited
+ // surface — equivalent to the intermediate surface approach.
+ // This allows tile cache barriers to fire normally, enabling
+ // proper picture caching with multiple slices.
+ if !self.sc_stack.is_empty() ||
+ !self.clip_tree_builder.clip_chain_complex_clips_are_promotable(
+ clip_chain_id,
+ &self.interners,
+ &self.spatial_tree,
+ )
+ {
+ blit_reason |= BlitReason::CLIP;
+ }
}
}
// Check if we know this stacking context is redundant (doesn't need a surface)
// The check for blend-container redundancy is more involved so it's handled below.

View File

@@ -1,641 +0,0 @@
diff --git a/browser/base/content/main-popupset.inc.xhtml b/browser/base/content/main-popupset.inc.xhtml
--- a/browser/base/content/main-popupset.inc.xhtml
+++ b/browser/base/content/main-popupset.inc.xhtml
@@ -192,10 +192,11 @@
<!-- Starting point for selection actions -->
<panel class="panel-no-padding"
id="selection-shortcut-action-panel"
noautofocus="true"
consumeoutsideclicks="never"
+ nonnative=""
type="arrow">
<hbox class="panel-subview-body">
<html:moz-button id="ai-action-button"/>
</hbox>
</panel>
@@ -203,10 +204,11 @@
<!-- Shortcut options for Gen AI action -->
<panel class="panel-no-padding"
id="chat-shortcuts-options-panel"
noautofocus="true"
+ nonnative=""
type="arrow">
<vbox class="panel-subview-body"/>
</panel>
<html:template id="screenshotsPagePanelTemplate">
@@ -610,10 +612,11 @@
type="arrow"
orient="vertical"
noautofocus="true"
norolluponanchor="true"
consumeoutsideclicks="false"
+ nonnative=""
role="tooltip">
<html:div class="tab-preview-content-interactive"></html:div>
<html:div class="tab-preview-content-main">
<html:div class="tab-preview-thumbnail-container"></html:div>
<html:div class="tab-preview-text-container">
diff --git a/browser/components/asrouter/modules/FeatureCallout.sys.mjs b/browser/components/asrouter/modules/FeatureCallout.sys.mjs
--- a/browser/components/asrouter/modules/FeatureCallout.sys.mjs
+++ b/browser/components/asrouter/modules/FeatureCallout.sys.mjs
@@ -1054,10 +1054,11 @@
noautofocus="true"
flip="slide"
type="arrow"
consumeoutsideclicks="never"
norolluponanchor="true"
+ nonnative=""
position="${panel_position.panel_position_string}"
${hide_arrow ? "" : 'show-arrow=""'}
${autohide ? "" : 'noautohide="true"'}
${ignorekeys ? 'ignorekeys="true"' : ""}
${no_open_on_anchor ? 'no-open-on-anchor=""' : ""}
diff --git a/browser/components/customizableui/content/panelUI.inc.xhtml b/browser/components/customizableui/content/panelUI.inc.xhtml
--- a/browser/components/customizableui/content/panelUI.inc.xhtml
+++ b/browser/components/customizableui/content/panelUI.inc.xhtml
@@ -276,10 +276,11 @@
role="group"
type="arrow"
hidden="true"
flip="slide"
position="bottomright topright"
+ hidepopovertail=""
noautofocus="true">
<panelmultiview id="appMenu-multiView" mainViewId="appMenu-mainView"
viewCacheId="appMenu-viewCache">
</panelmultiview>
</panel>
diff --git a/dom/xul/XULPopupElement.cpp b/dom/xul/XULPopupElement.cpp
--- a/dom/xul/XULPopupElement.cpp
+++ b/dom/xul/XULPopupElement.cpp
@@ -80,10 +80,15 @@
}
void XULPopupElement::OpenPopupAtScreen(int32_t aXPos, int32_t aYPos,
bool aIsContextMenu,
Event* aTriggerEvent) {
+ if (NodeInfo()->NameAtom() == nsGkAtoms::panel) {
+ // TODO(bug 2038354): Remove this and make the front-end set the attribute
+ // explicitly.
+ SetAttr(kNameSpaceID_None, nsGkAtoms::nonnative, u"true"_ns, true);
+ }
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
if (pm) {
pm->ShowPopupAtScreen(this, aXPos, aYPos, aIsContextMenu, aTriggerEvent);
}
}
@@ -93,10 +98,15 @@
int32_t aWidth, int32_t aHeight,
bool aIsContextMenu,
bool aAttributesOverride,
Event* aTriggerEvent) {
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
+ if (NodeInfo()->NameAtom() == nsGkAtoms::panel) {
+ // TODO(bug 2038354): Remove this and make the front-end set the attribute
+ // explicitly.
+ SetAttr(kNameSpaceID_None, nsGkAtoms::nonnative, u"true"_ns, true);
+ }
if (pm) {
pm->ShowPopupAtScreenRect(
this, aPosition, nsIntRect(aXPos, aYPos, aWidth, aHeight),
aIsContextMenu, aAttributesOverride, aTriggerEvent);
}
diff --git a/layout/xul/nsMenuPopupFrame.h b/layout/xul/nsMenuPopupFrame.h
--- a/layout/xul/nsMenuPopupFrame.h
+++ b/layout/xul/nsMenuPopupFrame.h
@@ -516,18 +516,10 @@
// Move the popup to the position specified in its |left| and |top|
// attributes.
void MoveToAttributePosition();
- // Returns true if the popup should try to remain at the same relative
- // location as the anchor while it is open. If the anchor becomes hidden
- // either directly or indirectly because a parent popup or other element
- // is no longer visible, or a parent deck page is changed, the popup hides
- // as well. The second variation also sets the anchor rectangle, relative to
- // the popup frame.
- bool ShouldFollowAnchor() const;
-
nsIFrame* GetAnchorFrame() const;
public:
/**
* Return whether the popup direction should be RTL.
@@ -536,10 +528,18 @@
*
* Return whether the popup direction should be RTL.
*/
bool IsDirectionRTL() const;
+ // Returns true if the popup should try to remain at the same relative
+ // location as the anchor while it is open. If the anchor becomes hidden
+ // either directly or indirectly because a parent popup or other element
+ // is no longer visible, or a parent deck page is changed, the popup hides
+ // as well. The second variation also sets the anchor rectangle, relative to
+ // the popup frame.
+ bool ShouldFollowAnchor() const;
+
bool ShouldFollowAnchor(nsRect& aRect);
// Returns parent menu widget for submenus that are in the same
// frame hierarchy, it's needed for Linux/Wayland which demands
// strict popup windows hierarchy.
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
--- a/modules/libpref/init/StaticPrefList.yaml
+++ b/modules/libpref/init/StaticPrefList.yaml
@@ -19840,10 +19840,19 @@
value: true
mirror: always
#ifdef XP_MACOSX
+# If true, use native NSPopover for arrow panel popups (type="arrow") on macOS
+# Someone like Zen browser will use this pref by default, so
+# please take this into account when you change the behavior of
+# native popover. Note: Only panels with type="arrow" will use NSPopover.
+- name: widget.macos.native-popovers
+ type: RelaxedAtomicBool
+ value: false
+ mirror: always
+
# Whether to shift by the menubar height on fullscreen mode.
# 0: never
# 1: always
# 2: auto (tries to detect when it is needed)
- name: widget.macos.shift-by-menubar-on-fullscreen
diff --git a/toolkit/themes/shared/global-shared.css b/toolkit/themes/shared/global-shared.css
--- a/toolkit/themes/shared/global-shared.css
+++ b/toolkit/themes/shared/global-shared.css
@@ -72,10 +72,22 @@
--menuitem-border-radius: var(--arrowpanel-menuitem-border-radius);
--menuitem-padding: var(--arrowpanel-menuitem-padding);
--menuitem-margin: var(--arrowpanel-menuitem-margin);
}
+/* stylelint-disable-next-line media-query-no-invalid */
+@media -moz-pref("widget.macos.native-popovers") and (-moz-platform: macos) {
+ panel:not([nonnative]) {
+ background-color: transparent;
+ --panel-background: transparent;
+ --panel-box-shadow: none;
+ --panel-border-color: transparent;
+ --panel-box-shadow-margin: 0px;
+ --panel-padding: 0px;
+ }
+}
+
/* Lightweight theme roots */
:root[lwtheme] {
body,
toolbar,
diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -132,23 +132,38 @@
// to create its "frame view".
+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask;
@end
-@interface PopupWindow : BaseWindow {
+@interface PopupWindow : BaseWindow <NSPopoverDelegate> {
@private
BOOL mIsContextMenu;
+
+ // NSPopover support for native appearance
+ NSPopover* mPopover;
+ NSViewController* mPopoverViewController;
+ BOOL mUsePopover;
}
- (id)initWithContentRect:(NSRect)contentRect
styleMask:(NSUInteger)styleMask
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)deferCreation;
- (BOOL)isContextMenu;
- (void)setIsContextMenu:(BOOL)flag;
- (BOOL)canBecomeMainWindow;
+// NSPopover support
+- (void)setAllowPopover;
+- (BOOL)usePopover;
+- (void)showPopoverRelativeToRect:(NSRect)positioningRect
+ ofView:(NSView*)positioningView
+ preferredEdge:(NSRectEdge)preferredEdge
+ hiddenAnchor:(BOOL)hiddenAnchor;
+- (void)closePopover;
+- (void)updatePopoverContent;
+
@end
@interface BorderlessWindow : BaseWindow {
}
@@ -200,10 +215,14 @@
typedef nsIWidget Inherited;
public:
nsCocoaWindow();
+ // Check if this window should use NSPopover for popup/menu display
+ bool ShouldUseNSPopover() const;
+ bool ShouldShowAsNSPopover() const;
+
[[nodiscard]] nsresult Create(nsIWidget* aParent, const DesktopIntRect& aRect,
const InitData&) override;
[[nodiscard]] nsresult Create(nsIWidget* aParent,
const LayoutDeviceIntRect& aRect,
diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -4,10 +4,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsCocoaWindow.h"
#include "nsArrayUtils.h"
+#include "nsMenuPopupFrame.h"
+#include "nsDeviceContext.h"
+#include "mozilla/dom/XULPopupElement.h"
#include "MOZDynamicCursor.h"
#include "nsIAppStartup.h"
#include "nsIDOMWindowUtils.h"
#include "nsILocalFileMac.h"
#include "CocoaCompositorWidget.h"
@@ -5088,10 +5091,15 @@
if (mWindowType == WindowType::Popup) {
SetPopupWindowLevel();
mWindow.backgroundColor = NSColor.clearColor;
mWindow.opaque = NO;
+ // Enable NSPopover for panel popup types when preference is enabled
+ if ([mWindow isKindOfClass:[PopupWindow class]] && ShouldUseNSPopover()) {
+ [(PopupWindow*)mWindow setAllowPopover];
+ }
+
// When multiple spaces are in use and the browser is assigned to a
// particular space, override the "Assign To" space and display popups on
// the active space. Does not work with multiple displays. See
// NeedsRecreateToReshow() for multi-display with multi-space workaround.
mWindow.collectionBehavior = mWindow.collectionBehavior |
@@ -5293,10 +5301,57 @@
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
bool nsCocoaWindow::IsRunningAppModal() { return [NSApp _isRunningAppModal]; }
+static NSRectEdge AlignmentPositionToNSRectEdge(int8_t aPosition) {
+ switch (aPosition) {
+ case POPUPPOSITION_BEFORESTART:
+ case POPUPPOSITION_BEFOREEND:
+ return NSRectEdgeMaxY;
+ case POPUPPOSITION_AFTERSTART:
+ case POPUPPOSITION_AFTEREND:
+ return NSRectEdgeMinY;
+ case POPUPPOSITION_STARTBEFORE:
+ case POPUPPOSITION_STARTAFTER:
+ return NSRectEdgeMaxX;
+ case POPUPPOSITION_ENDBEFORE:
+ case POPUPPOSITION_ENDAFTER:
+ return NSRectEdgeMinX;
+ default:
+ return NSRectEdgeMinY;
+ }
+}
+
+static void SyncPopoverBounds(NSPopover* aPopover,
+ nsMenuPopupFrame* aPopupFrame) {
+ if (!aPopover || !aPopover.shown || !aPopupFrame) {
+ return;
+ }
+ NSWindow* popoverWindow = aPopover.contentViewController.view.window;
+ if (!popoverWindow) {
+ return;
+ }
+
+ // Synchronize the popup frame's internal bounds with the actual bounds that
+ // macOS calculated for the popover.
+ NSView* contentView = popoverWindow.contentView;
+ NSRect contentFrame = [contentView convertRect:contentView.bounds toView:nil];
+ NSRect windowFrame = [popoverWindow convertRectToScreen:contentFrame];
+
+ CGFloat backingScale = popoverWindow.backingScaleFactor;
+ mozilla::LayoutDeviceIntRect devPixRect =
+ nsCocoaUtils::CocoaRectToGeckoRectDevPix(windowFrame, backingScale);
+
+ nsPresContext* presContext = aPopupFrame->PresContext();
+ mozilla::CSSIntPoint cssPos =
+ presContext->DevPixelsToIntCSSPixels(devPixRect.TopLeft());
+
+ aPopupFrame->MoveTo(mozilla::CSSPoint(cssPos.x, cssPos.y),
+ /* aUpdateAttrs */ false);
+}
+
// Hide or show this window
void nsCocoaWindow::Show(bool aState) {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
if (!mWindow) {
@@ -5357,10 +5412,53 @@
mWindow.contentView.needsDisplay = YES;
if (!nativeParentWindow || mPopupLevel != PopupLevel::Parent) {
[mWindow orderFront:nil];
}
NS_OBJC_END_TRY_IGNORE_BLOCK;
+ if (ShouldShowAsNSPopover() && nativeParentWindow) {
+ nsMenuPopupFrame* popupFrame = GetPopupFrame();
+ NSRectEdge preferredEdge =
+ AlignmentPositionToNSRectEdge(popupFrame->GetAlignmentPosition());
+ nsRect anchorRectAppUnits = popupFrame->GetUntransformedAnchorRect();
+ nsPresContext* pc = popupFrame->PresContext();
+ int32_t appUnitsPerDevPixel = pc->AppUnitsPerDevPixel();
+ mozilla::DesktopToLayoutDeviceScale desktopToLayoutScale =
+ pc->DeviceContext()->GetDesktopToDeviceScale();
+ mozilla::DesktopIntRect popupAnchorRectScaled =
+ mozilla::DesktopIntRect::RoundOut(
+ mozilla::LayoutDeviceRect::FromAppUnits(anchorRectAppUnits,
+ appUnitsPerDevPixel) /
+ desktopToLayoutScale);
+ // Taking the now correctly scaled anchor rect and turning it into a
+ // gecko rect this accounts for the y-axis inversion that cocoa needs,
+ // as the origin is in the bottom left. This rect is in screen space
+ NSRect cocoaScreenRect =
+ nsCocoaUtils::GeckoRectToCocoaRect(popupAnchorRectScaled);
+ // We take the screen space rect and convert it to window space
+ // coordinates, as NSPopover requires the coordinates to be in view
+ // space and inside the view. If the coordinates are outside our view,
+ // the popover will fail silently
+ NSRect windowRect =
+ [nativeParentWindow convertRectFromScreen:cocoaScreenRect];
+ NSView* parentView = [nativeParentWindow contentView];
+ // We take the window space rect and convert it to view space for the
+ // specific parent view
+ NSRect positioningRect = [parentView convertRect:windowRect
+ fromView:nil];
+ bool shouldHideAnchor =
+ popupFrame->PopupElement().GetBoolAttr(nsGkAtoms::hidepopovertail);
+ [(PopupWindow*)mWindow showPopoverRelativeToRect:positioningRect
+ ofView:parentView
+ preferredEdge:preferredEdge
+ hiddenAnchor:shouldHideAnchor];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wobjc-method-access"
+ SyncPopoverBounds([(PopupWindow*)mWindow popover], popupFrame);
+#pragma clang diagnostic pop
+ // Exit early here since the popover is now shown.
+ return;
+ }
// If our popup window is a non-native context menu, tell the OS (and
// other programs) that a menu has opened. This is how the OS knows to
// close other programs' context menus when ours open.
if ([mWindow isKindOfClass:[PopupWindow class]] &&
[(PopupWindow*)mWindow isContextMenu]) {
@@ -5430,11 +5528,15 @@
// unhook it here before ordering it out. When you order out the child
// of a window it hides the parent window.
if (mWindowType == WindowType::Popup && nativeParentWindow) {
[nativeParentWindow removeChildWindow:mWindow];
}
-
+ // Handle NSPopover hiding or traditional window hiding
+ if ([mWindow isKindOfClass:[PopupWindow class]] &&
+ [(PopupWindow*)mWindow usePopover]) {
+ [(PopupWindow*)mWindow closePopover];
+ }
[mWindow orderOut:nil];
// If our popup window is a non-native context menu, tell the OS (and
// other programs) that a menu has closed.
if ([mWindow isKindOfClass:[PopupWindow class]] &&
[(PopupWindow*)mWindow isContextMenu]) {
@@ -5481,10 +5583,28 @@
return false;
}
return nsIWidget::ShouldUseOffMainThreadCompositing();
}
+bool nsCocoaWindow::ShouldUseNSPopover() const {
+ // Use NSPopover for panel popups when the preference is enabled
+ // But not for detached popups - they should use traditional window logic
+ return mWindowType == WindowType::Popup && mPopupType == PopupType::Panel &&
+ mozilla::StaticPrefs::widget_macos_native_popovers();
+}
+
+bool nsCocoaWindow::ShouldShowAsNSPopover() const {
+ if (!ShouldUseNSPopover()) {
+ return false;
+ }
+ nsMenuPopupFrame* popupFrame = GetPopupFrame();
+ return [mWindow isKindOfClass:[PopupWindow class]] &&
+ [(PopupWindow*)mWindow usePopover] && popupFrame &&
+ popupFrame->ShouldFollowAnchor() &&
+ !popupFrame->PopupElement().GetBoolAttr(nsGkAtoms::nonnativepopover);
+}
+
TransparencyMode nsCocoaWindow::GetTransparencyMode() {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
return mWindow.isOpaque ? TransparencyMode::Opaque
: TransparencyMode::Transparent;
@@ -6442,10 +6562,22 @@
// We ignore aRepaint -- we have to call display:YES, otherwise the
// title bar doesn't immediately get repainted and is displayed in
// the wrong place, leading to a visual jump.
[mWindow setFrame:newFrame display:YES];
+ if (ShouldUseNSPopover() && [(PopupWindow*)mWindow usePopover]) {
+ [(PopupWindow*)mWindow updatePopoverContent];
+ // A popover won't resize by setting the frame
+ // as it's size is calculated based on the content size
+ // Therefore the content size has to be changed as well
+ NSSize contentSize = NSMakeSize(aWidth, aHeight);
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wobjc-method-access"
+ [[(PopupWindow*)mWindow popover] setContentSize:contentSize];
+ SyncPopoverBounds([(PopupWindow*)mWindow popover], GetPopupFrame());
+#pragma clang diagnostic pop
+ }
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
void nsCocoaWindow::Resize(const DesktopRect& aRect, bool aRepaint) {
@@ -8517,18 +8649,31 @@
backing:bufferingType
defer:deferCreation];
if (!self) {
return nil;
}
-
+ mPopover = nil;
+ mPopoverViewController = nil;
+ mUsePopover = NO;
mIsContextMenu = false;
return self;
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
}
+- (void)dealloc {
+ if (mPopover) {
+ ChildViewMouseTracker::OnDestroyWindow(
+ mPopover.contentViewController.view.window);
+ }
+
+ [mPopover release];
+ [mPopoverViewController release];
+ [super dealloc];
+}
+
// Override the private API _backdropBleedAmount. This determines how much the
// desktop wallpaper contributes to the vibrancy backdrop.
// Return 0 in order to match what the system does for sheet windows and
// _NSPopoverWindows.
- (CGFloat)_backdropBleedAmount {
@@ -8584,10 +8729,125 @@
- (void)setIsContextMenu:(BOOL)flag {
mIsContextMenu = flag;
}
+- (void)setAllowPopover {
+ mUsePopover = YES;
+
+ if (!mPopover) {
+ mPopover = [[NSPopover alloc] init];
+
+ // Use NSPopoverBehaviorApplicationDefined to prevent auto-closing
+ // when other popovers are opened, and to respect the disable_autohide
+ // preference
+ mPopover.behavior = NSPopoverBehaviorApplicationDefined;
+ mPopover.delegate = self;
+
+ // Create view controller that will contain our content view
+ mPopoverViewController = [[NSViewController alloc] init];
+
+ NSView* contentView = self.contentView;
+ if (contentView) {
+ // Ensure the content view is properly configured
+ [contentView
+ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+
+ mPopoverViewController.view = contentView;
+ mPopover.contentViewController = mPopoverViewController;
+
+ // Set popover size to match our window content size
+ NSRect contentRect = [contentView frame];
+ if (contentRect.size.width > 0 && contentRect.size.height > 0) {
+ [mPopover setContentSize:contentRect.size];
+ }
+ }
+ }
+}
+
+- (BOOL)usePopover {
+ return mUsePopover;
+}
+
+- (void)showPopoverRelativeToRect:(NSRect)positioningRect
+ ofView:(NSView*)positioningView
+ preferredEdge:(NSRectEdge)preferredEdge
+ hiddenAnchor:(BOOL)hiddenAnchor {
+ NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
+ if (!mPopover) {
+ return;
+ }
+
+ // Close existing popover if it's already shown
+ if (mPopover.shown) {
+ [mPopover close];
+ }
+
+ // Force content update before showing
+ [self updatePopoverContent];
+
+ if (mPopoverViewController.view) {
+ mPopover.behavior = NSPopoverBehaviorApplicationDefined;
+
+ // This is a hidden API that prevents the popover from showing its arrow
+ // pointing to the anchor.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wobjc-method-access"
+ [mPopover setShouldHideAnchor:hiddenAnchor];
+#pragma clang diagnostic pop
+
+ [mPopover showRelativeToRect:positioningRect
+ ofView:positioningView
+ preferredEdge:preferredEdge];
+ }
+
+ NSWindow* popoverWindow = mPopover.contentViewController.view.window;
+ [popoverWindow setAcceptsMouseMovedEvents:YES];
+
+ NS_OBJC_END_TRY_IGNORE_BLOCK;
+}
+
+- (void)closePopover {
+ NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
+
+ if (mPopover && mPopover.shown) {
+ [mPopover close];
+ }
+
+ NS_OBJC_END_TRY_IGNORE_BLOCK;
+}
+
+- (void)updatePopoverContent {
+ NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
+ if (!mPopover || !mPopoverViewController) {
+ return;
+ }
+
+ NSView* contentView = self.contentView;
+ if (!contentView) {
+ return;
+ }
+ // Ensure proper hit testing for hover events
+ [contentView setWantsLayer:YES];
+ [contentView setAcceptsTouchEvents:YES];
+
+ // Update the popover content view to match current window content
+ mPopoverViewController.view = contentView;
+
+ // Update popover size to match content
+ NSRect contentRect = [contentView frame];
+ if (contentRect.size.width > 0 && contentRect.size.height > 0) {
+ mPopover.contentSize = contentRect.size;
+ }
+
+ NS_OBJC_END_TRY_IGNORE_BLOCK;
+}
+
+- (NSPopover*)popover {
+ return mPopover;
+}
+
- (BOOL)canBecomeMainWindow {
// This is overridden because the default is 'yes' when a titlebar is present.
return NO;
}
diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py
--- a/xpcom/ds/StaticAtoms.py
+++ b/xpcom/ds/StaticAtoms.py
@@ -536,10 +536,11 @@
Atom("hgroup", "hgroup"),
Atom("hidden", "hidden"),
Atom("hidechrome", "hidechrome"),
Atom("hidecolumnpicker", "hidecolumnpicker"),
Atom("hidetitlebarseparator", "hidetitlebarseparator"),
+ Atom("hidepopovertail", "hidepopovertail"),
Atom("hide_popover", "hide-popover"),
Atom("high", "high"),
Atom("highest", "highest"),
Atom("horizontal", "horizontal"),
Atom("hover", "hover"),

View File

@@ -38,7 +38,7 @@ diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
return [mWindow isKindOfClass:[PopupWindow class]] &&
[(PopupWindow*)mWindow usePopover] && popupFrame &&
- popupFrame->ShouldFollowAnchor() &&
!popupFrame->PopupElement().GetBoolAttr(nsGkAtoms::nonnativepopover);
!popupFrame->PopupElement().GetBoolAttr(nsGkAtoms::nonnative);
}
TransparencyMode nsCocoaWindow::GetTransparencyMode() {

View File

@@ -1,251 +0,0 @@
diff --git a/dom/chrome-webidl/IOUtils.webidl b/dom/chrome-webidl/IOUtils.webidl
--- a/dom/chrome-webidl/IOUtils.webidl
+++ b/dom/chrome-webidl/IOUtils.webidl
@@ -93,23 +93,23 @@
* otherwise rejects with a DOMException.
*/
[NewObject]
Promise<unsigned long long> writeUTF8(DOMString path, UTF8String string, optional WriteOptions options = {});
/**
- * Attempts to serialize |value| into a JSON string and encode it as into a
- * UTF-8 string, then safely write the result to a file at |path|. Works
- * exactly like |write|.
+ * Attempts to serialize |value| into a JSON string and encode it as a UTF-8
+ * string, then safely write the result to a file at |path|. Works exactly
+ * like |write|.
*
* @param path An absolute file path
* @param value The value to be serialized.
* @param options Options for writing the file. The "append" mode is not supported.
*
* @return Resolves with the number of bytes successfully written to the file,
* otherwise rejects with a DOMException.
*/
[NewObject]
- Promise<unsigned long long> writeJSON(DOMString path, any value, optional WriteOptions options = {});
+ Promise<WriteJSONResult> writeJSON(DOMString path, any value, optional WriteJSONOptions options = {});
/**
* Moves the file from |sourcePath| to |destPath|, creating necessary parents.
* If |destPath| is a directory, then the source file will be moved into the
* destination directory.
*
@@ -566,10 +566,39 @@
* If true, compress the data with LZ4-encoding before writing to the file.
*/
boolean compress = false;
};
+/**
+ * Options to be passed to the |IOUtils.writeJSON| method.
+ */
+dictionary WriteJSONOptions: WriteOptions {
+ /**
+ * An optional length hint that will be used to pre-allocate the buffer that
+ * will hold the stringified JSON.
+ *
+ * This is the *length* and not the size (i.e., it is the number of UTF-16
+ * codepoints and not the number of bytes).
+ */
+ unsigned long long lengthHint = 0;
+};
+
+/**
+ * Information about a WriteJSON operation.
+ */
+dictionary WriteJSONResult {
+ /**
+ * The number of bytes written.
+ */
+ required unsigned long long size;
+
+ /**
+ * The length of the stringified JSON (in UTF-16 codepoints).
+ */
+ required unsigned long long jsonLength;
+};
+
/**
* Options to be passed to the |IOUtils.move| method.
*/
dictionary MoveOptions {
/**
diff --git a/xpcom/ioutils/IOUtils.h b/xpcom/ioutils/IOUtils.h
--- a/xpcom/ioutils/IOUtils.h
+++ b/xpcom/ioutils/IOUtils.h
@@ -92,11 +92,11 @@
const nsACString& aString, const dom::WriteOptions& aOptions,
ErrorResult& aError);
static already_AddRefed<dom::Promise> WriteJSON(
dom::GlobalObject& aGlobal, const nsAString& aPath,
- JS::Handle<JS::Value> aValue, const dom::WriteOptions& aOptions,
+ JS::Handle<JS::Value> aValue, const dom::WriteJSONOptions& aOptions,
ErrorResult& aError);
static already_AddRefed<dom::Promise> Move(dom::GlobalObject& aGlobal,
const nsAString& aSourcePath,
const nsAString& aDestPath,
@@ -734,13 +734,16 @@
RefPtr<nsIFile> mBackupFile;
RefPtr<nsIFile> mTmpFile;
dom::WriteMode mMode;
bool mFlush = false;
bool mCompress = false;
+ size_t mLengthHint = 0;
static Result<InternalWriteOpts, IOUtils::IOError> FromBinding(
const dom::WriteOptions& aOptions);
+ static Result<InternalWriteOpts, IOUtils::IOError> FromBinding(
+ const dom::WriteJSONOptions& aOptions);
};
/**
* Re-implements the file compression and decompression utilities found
* in toolkit/components/lz4/lz4.js
diff --git a/xpcom/ioutils/IOUtils.cpp b/xpcom/ioutils/IOUtils.cpp
--- a/xpcom/ioutils/IOUtils.cpp
+++ b/xpcom/ioutils/IOUtils.cpp
@@ -587,15 +587,21 @@
return WriteSync(file, AsBytes(Span(str)), opts);
});
});
}
+static bool AppendJSON(const char16_t* aBuf, uint32_t aLen, void* aStr) {
+ nsAString* str = static_cast<nsAString*>(aStr);
+
+ return str->Append(aBuf, aLen, fallible);
+}
+
/* static */
already_AddRefed<Promise> IOUtils::WriteJSON(GlobalObject& aGlobal,
const nsAString& aPath,
JS::Handle<JS::Value> aValue,
- const WriteOptions& aOptions,
+ const WriteJSONOptions& aOptions,
ErrorResult& aError) {
return WithPromiseAndState(
aGlobal, aError, [&](Promise* promise, auto& state) {
nsCOMPtr<nsIFile> file = new nsLocalFile();
REJECT_IF_INIT_PATH_FAILED(file, aPath, promise,
@@ -621,14 +627,15 @@
file->HumanReadablePath().get()));
return;
}
JSContext* cx = aGlobal.Context();
- JS::Rooted<JS::Value> rootedValue(cx, aValue);
+ JS::Rooted<JS::Value> value(cx, aValue);
nsString string;
- if (!nsContentUtils::StringifyJSON(cx, aValue, string,
- UndefinedIsNullStringLiteral)) {
+ if (!JS_StringifyWithLengthHint(cx, &value, nullptr,
+ JS::NullHandleValue, AppendJSON,
+ &string, opts.mLengthHint)) {
JS::Rooted<JS::Value> exn(cx, JS::UndefinedValue());
if (JS_GetPendingException(cx, &exn)) {
JS_ClearPendingException(cx);
promise->MaybeReject(exn);
} else {
@@ -637,22 +644,29 @@
"Could not serialize object to JSON"_ns));
}
return;
}
- DispatchAndResolve<uint32_t>(
+ DispatchAndResolve<dom::WriteJSONResult>(
state->mEventQueue, promise,
[file = std::move(file), string = std::move(string),
- opts = std::move(opts)]() -> Result<uint32_t, IOError> {
+ opts = std::move(opts)]() -> Result<WriteJSONResult, IOError> {
nsAutoCString utf8Str;
if (!CopyUTF16toUTF8(string, utf8Str, fallible)) {
return Err(IOError(
NS_ERROR_OUT_OF_MEMORY,
"Failed to write to `%s': could not allocate buffer",
file->HumanReadablePath().get()));
}
- return WriteSync(file, AsBytes(Span(utf8Str)), opts);
+
+ uint32_t size =
+ MOZ_TRY(WriteSync(file, AsBytes(Span(utf8Str)), opts));
+
+ dom::WriteJSONResult result;
+ result.mSize = size;
+ result.mJsonLength = static_cast<uint32_t>(string.Length());
+ return result;
});
});
}
/* static */
@@ -2838,10 +2852,20 @@
opts.mCompress = aOptions.mCompress;
return opts;
}
+Result<IOUtils::InternalWriteOpts, IOUtils::IOError>
+IOUtils::InternalWriteOpts::FromBinding(const WriteJSONOptions& aOptions) {
+ InternalWriteOpts opts =
+ MOZ_TRY(FromBinding(static_cast<const WriteOptions&>(aOptions)));
+
+ opts.mLengthHint = aOptions.mLengthHint;
+
+ return opts;
+}
+
/* static */
Result<IOUtils::JsBuffer, IOUtils::IOError> IOUtils::JsBuffer::Create(
IOUtils::BufferKind aBufferKind, size_t aCapacity) {
JsBuffer buffer(aBufferKind, aCapacity);
if (aCapacity != 0 && !buffer.mBuffer) {
diff --git a/xpcom/ioutils/tests/test_ioutils_read_write_json.html b/xpcom/ioutils/tests/test_ioutils_read_write_json.html
--- a/xpcom/ioutils/tests/test_ioutils_read_write_json.html
+++ b/xpcom/ioutils/tests/test_ioutils_read_write_json.html
@@ -140,10 +140,43 @@
);
await cleanup(filename);
});
+ add_task(async function test_writeJSON_return() {
+ const filename = PathUtils.join(PathUtils.tempDir, "test_ioutils_writeJSON_return.tmp");
+
+ const obj = { emoji: "☕️ ⚧️ 😀 🖖🏿 🤠 🏳️‍🌈 🥠 🏴‍☠️ 🪐" };
+
+ const expectedJson = JSON.stringify(obj);
+ const size = new TextEncoder().encode(expectedJson).byteLength;
+
+ {
+ const result = await IOUtils.writeJSON(filename, obj, { lengthHint: 0 });
+
+ is(await IOUtils.readUTF8(filename), expectedJson, "should have written expected JSON");
+
+ is(typeof result, "object", "writeJSON returns an object");
+ ok(result !== null, "writeJSON returns non-null");
+
+ ok(Object.hasOwn(result, "size"), "result has size property");
+ ok(Object.hasOwn(result, "jsonLength"), "result has jsonLength property");
+
+ is(result.size, size, "Should have written the expected number of bytes");
+ is(result.jsonLength, expectedJson.length, "Should have written the expected number of UTF-16 codepoints");
+ }
+
+ {
+ const result = await IOUtils.writeJSON(filename, obj, { lengthHint: expectedJson.length, compress: true });
+
+ isnot(result.size, size, "Should have written a different number of bytes due to compression");
+ is(result.jsonLength, expectedJson.length, "Should have written the same number of UTF-16 codepoints");
+ }
+
+ await cleanup(filename);
+ });
+
add_task(async function test_append_json() {
const filename = PathUtils.join(PathUtils.tempDir, "test_ioutils_append_json.tmp");
await IOUtils.writeJSON(filename, OBJECT);

View File

@@ -1,254 +0,0 @@
diff --git a/browser/components/sessionstore/SessionWriter.sys.mjs b/browser/components/sessionstore/SessionWriter.sys.mjs
--- a/browser/components/sessionstore/SessionWriter.sys.mjs
+++ b/browser/components/sessionstore/SessionWriter.sys.mjs
@@ -80,10 +80,14 @@
return await SessionWriterInternal.wipe();
} finally {
unlock();
}
},
+
+ get _jsonLengthHint() {
+ return SessionWriterInternal._lastJsonLength;
+ },
};
const SessionWriterInternal = {
// Path to the files used by the SessionWriter
Paths: null,
@@ -104,10 +108,14 @@
/**
* Number of old upgrade backups that are being kept
*/
maxUpgradeBackups: null,
+ // Estimated JSON string length from the previous write, used to pre-size
+ // the serialization buffer and avoid incremental reallocations.
+ _lastJsonLength: 0,
+
/**
* Initialize (or reinitialize) the writer.
*
* @param {string} origin Which of sessionstore.js or its backups
* was used. One of the `STATE_*` constants defined above.
@@ -201,48 +209,60 @@
}
}
let startWriteMs = Date.now();
let fileStat;
+ // Add 5% headroom to the hint so small growth between saves doesn't
+ // cause reallocs. The compressed-size-based estimate already has
+ // sufficient margin from the 4x multiplier.
+ let jsonLengthHint = Math.ceil(this._lastJsonLength * 1.05);
+
+ let uncompressedBytes;
if (options.isFinalWrite) {
// We are shutting down. At this stage, we know that
// $Paths.clean is either absent or corrupted. If it was
// originally present and valid, it has been moved to
// $Paths.cleanBackup a long time ago. We can therefore write
// with the guarantees that we erase no important data.
- await IOUtils.writeJSON(this.Paths.clean, state, {
+ uncompressedBytes = await IOUtils.writeJSON(this.Paths.clean, state, {
tmpPath: this.Paths.clean + ".tmp",
compress: true,
+ jsonLengthHint,
});
fileStat = await IOUtils.stat(this.Paths.clean);
} else if (this.state == STATE_RECOVERY) {
// At this stage, either $Paths.recovery was written >= 15
// seconds ago during this session or we have just started
// from $Paths.recovery left from the previous session. Either
// way, $Paths.recovery is good. We can move $Path.backup to
// $Path.recoveryBackup without erasing a good file with a bad
// file.
- await IOUtils.writeJSON(this.Paths.recovery, state, {
+ uncompressedBytes = await IOUtils.writeJSON(this.Paths.recovery, state, {
tmpPath: this.Paths.recovery + ".tmp",
backupFile: this.Paths.recoveryBackup,
compress: true,
+ jsonLengthHint,
});
fileStat = await IOUtils.stat(this.Paths.recovery);
} else {
// In other cases, either $Path.recovery is not necessary, or
// it doesn't exist or it has been corrupted. Regardless,
// don't backup $Path.recovery.
- await IOUtils.writeJSON(this.Paths.recovery, state, {
+ uncompressedBytes = await IOUtils.writeJSON(this.Paths.recovery, state, {
tmpPath: this.Paths.recovery + ".tmp",
compress: true,
+ jsonLengthHint,
});
fileStat = await IOUtils.stat(this.Paths.recovery);
}
telemetry.writeFileMs = Date.now() - startWriteMs;
telemetry.fileSizeBytes = fileStat.size;
+ // Use the actual pre-compression size from this write as the hint
+ // for the next write's buffer allocation.
+ this._lastJsonLength = uncompressedBytes;
lazy.sessionStoreLogger.debug(
`SessionWriter.write wrote ${telemetry.fileSizeBytes} bytes in ${telemetry.writeFileMs}ms`
);
} catch (ex) {
// Don't throw immediately
@@ -375,10 +395,11 @@
} catch (ex) {
exn = exn || ex;
}
this.state = STATE_EMPTY;
+ this._lastJsonLength = 0;
if (exn) {
throw exn;
}
return { result: true };
diff --git a/browser/components/sessionstore/test/unit/test_write_json_length_hint.js b/browser/components/sessionstore/test/unit/test_write_json_length_hint.js
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/unit/test_write_json_length_hint.js
@@ -0,0 +1,73 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { SessionWriter } = ChromeUtils.importESModule(
+ "resource:///modules/sessionstore/SessionWriter.sys.mjs"
+);
+
+const profd = do_get_profile();
+const { SessionFile } = ChromeUtils.importESModule(
+ "resource:///modules/sessionstore/SessionFile.sys.mjs"
+);
+
+const { updateAppInfo } = ChromeUtils.importESModule(
+ "resource://testing-common/AppInfo.sys.mjs"
+);
+updateAppInfo({
+ name: "SessionRestoreTest",
+ ID: "{230de50e-4cd1-11dc-8314-0800200c9a66}",
+ version: "1",
+ platformVersion: "",
+});
+
+add_setup(async function () {
+ let source = do_get_file("data/sessionstore_valid.js");
+ source.copyTo(profd, "sessionstore.js");
+ await writeCompressedFile(
+ SessionFile.Paths.clean.replace("jsonlz4", "js"),
+ SessionFile.Paths.clean
+ );
+ await SessionFile.read();
+});
+
+add_task(async function test_length_hint_updates_after_write() {
+ Assert.equal(
+ SessionWriter._jsonLengthHint,
+ 0,
+ "Length hint starts at 0"
+ );
+
+ await SessionFile.write({});
+
+ let hintAfterSmall = SessionWriter._jsonLengthHint;
+ Assert.equal(
+ hintAfterSmall,
+ JSON.stringify({}).length,
+ "Hint matches the uncompressed JSON byte length"
+ );
+
+ let largerState = await IOUtils.readJSON(
+ PathUtils.join(do_get_cwd().path, "data", "sessionstore_complete.json")
+ );
+ await SessionFile.write(largerState);
+
+ Assert.greater(
+ SessionWriter._jsonLengthHint,
+ hintAfterSmall,
+ "Hint grows after writing a larger state"
+ );
+});
+
+add_task(async function test_length_hint_resets_on_wipe() {
+ await SessionFile.write({ windows: [{ tabs: [{ entries: [] }] }] });
+ Assert.greater(SessionWriter._jsonLengthHint, 0, "Hint is nonzero");
+
+ await SessionFile.wipe();
+ Assert.equal(
+ SessionWriter._jsonLengthHint,
+ 0,
+ "Hint resets to 0 after wipe"
+ );
+});
diff --git a/browser/components/sessionstore/test/unit/xpcshell.toml b/browser/components/sessionstore/test/unit/xpcshell.toml
--- a/browser/components/sessionstore/test/unit/xpcshell.toml
+++ b/browser/components/sessionstore/test/unit/xpcshell.toml
@@ -39,5 +39,10 @@
skip-if = [
"condprof", # Bug 1769154
]
["test_startup_session_async.js"]
+
+["test_write_json_length_hint.js"]
+support-files = [
+ "data/sessionstore_complete.json",
+]
diff --git a/dom/chrome-webidl/IOUtils.webidl b/dom/chrome-webidl/IOUtils.webidl
--- a/dom/chrome-webidl/IOUtils.webidl
+++ b/dom/chrome-webidl/IOUtils.webidl
@@ -101,12 +101,12 @@
*
* @param path An absolute file path
* @param value The value to be serialized.
* @param options Options for writing the file. The "append" mode is not supported.
*
- * @return Resolves with the number of bytes successfully written to the file,
- * otherwise rejects with a DOMException.
+ * @return Resolves with the pre-compression size of the serialized JSON in
+ * bytes (UTF-8), otherwise rejects with a DOMException.
*/
[NewObject]
Promise<WriteJSONResult> writeJSON(DOMString path, any value, optional WriteJSONOptions options = {});
/**
* Moves the file from |sourcePath| to |destPath|, creating necessary parents.
@@ -564,10 +564,16 @@
boolean flush = false;
/**
* If true, compress the data with LZ4-encoding before writing to the file.
*/
boolean compress = false;
+ /**
+ * For |writeJSON|, a hint for the expected JSON string length in UTF-16 code
+ * units. When provided, the JSON serializer pre-allocates a buffer of this
+ * size to avoid incremental reallocations.
+ */
+ unsigned long long jsonLengthHint = 0;
};
/**
* Options to be passed to the |IOUtils.writeJSON| method.
*/
diff --git a/xpcom/ioutils/IOUtils.cpp b/xpcom/ioutils/IOUtils.cpp
--- a/xpcom/ioutils/IOUtils.cpp
+++ b/xpcom/ioutils/IOUtils.cpp
@@ -629,10 +629,13 @@
}
JSContext* cx = aGlobal.Context();
JS::Rooted<JS::Value> value(cx, aValue);
nsString string;
+ if (opts.mLengthHint) {
+ string.SetCapacity(opts.mLengthHint);
+ }
if (!JS_StringifyWithLengthHint(cx, &value, nullptr,
JS::NullHandleValue, AppendJSON,
&string, opts.mLengthHint)) {
JS::Rooted<JS::Value> exn(cx, JS::UndefinedValue());
if (JS_GetPendingException(cx, &exn)) {

View File

@@ -4,31 +4,8 @@
[
{
"type": "phabricator",
"ids": [
"D284084",
"D299584"
],
"name": "Native MacOS popovers",
"replaces": {
// Specifically trying to target FeatureCallout.sys.mjs's change.
// IMPORTANT: Make sure Feature callouts STILL use native popopvers when
// syncing from upstream, as this is a critical part of the patch.
"+ nonnativepopover=\"true\"": "+ ",
// Fix conflicts with upstream changes.
"--menuitem-border-radius: var(--panel-menuitem-border-radius)": "--menuitem-border-radius: var(--arrowpanel-menuitem-border-radius)",
"--menuitem-padding: var(--panel-menuitem-padding)": "--menuitem-padding: var(--arrowpanel-menuitem-padding)",
"--menuitem-margin: var(--panel-menuitem-margin)": "--menuitem-margin: var(--arrowpanel-menuitem-margin)",
" \n #include \"nsCocoaWindow.h\"\n \n #include \"nsISupportsPrimitives.h\"\n #include \"nsArrayUtils.h\"":
" * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\n \n #include \"nsCocoaWindow.h\"\n \n #include \"nsISupportsPrimitives.h\"\n #include \"nsArrayUtils.h\"",
" #include \"nsISupportsPrimitives.h\"\n": "",
" Atom(\"nonnative\", \"nonnative\"),\n": "",
"Atom(\"noscript\", \"noscript\"),": "Atom(\"noscript\", \"noscript\"),\n Atom(\"noshade\", \"noshade\"),",
"GetBoolAttr(nsGkAtoms::nonnative)": "GetBoolAttr(nsGkAtoms::nonnativepopover)"
}
"id": "D299584",
"name": "Native MacOS popovers fix"
},
{
"type": "phabricator",
@@ -62,17 +39,5 @@
"type": "phabricator",
"id": "D291714",
"name": "gh-12979 Clip dirty_rect to device_size"
},
{
"type": "phabricator",
"ids": [
"D247215",
"D298708"
],
"name": "Session store use size hint"
},
{
"type": "local",
"path": "firefox/bug_2013682_allow_stacking_contexts_to_be_promoted.patch"
}
]

View File

@@ -1,5 +1,5 @@
diff --git a/layout/painting/nsImageRenderer.cpp b/layout/painting/nsImageRenderer.cpp
index 4acb7670e971024f9c63e48ff711bbdd1dc02301..518543f29f396d819a71edb984879de22f8434a8 100644
index 6e464b48c90174b8954aad8a79bae30a7a30cbc9..9ea9a4963ceae679f092e014ac24a0d24fb106ce 100644
--- a/layout/painting/nsImageRenderer.cpp
+++ b/layout/painting/nsImageRenderer.cpp
@@ -90,7 +90,7 @@ static already_AddRefed<imgIContainer> GetSymbolicIconImage(nsAtom* aName,
@@ -9,9 +9,9 @@ index 4acb7670e971024f9c63e48ff711bbdd1dc02301..518543f29f396d819a71edb984879de2
- const auto fg = aFrame->StyleText()->mColor.ToColor();
+ const auto fg = aFrame->StyleText()->mColor.ToColor(aFrame);
auto key = std::make_tuple(aName, aScale, fg);
auto* cache = aFrame->GetProperty(SymbolicImageCacheProp());
if (!cache) {
@@ -567,7 +567,7 @@ ImgDrawResult nsImageRenderer::Draw(nsPresContext* aPresContext,
auto* cache = aFrame->GetOrCreateDeletableProperty(SymbolicImageCacheProp());
auto lookup = cache->Lookup(key);
@@ -575,7 +575,7 @@ ImgDrawResult nsImageRenderer::Draw(nsPresContext* aPresContext,
}
case StyleImage::Tag::Gradient: {
nsCSSGradientRenderer renderer = nsCSSGradientRenderer::Create(
@@ -20,7 +20,7 @@ index 4acb7670e971024f9c63e48ff711bbdd1dc02301..518543f29f396d819a71edb984879de2
renderer.Paint(*ctx, aDest, aFill, aRepeatSize, aSrc, aDirtyRect,
aOpacity);
@@ -644,7 +644,7 @@ ImgDrawResult nsImageRenderer::BuildWebRenderDisplayItems(
@@ -652,7 +652,7 @@ ImgDrawResult nsImageRenderer::BuildWebRenderDisplayItems(
switch (mType) {
case StyleImage::Tag::Gradient: {
nsCSSGradientRenderer renderer = nsCSSGradientRenderer::Create(
@@ -29,7 +29,7 @@ index 4acb7670e971024f9c63e48ff711bbdd1dc02301..518543f29f396d819a71edb984879de2
renderer.BuildWebRenderDisplayItems(aBuilder, aSc, aDest, aFill,
aRepeatSize, aSrc,
@@ -670,6 +670,8 @@ ImgDrawResult nsImageRenderer::BuildWebRenderDisplayItems(
@@ -678,6 +678,8 @@ ImgDrawResult nsImageRenderer::BuildWebRenderDisplayItems(
nsPresContext::AppUnitsToIntCSSPixels(aDest.height)};
SVGImageContext svgContext(Some(destCSSSize));
@@ -37,8 +37,8 @@ index 4acb7670e971024f9c63e48ff711bbdd1dc02301..518543f29f396d819a71edb984879de2
+ *mForFrame->PresContext());
Maybe<ImageIntRegion> region;
const int32_t appUnitsPerDevPixel =
@@ -1076,7 +1078,7 @@ ImgDrawResult nsImageRenderer::DrawShapeImage(nsPresContext* aPresContext,
const int32_t appUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel();
@@ -1092,7 +1094,7 @@ ImgDrawResult nsImageRenderer::DrawShapeImage(nsPresContext* aPresContext,
if (mImage->IsGradient()) {
nsCSSGradientRenderer renderer = nsCSSGradientRenderer::Create(

View File

@@ -1,5 +1,5 @@
diff --git a/layout/svg/SVGGradientFrame.cpp b/layout/svg/SVGGradientFrame.cpp
index 9c66d90fc0292abcab30c912968d3f84c0e181ff..aec0b2e48965729ccff19d632ac5e8fd04fd09eb 100644
index b0d38b0fab01797328af0b1f1f48af8fb5eebe4d..953feffdc96143dc2d8f8e57f8bb4a6aeb33f0c5 100644
--- a/layout/svg/SVGGradientFrame.cpp
+++ b/layout/svg/SVGGradientFrame.cpp
@@ -229,8 +229,9 @@ class MOZ_STACK_CLASS SVGColorStopInterpolator
@@ -18,9 +18,9 @@ index 9c66d90fc0292abcab30c912968d3f84c0e181ff..aec0b2e48965729ccff19d632ac5e8fd
if (nStops == 1 || GradientVectorLengthIsZero()) {
// The gradient paints a single colour, using the stop-color of the last
// gradient step if there are more than one.
- return do_AddRef(new gfxPattern(ToDeviceColor(stops.LastElement().mColor)));
+ return do_AddRef(
+ new gfxPattern(ToDeviceColor(stops.LastElement().mColor, aSource)));
- return MakeAndAddRef<gfxPattern>(ToDeviceColor(stops.LastElement().mColor));
+ return MakeAndAddRef<gfxPattern>(
+ ToDeviceColor(stops.LastElement().mColor, aSource));
}
// Get the transform list (if there is one). We do this after the returns

View File

@@ -1,17 +1,17 @@
diff --git a/servo/components/style/queries/feature_expression.rs b/servo/components/style/queries/feature_expression.rs
index e007f3e1583b5c53475e9dbbb3a52cde16d37e25..906d86922311cfe2339719d07d64b2af8819b05a 100644
index 1519c1993d3f3c689aac423f430a53efe92aa009..9c94cda6290448c040e43182957c10ead99ba178 100644
--- a/servo/components/style/queries/feature_expression.rs
+++ b/servo/components/style/queries/feature_expression.rs
@@ -21,7 +21,7 @@ use crate::str::{starts_with_ignore_ascii_case, string_as_ascii_lowercase};
use crate::stylesheets::{CssRuleType, Origin, UrlExtraData};
use crate::values::computed::{self, CSSPixelLength, Ratio, ToComputedValue};
use crate::values::specified::{Angle, Integer, Length, Number, Percentage, Resolution, Time};
-use crate::values::{CSSFloat, DashedIdent};
+use crate::values::{CSSFloat, DashedIdent, AtomString};
@@ -23,7 +23,7 @@ use crate::values::computed::{self, CSSPixelLength, ToComputedValue};
use crate::values::specified::{
Angle, Integer, Length, Number, Percentage, Ratio, Resolution, Time,
};
-use crate::values::DashedIdent;
+use crate::values::{DashedIdent, AtomString};
use crate::{Atom, Zero};
use cssparser::{Parser, ParserInput, Token};
use selectors::kleene_value::KleeneValue;
@@ -633,6 +633,10 @@ impl QueryFeatureExpression {
@@ -643,6 +643,10 @@ impl QueryFeatureExpression {
.map(|v| *expect!(Enumerated, v));
return evaluator(context, computed);
},
@@ -22,7 +22,7 @@ index e007f3e1583b5c53475e9dbbb3a52cde16d37e25..906d86922311cfe2339719d07d64b2af
Evaluator::BoolInteger(eval) => {
let computed = self
.kind
@@ -671,6 +675,7 @@ pub enum QueryExpressionValue {
@@ -681,6 +685,7 @@ pub enum QueryExpressionValue {
/// An enumerated value, defined by the variant keyword table in the
/// feature's `mData` member.
Enumerated(KeywordDiscriminant),
@@ -30,7 +30,7 @@ index e007f3e1583b5c53475e9dbbb3a52cde16d37e25..906d86922311cfe2339719d07d64b2af
/// Value types only used by style-range query expressions, not feature queries.
/// A CSS-wide keyword.
Keyword(CSSWideKeyword),
@@ -718,6 +723,7 @@ impl QueryExpressionValue {
@@ -728,6 +733,7 @@ impl QueryExpressionValue {
Evaluator::Enumerated { serializer, .. } => dest.write_str(&*serializer(value)),
_ => unreachable!(),
},
@@ -38,7 +38,7 @@ index e007f3e1583b5c53475e9dbbb3a52cde16d37e25..906d86922311cfe2339719d07d64b2af
}
}
@@ -755,6 +761,9 @@ impl QueryExpressionValue {
@@ -764,6 +770,9 @@ impl QueryExpressionValue {
Evaluator::Resolution(..) => {
QueryExpressionValue::Resolution(Resolution::parse(context, input)?)
},

View File

@@ -1,9 +1,9 @@
diff --git a/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs b/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs
index 098742100858b266aebc8f764f918c85815f3c5f..71b8f8d71d48229fc96d6c84c635d09012a82250 100644
index e29503cef61f8a08134cb08b6a533cdc9107e725..186d366c71852ae2e04c0455ef769c81cce8c905 100644
--- a/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs
+++ b/toolkit/components/pictureinpicture/PictureInPicture.sys.mjs
@@ -122,6 +122,9 @@ export class PictureInPictureToggleParent extends JSWindowActorParent {
if (browser.ownerGlobal.gBrowser.selectedBrowser == browser) {
if (browser.documentGlobal.gBrowser.selectedBrowser == browser) {
break;
}
+ if (browser.audioMuted) {
@@ -14,10 +14,10 @@ index 098742100858b266aebc8f764f918c85815f3c5f..71b8f8d71d48229fc96d6c84c635d090
);
@@ -493,7 +496,7 @@ export var PictureInPicture = {
// focus the tab's window
tab.ownerGlobal.focus();
tab.documentGlobal.focus();
- gBrowser.selectedTab = tab;
+ browser?.ownerGlobal?.gZenWorkspaces.switchIfNeeded(browser);
+ browser?.documentGlobal?.gZenWorkspaces.switchIfNeeded(browser);
await this.closeSinglePipWindow({ reason: "Unpip", actorRef: pipActor });
},

View File

@@ -1,5 +1,5 @@
diff --git a/toolkit/content/widgets/panel.js b/toolkit/content/widgets/panel.js
index dc3e34847f1b6dfd58f5e036fd7d714ef51c1380..20f18fcb1a2f637d83366b8a517d43200270739f 100644
index dc3e34847f1b6dfd58f5e036fd7d714ef51c1380..243c5b8c849342dd2e887242d4c8499915ee51c2 100644
--- a/toolkit/content/widgets/panel.js
+++ b/toolkit/content/widgets/panel.js
@@ -136,7 +136,19 @@
@@ -7,11 +7,11 @@ index dc3e34847f1b6dfd58f5e036fd7d714ef51c1380..20f18fcb1a2f637d83366b8a517d4320
this.anchorNode.closest("toolbarbutton, .anchor-root") ||
this.anchorNode;
+ let toolbox = anchorRoot.closest("#navigator-toolbox");
+ if (toolbox && toolbox.ownerGlobal.gZenCompactModeManager?.preference) {
+ if (toolbox && toolbox.documentGlobal.gZenCompactModeManager?.preference) {
+ // Disable transitions for now, see gh-11667
+ toolbox.style.transition = "none";
+ toolbox.setAttribute("zen-compact-mode-active", "true");
+ anchorRoot.ownerGlobal.setTimeout(() => {
+ anchorRoot.documentGlobal.setTimeout(() => {
+ toolbox.style.transition = "";
+ }, 0);
+ }

View File

@@ -1,8 +1,8 @@
diff --git a/toolkit/modules/PopupNotifications.sys.mjs b/toolkit/modules/PopupNotifications.sys.mjs
index a53369760ced2df3d2d9682142d94dfc7deda71c..8755f15ea82f6a7addcf91b62b1b3e7b1e20bce6 100644
index 5e88f279e570edbf95823bb9dc9835bae89feb32..f50db584dff740583665239d2cc2c5d00c5010e9 100644
--- a/toolkit/modules/PopupNotifications.sys.mjs
+++ b/toolkit/modules/PopupNotifications.sys.mjs
@@ -1526,6 +1526,15 @@ PopupNotifications.prototype = {
@@ -1532,6 +1532,15 @@ PopupNotifications.prototype = {
) {
for (let anchorElement of anchorElements) {
anchorElement.setAttribute(ICON_ATTRIBUTE_SHOWING, "true");
@@ -11,7 +11,7 @@ index a53369760ced2df3d2d9682142d94dfc7deda71c..8755f15ea82f6a7addcf91b62b1b3e7b
+ // Disable transitions for now, see gh-11667
+ toolbox.style.transition = "none";
+ toolbox.setAttribute("zen-compact-mode-active", "true");
+ anchorElement.ownerGlobal.setTimeout(() => {
+ anchorElement.documentGlobal.setTimeout(() => {
+ toolbox.style.transition = "";
+ }, 0);
+ }

View File

@@ -1,5 +1,5 @@
diff --git a/toolkit/moz.configure b/toolkit/moz.configure
index 0f5dab192533aa42df97ee3bd4176a9f44d4d568..d45ad2409f6d36106fce5a380545aaae9397ae84 100644
index 75e99bbd2490b9014be6f4e956546d4507e751df..fbe16d282113175f067d739e1284b2544d014e7d 100644
--- a/toolkit/moz.configure
+++ b/toolkit/moz.configure
@@ -20,6 +20,7 @@ def check_moz_app_id(moz_app_id, build_project):
@@ -33,20 +33,7 @@ index 0f5dab192533aa42df97ee3bd4176a9f44d4d568..d45ad2409f6d36106fce5a380545aaae
help="Set distribution-specific id",
)
set_config("MOZ_DISTRIBUTION_ID", depends("--with-distribution-id")(lambda v: v[0]))
@@ -874,9 +879,9 @@ set_config("MOZ_SYSTEM_AV1", True, when="--with-system-av1")
option("--disable-jxl", help="Disable jxl image support")
-@depends("--disable-jxl", milestone.is_nightly)
-def jxl(value, is_nightly):
- if is_nightly and value:
+@depends("--disable-jxl")
+def jxl(value):
+ if value:
return True
@@ -2028,7 +2033,7 @@ set_define("A11Y_LOG", True, when=a11y_log)
@@ -2032,7 +2037,7 @@ set_define("A11Y_LOG", True, when=a11y_log)
# ==============================================================
@depends(milestone)
def require_signing(milestone):
@@ -55,7 +42,7 @@ index 0f5dab192533aa42df97ee3bd4176a9f44d4d568..d45ad2409f6d36106fce5a380545aaae
option(
@@ -3912,7 +3917,7 @@ with only_when(compile_environment):
@@ -3916,7 +3921,7 @@ with only_when(compile_environment):
return "Mozilla"
elif target.os == "Android":
return ".mozilla"
@@ -64,7 +51,7 @@ index 0f5dab192533aa42df97ee3bd4176a9f44d4d568..d45ad2409f6d36106fce5a380545aaae
option(
"--with-user-appdir",
@@ -4325,7 +4330,7 @@ with only_when(target_is_windows):
@@ -4329,7 +4334,7 @@ with only_when(target_is_windows):
@depends(target.abi)
def desktop_launcher_enabled(abi):

View File

@@ -1,17 +1,17 @@
diff --git a/toolkit/profile/nsToolkitProfileService.cpp b/toolkit/profile/nsToolkitProfileService.cpp
index df573b68c781a91763bb60ff63a248cea7a1c5af..f7b68fb5bc5ca22bdaf768a3afe2eb3eae568bc0 100644
index f624b97e480cdeae8e7621060b33c7ab872c4523..2fc8240543ef391f43ca6a02d169302488d738cc 100644
--- a/toolkit/profile/nsToolkitProfileService.cpp
+++ b/toolkit/profile/nsToolkitProfileService.cpp
@@ -97,6 +97,8 @@ using namespace mozilla;
#define INSTALL_PREFIX_LENGTH 7
@@ -101,6 +101,8 @@ using namespace mozilla;
#define STORE_ID_PREF "toolkit.profiles.storeID"
#define NEW_PROFILE_PREF "toolkit.profiles.newProfileSubmitted"
+#include "zenToolkitProfileServiceDefaultOverride.h"
+
struct KeyValue {
KeyValue(const char* aKey, const char* aValue) : key(aKey), value(aValue) {}
@@ -1418,7 +1420,7 @@ nsresult nsToolkitProfileService::CreateDefaultProfile(
@@ -1482,7 +1484,7 @@ nsresult nsToolkitProfileService::CreateDefaultProfile(
if (mUseDevEditionProfile) {
name.AssignLiteral(DEV_EDITION_NAME);
} else if (mUseDedicatedProfile) {

View File

@@ -1,13 +1,24 @@
diff --git a/toolkit/themes/shared/design-system/dist/tokens-shared.css b/toolkit/themes/shared/design-system/dist/tokens-shared.css
index 452f3731fbca42a3529ab14421ef1c2c453b6c01..66791a5b6b074bccb02905053f043cc054b6bd57 100644
index 94afbe630914eef375967f2eff310d69c61fa1aa..04b42529d43c5100a76c883220875c0b70ad0616 100644
--- a/toolkit/themes/shared/design-system/dist/tokens-shared.css
+++ b/toolkit/themes/shared/design-system/dist/tokens-shared.css
@@ -7,6 +7,8 @@
@layer tokens-foundation, tokens-foundation-nova, tokens-prefers-contrast, tokens-prefers-contrast-nova, tokens-forced-colors, tokens-forced-colors-nova;
@layer tokens-foundation, tokens-foundation-nova, tokens-prefers-contrast, tokens-prefers-contrast-nova, tokens-forced-colors, tokens-forced-colors-nova, tokens-browser-theme, tokens-browser-theme-nova;
+@import url("chrome://browser/content/zen-styles/zen-theme.css");
+
@layer tokens-foundation {
:root,
:host(.anonymous-content-host) {
@@ -368,8 +370,8 @@
--panel-background-color-dimmed-further: color-mix(in srgb, currentColor 30%, transparent);
--panel-border-color: ThreeDShadow;
--panel-border-radius: var(--border-radius-medium);
- --panel-box-shadow: 0 0 var(--panel-box-shadow-margin) hsla(0, 0%, 0%, 0.2);
- --panel-box-shadow-margin: 4px;
+ --panel-box-shadow: var(--zen-big-shadow);
+ --panel-box-shadow-margin: 8px;
--panel-menuitem-border-radius: var(--border-radius-small);
--panel-menuitem-margin: var(--panel-menuitem-margin-block) var(--panel-menuitem-margin-inline);
--panel-menuitem-margin-block: 0px;

View File

@@ -1,15 +0,0 @@
diff --git a/toolkit/themes/shared/design-system/src/panel.css b/toolkit/themes/shared/design-system/src/panel.css
index 92a6b4b23aee7d880bee21a5e843653444e3fc32..2d0a73d338b4e4d5a0f98b8e3c00134a823c223c 100644
--- a/toolkit/themes/shared/design-system/src/panel.css
+++ b/toolkit/themes/shared/design-system/src/panel.css
@@ -10,8 +10,8 @@
--panel-color: FieldText;
--panel-padding-block: var(--dimension-4);
--panel-padding: var(--dimension-16);
- --panel-shadow-margin: var(--dimension-4);
- --panel-shadow: 0 0 var(--panel-shadow-margin) hsla(0, 0%, 0%, 0.2);
+ --panel-shadow-margin: 8px;
+ --panel-shadow: var(--zen-big-shadow);
--panel-width: initial;
--panel-dimmed: color-mix(in srgb, currentColor 17%, transparent);
--panel-dimmed-further: color-mix(in srgb, currentColor 30%, transparent);

View File

@@ -1,12 +1,12 @@
diff --git a/toolkit/themes/shared/design-system/src/toolbar.css b/toolkit/themes/shared/design-system/src/toolbar.css
index 61667b3f778a66b74aa7b169cd646a8437a5dd42..d1a9e5ad121a44f182e7061a21f4bbe9540cae8c 100644
index b5e0d34222312ec568d027725489ac8beee41dbe..c6fc389fbf4b3864f391b197c33ebd616bfc3b3c 100644
--- a/toolkit/themes/shared/design-system/src/toolbar.css
+++ b/toolkit/themes/shared/design-system/src/toolbar.css
@@ -61,7 +61,6 @@
--toolbar-field-color: inherit;
@media (prefers-color-scheme: light) {
- --toolbar-bgcolor: var(--color-white);
@@ -9,7 +9,6 @@
:root {
@media not (prefers-contrast) {
@media (prefers-color-scheme: light) {
- --toolbar-background-color: var(--color-white);
}
}
}

View File

@@ -1,9 +1,9 @@
diff --git a/tools/lint/rejected-words.yml b/tools/lint/rejected-words.yml
index 3eb549d252c9f5f7b5cbcf72ca1480025794b481..1a065643971f1048e9598b3c389f51e199eba63d 100644
index eae20774aaf1001a8fd06dbfe13dca13979db4ad..dd4786dcb8ea1ca4d2115a775bd1e940d2ccd725 100644
--- a/tools/lint/rejected-words.yml
+++ b/tools/lint/rejected-words.yml
@@ -8,7 +8,6 @@ avoid-blacklist-and-whitelist:
ignore-case: true
@@ -13,7 +13,6 @@ avoid-blacklist-and-whitelist:
- 'tools/lint/mozcheck/**'
# Based on codespell with idl and webidl added.
extensions:
- - js

View File

@@ -50,7 +50,7 @@ export class SelectorComponent {
localizationArray = null
) {
this.document = document;
this.window = document.ownerGlobal;
this.window = document.documentGlobal;
this.zenBoostsChild = zenBoostsChild;
this.#onSelect = onSelect;

View File

@@ -164,7 +164,7 @@ void main() {
return;
}
this.document = document;
this.window = document.ownerGlobal;
this.window = document.documentGlobal;
}
/**

View File

@@ -34,7 +34,7 @@ export class ZapOverlay {
*/
constructor(document, zenBoostsChild) {
this.document = document;
this.window = document.ownerGlobal;
this.window = document.documentGlobal;
this.zenBoostsChild = zenBoostsChild;
this.#selectorComponent = new lazy.SelectorComponent(

View File

@@ -299,12 +299,12 @@ window.gZenUIManager = {
},
openAndChangeToTab(url, options) {
if (window.ownerGlobal.parent) {
const tab = window.ownerGlobal.parent.gBrowser.addTrustedTab(
if (window.parent) {
const tab = window.parent.gBrowser.addTrustedTab(
url,
options
);
window.ownerGlobal.parent.gBrowser.selectedTab = tab;
window.parent.gBrowser.selectedTab = tab;
return tab;
}
const tab = window.gBrowser.addTrustedTab(url, options);
@@ -616,8 +616,8 @@ window.gZenUIManager = {
if (
this._lastTab &&
!this._lastTab.closing &&
this._lastTab.ownerGlobal &&
!this._lastTab.ownerGlobal.closed &&
this._lastTab.documentGlobal &&
!this._lastTab.documentGlobal.closed &&
gBrowser.selectedTab === this._lastTab
) {
this._lastTab._visuallySelected = true;

View File

@@ -442,7 +442,7 @@
* available space as much as possible, see bug 1795260. */
min-width: 0;
--toolbarbutton-inner-padding: var(--zen-toolbar-button-inner-padding);
--toolbarbutton-padding-inner: var(--zen-toolbar-button-inner-padding);
/* Add space to beginning of toolbar and make that space click the first <toolbarbutton> */
> :is(toolbarbutton, toolbaritem):first-child,

View File

@@ -15,7 +15,7 @@ panel[type="arrow"]:not(#feature-callout) {
/* The mica rendering already adds a shadow and a border, so we
* remove the one we add via CSS */
--panel-shadow-margin: 0px !important;
--panel-box-shadow-margin: 0px !important;
--panel-border-color: transparent !important;
border: none !important;
@@ -39,7 +39,7 @@ panel[type="arrow"]:not(#feature-callout) {
background-color: Menu !important;
}
--panel-shadow-margin: 0px !important;
--panel-box-shadow-margin: 0px !important;
--panel-background: transparent !important;
--panel-border-color: transparent;
@@ -48,7 +48,7 @@ panel[type="arrow"]:not(#feature-callout) {
* on Tahoe, where we *don't* apply an image mask, meaning that
* trying to render a shadow would end up in having weird borders
* around the panel */
--panel-shadow: none;
--panel-box-shadow: none;
&::part(content) {
/* This shoudn't really be needed, but just in case */

View File

@@ -35,7 +35,7 @@ menupopup,
panel {
--panel-background: var(--arrowpanel-background);
--menuitem-padding: 6px !important;
--panel-shadow-margin: 8px;
--panel-box-shadow-margin: 8px;
/* This should match GetMenuCornerRadius() on macOS, or be overridden below */
@media (-moz-platform: macos) {

View File

@@ -187,8 +187,8 @@
.identity-box-button {
--tab-border-radius: 6px;
--toolbarbutton-border-radius: var(--tab-border-radius);
--toolbarbutton-inner-padding: 6px;
--toolbarbutton-outer-padding: 1px;
--toolbarbutton-padding-inner: 6px;
--toolbarbutton-padding-outer: 1px;
--toolbarbutton-icon-fill: color-mix(in srgb, currentColor 70%, transparent);
transition:
@@ -281,7 +281,7 @@
/* Customizable modes */
#customization-container {
--toolbar-bgcolor: var(--arrowpanel-background);
--toolbar-background-color: var(--arrowpanel-background);
}
/* Site Data popup */

View File

@@ -157,7 +157,7 @@
}
--zen-toolbar-button-inner-padding: 6px;
--toolbarbutton-outer-padding: 4px;
--toolbarbutton-padding-outer: 4px;
--zen-toolbar-height-with-bookmarks: var(--zen-toolbar-height);
&[zen-has-bookmarks='true'] {
/* Make sure `30px` matches the bookmarks toolbar height */
@@ -175,7 +175,7 @@
* as the backdrop matches our color scheme. The .6 matches what we do for
* acrylic, and the .15 matches the 85% we do for the default toolbar
* background on the native theme. */
--toolbar-bgcolor: light-dark(rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0.15));
--toolbar-background-color: light-dark(rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0.15));
--toolbarbutton-active-background: color-mix(
in srgb,

View File

@@ -980,7 +980,7 @@ window.gZenCompactModeManager = {
button: {
id: "zen-open-background-tab-button",
command: () => {
const targetWindow = window.ownerGlobal.parent || window;
const targetWindow = window.parent || window;
targetWindow.gBrowser.selectedTab = tab;
},
},

View File

@@ -38,7 +38,7 @@
#zen-sidebar-top-buttons-customization-target {
padding-inline-start: calc(
var(--zen-toolbox-padding) - var(--toolbarbutton-outer-padding)
var(--zen-toolbox-padding) - var(--toolbarbutton-padding-outer)
) !important;
}

View File

@@ -947,7 +947,7 @@
const ownerGlobal = event.dataTransfer.mozGetDataAt(
TAB_DROP_TYPE,
0
)?.ownerGlobal;
)?.documentGlobal;
if (ownerGlobal?.gZenCompactModeManager) {
// Sometimes, dragend doesn't always get called when dragging
// to different windows, see gh-8643.
@@ -967,7 +967,7 @@
const dt = event.dataTransfer;
const activeWorkspace = gZenWorkspaces.activeWorkspace;
let draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
if (draggedTab.ownerGlobal === window) {
if (draggedTab.documentGlobal === window) {
if (
!draggedTab.hasAttribute("zen-essential") &&
draggedTab.getAttribute("zen-workspace-id") != activeWorkspace
@@ -1051,7 +1051,7 @@
gZenWorkspaces.activeWorkspace ||
!dropElement.visible ||
!draggedTab.visible ||
draggedTab.ownerGlobal !== window
draggedTab.documentGlobal !== window
) {
return;
}
@@ -1158,7 +1158,7 @@
handle_dragend(event) {
const dt = event.dataTransfer;
const draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
let ownerGlobal = draggedTab?.ownerGlobal;
let ownerGlobal = draggedTab?.documentGlobal;
draggedTab.style.visibility = "";
let thisFromGlobal = ownerGlobal?.gBrowser.tabContainer.tabDragAndDrop;
let currentEssenialContainer =

View File

@@ -129,7 +129,7 @@ export class nsZenLiveFolderProvider {
let userContextId = 0;
let folder = this.manager.getFolderForLiveFolder(this);
if (folder) {
let space = folder.ownerGlobal.gZenWorkspaces.getWorkspaceFromId(
let space = folder.documentGlobal.gZenWorkspaces.getWorkspaceFromId(
folder.getAttribute("zen-workspace-id")
);
if (space) {

View File

@@ -272,7 +272,7 @@ class nsZenLiveFoldersManager {
let labelElement = folder.labelElement;
labelElement.setAttribute("live-folder-animation", "true");
labelElement.style.backgroundPositionX = "0%";
folder.ownerGlobal.gZenUIManager.motion
folder.documentGlobal.gZenUIManager.motion
.animate(
labelElement,
{
@@ -440,7 +440,7 @@ class nsZenLiveFoldersManager {
}
let userContextId = 0;
let space = folder.ownerGlobal.gZenWorkspaces.getWorkspaceFromId(
let space = folder.documentGlobal.gZenWorkspaces.getWorkspaceFromId(
folder.getAttribute("zen-workspace-id")
);
if (space) {

View File

@@ -21,7 +21,7 @@
#zen-media-buttons-hbox {
align-items: start;
margin-top: -4px;
--toolbarbutton-outer-padding: 2px;
--toolbarbutton-padding-outer: 2px;
}
&:not([media-sharing]) {
@@ -274,7 +274,7 @@
align-items: flex-end;
justify-content: space-between;
max-width: 100%;
--toolbarbutton-outer-padding: 0;
--toolbarbutton-padding-outer: 0;
container: media-controls / inline-size;
gap: 0.7rem;
}

View File

@@ -380,7 +380,7 @@ class nsZenWindowSync {
}
handleEvent(aEvent) {
const window = aEvent.currentTarget.ownerGlobal;
const window = aEvent.currentTarget.documentGlobal ?? aEvent.currentTarget;
if (
!window.gZenStartup.isReady ||
!window.gZenWorkspaces?.shouldHaveWorkspaces ||
@@ -686,7 +686,7 @@ class nsZenWindowSync {
} else {
const workspaceId =
aTargetItem.getAttribute("zen-workspace-id") ||
aOriginalItem.ownerGlobal.gZenWorkspaces.activeWorkspace;
aOriginalItem.documentGlobal.gZenWorkspaces.activeWorkspace;
const workspaceElement = gZenWorkspaces.workspaceElement(workspaceId);
container = isPinned
? workspaceElement?.pinnedTabsContainer
@@ -717,7 +717,7 @@ class nsZenWindowSync {
* @param {number} flags - The sync flags indicating what to synchronize.
*/
#syncItemForAllWindows(aItem, flags = 0) {
const window = aItem.ownerGlobal;
const window = aItem.documentGlobal;
this.#runOnAllWindows(window, win => {
this.#syncItemWithOriginal(
aItem,
@@ -765,7 +765,7 @@ class nsZenWindowSync {
* @param {boolean} onClose - Indicates if the swap is done during a tab close operation.
*/
#withRestoreTabProgressListener(aTab, callback, onClose = false) {
const otherTabBrowser = aTab.ownerGlobal.gBrowser;
const otherTabBrowser = aTab.documentGlobal.gBrowser;
const otherBrowser = aTab.linkedBrowser;
// We aren't closing the other tab so, we also need to swap its tablisteners.
@@ -821,7 +821,7 @@ class nsZenWindowSync {
// There has been some reports of this happening in the wild, and while it shouldn't
// cause any critical issues, it can cause some weird states and we should avoid it.
// For example, see gh-13149
if (aOtherTab.ownerGlobal === aOurTab.ownerGlobal) {
if (aOtherTab.documentGlobal === aOurTab.documentGlobal) {
this.log(
`Cannot swap browsers between tabs ${aOurTab.id} and ${aOtherTab.id} because they are in the same window`
);
@@ -866,7 +866,7 @@ class nsZenWindowSync {
() => {
this.log(`Swapping docshells between windows for tab ${aOurTab.id}`);
try {
aOurTab.ownerGlobal.gBrowser.swapBrowsersAndCloseOther(
aOurTab.documentGlobal.gBrowser.swapBrowsersAndCloseOther(
aOurTab,
aOtherTab,
false
@@ -936,7 +936,7 @@ class nsZenWindowSync {
// Recalculate the focus in order to allow the user to continue typing
// inside the web content area without having to click outside and back in.
aOurTab.linkedBrowser.blur();
aOurTab.ownerGlobal.gBrowser._adjustFocusAfterTabSwitch(aOurTab);
aOurTab.documentGlobal.gBrowser._adjustFocusAfterTabSwitch(aOurTab);
aOurTab.linkedBrowser.docShellIsActive = true;
}
}
@@ -955,7 +955,7 @@ class nsZenWindowSync {
return new Promise(async resolve => {
if (callback) {
const browserBlob =
await aOtherTab.ownerGlobal.PageThumbs.captureToBlob(
await aOtherTab.documentGlobal.PageThumbs.captureToBlob(
aOtherTab.linkedBrowser,
{
fullScale: true,
@@ -1005,7 +1005,7 @@ class nsZenWindowSync {
*/
#createPseudoImageForBrowser(aBrowser, aSrc) {
const doc = aBrowser.ownerDocument;
const win = aBrowser.ownerGlobal;
const win = aBrowser.documentGlobal;
const img = doc.createElement("img");
img.className = "zen-pseudo-browser-image";
img.src = aSrc;
@@ -1224,7 +1224,7 @@ class nsZenWindowSync {
this.log(`Setting pinned initial state for tab ${aTab.id}`);
let { entries, index } = this.#getTabEntriesFromCache(aTab);
let image =
aTab.getAttribute("image") || aTab.ownerGlobal.gBrowser.getIcon(aTab);
aTab.getAttribute("image") || aTab.documentGlobal.gBrowser.getIcon(aTab);
let activeIndex = typeof index === "number" ? index : entries.length;
// Tab state cache gives us the index starting from 1 instead of 0.
activeIndex--;
@@ -1322,7 +1322,7 @@ class nsZenWindowSync {
return;
}
let image =
aTab.getAttribute("image") || aTab.ownerGlobal.gBrowser.getIcon(aTab);
aTab.getAttribute("image") || aTab.documentGlobal.gBrowser.getIcon(aTab);
this.#runOnAllWindows(null, win => {
const targetTab = this.getItemFromWindow(win, aTab.id);
if (targetTab) {
@@ -1335,7 +1335,7 @@ class nsZenWindowSync {
on_TabOpen(aEvent, { ignoreExistingId = false } = {}) {
const tab = aEvent.target;
const window = tab.ownerGlobal;
const window = tab.documentGlobal;
const isUnsyncedWindow = window.gZenWorkspaces.privateWindowOrDisabled;
if (tab.id && !ignoreExistingId) {
// This tab was opened as part of a sync operation.
@@ -1390,28 +1390,28 @@ class nsZenWindowSync {
on_TabHide(aEvent) {
const tab = aEvent.target;
const window = tab.ownerGlobal;
const window = tab.documentGlobal;
if (lazy.gSyncOnlyPinnedTabs && !tab.pinned) {
return;
}
this.#runOnAllWindows(window, win => {
const targetTab = this.getItemFromWindow(win, tab.id);
if (targetTab) {
targetTab.ownerGlobal.gBrowser.hideTab(targetTab);
targetTab.documentGlobal.gBrowser.hideTab(targetTab);
}
});
}
on_TabShow(aEvent) {
const tab = aEvent.target;
const window = tab.ownerGlobal;
const window = tab.documentGlobal;
if (lazy.gSyncOnlyPinnedTabs && !tab.pinned) {
return;
}
this.#runOnAllWindows(window, win => {
const targetTab = this.getItemFromWindow(win, tab.id);
if (targetTab) {
targetTab.ownerGlobal.gBrowser.showTab(targetTab);
targetTab.documentGlobal.gBrowser.showTab(targetTab);
}
});
}
@@ -1465,7 +1465,7 @@ class nsZenWindowSync {
on_TabClose(aEvent) {
const tab = aEvent.target;
const window = tab.ownerGlobal;
const window = tab.documentGlobal;
this.#runOnAllWindows(window, win => {
const targetTab = this.getItemFromWindow(win, tab.id);
if (targetTab) {
@@ -1524,14 +1524,14 @@ class nsZenWindowSync {
// eslint-disable-next-line no-async-promise-executor
this.#docShellSwitchPromise = new Promise(async resolve => {
await promise;
await this.#onTabSwitchOrWindowFocus(tab.ownerGlobal, previousTab);
await this.#onTabSwitchOrWindowFocus(tab.documentGlobal, previousTab);
resolve();
this.#docShellSwitchPromise = null;
});
}
on_SSWindowClosing(aEvent) {
const window = aEvent.target.ownerGlobal;
const window = aEvent.target.documentGlobal ?? aEvent.target;
window._zenClosingWindow = true;
for (let eventName of EVENTS) {
window.removeEventListener(eventName, this);
@@ -1556,7 +1556,7 @@ class nsZenWindowSync {
const tab = this.#swapedTabsEntriesForWC.get(browser.permanentKey);
if (tab) {
try {
let win = tab.ownerGlobal;
let win = tab.documentGlobal;
this.log(`Finalizing swap for tab ${tab.id} on window close`);
lazy.TabStateCache.update(
tab.linkedBrowser.permanentKey,
@@ -1597,7 +1597,7 @@ class nsZenWindowSync {
// This tab group was opened as part of a sync operation.
return;
}
const window = tabGroup.ownerGlobal;
const window = tabGroup.documentGlobal;
const isFolder = tabGroup.isZenFolder;
const isSplitView = tabGroup.hasAttribute("split-view-group");
if (isSplitView) {
@@ -1630,7 +1630,7 @@ class nsZenWindowSync {
on_TabGroupRemoved(aEvent) {
const tabGroup = aEvent.target;
const window = tabGroup.ownerGlobal;
const window = tabGroup.documentGlobal;
this.#runOnAllWindows(window, win => {
const targetGroup = this.getItemFromWindow(win, tabGroup.id);
if (targetGroup) {
@@ -1664,7 +1664,7 @@ class nsZenWindowSync {
on_ZenTabRemovedFromSplit(aEvent) {
const tab = aEvent.target;
const window = tab.ownerGlobal;
const window = tab.documentGlobal;
this.#runOnAllWindows(window, win => {
const targetTab = this.getItemFromWindow(win, tab.id);
if (targetTab && win.gZenViewSplitter) {
@@ -1677,7 +1677,7 @@ class nsZenWindowSync {
on_ZenSplitViewTabsSplit(aEvent) {
const tabGroup = aEvent.target;
const window = tabGroup.ownerGlobal;
const window = tabGroup.documentGlobal;
const tabs = tabGroup.tabs;
this.#runOnAllWindows(window, win => {
const otherWindowTabs = tabs

View File

@@ -225,8 +225,8 @@ class nsZenWorkspaces {
if (
this._emptyTab &&
!this._emptyTab.closing &&
this._emptyTab.ownerGlobal &&
!this._emptyTab.ownerGlobal.closed &&
this._emptyTab.documentGlobal &&
!this._emptyTab.documentGlobal.closed &&
gZenVerticalTabsManager._canReplaceNewTab
) {
gBrowser.selectedTab = this._emptyTab;
@@ -3234,8 +3234,8 @@ class nsZenWorkspaces {
// Validate tab state
if (
tab.closing ||
!tab.ownerGlobal ||
tab.ownerGlobal.closed ||
!tab.documentGlobal ||
tab.documentGlobal.closed ||
!tab.linkedBrowser
) {
console.warn("Tab is no longer valid, cannot select it");

View File

@@ -166,7 +166,7 @@
/* Mark workspaces indicator */
.zen-current-workspace-indicator {
--indicator-gap: calc(var(--toolbarbutton-inner-padding) - 1px);
--indicator-gap: calc(var(--toolbarbutton-padding-inner) - 1px);
padding: calc(3px + var(--tab-inline-padding) + var(--zen-toolbox-padding));
font-weight: 500;
position: relative;
@@ -272,7 +272,7 @@
margin-left: auto !important;
transition: opacity 0.1s;
order: 5;
--toolbarbutton-inner-padding: 6px !important;
--toolbarbutton-padding-inner: 6px !important;
opacity: 0;
visibility: collapse;

View File

@@ -326,7 +326,7 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
if (
!gBrowser.isTab(draggedTab) ||
gBrowser.selectedTab.hasAttribute("zen-empty-tab") ||
draggedTab.ownerGlobal !== window
draggedTab.documentGlobal !== window
) {
return;
}
@@ -1975,7 +1975,7 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
* @returns {tab} The tab that was opened
*/
openAndSwitchToTab(url, options) {
const parentWindow = window.ownerGlobal.parent;
const parentWindow = window.parent;
const targetWindow = parentWindow || window;
const tab = targetWindow.gBrowser.addTrustedTab(url, options);
targetWindow.gBrowser.selectedTab = tab;

View File

@@ -471,7 +471,7 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
}
if (tab.pinned) {
gBrowser.zenHandleTabMove(tab, () => {
if (tab.ownerGlobal !== window) {
if (tab.documentGlobal !== window) {
tab = gBrowser.adoptTab(tab, {
selectTab: tab.selected,
});
@@ -679,12 +679,12 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
) {
workspaceId = gZenWorkspaces.activeWorkspace;
}
if (tab.ownerGlobal !== window) {
if (tab.documentGlobal !== window) {
fromDifferentWindow = true;
if (workspaceId) {
tab.ownerGlobal.gBrowser.selectedTab =
tab.ownerGlobal.gBrowser._findTabToBlurTo(tab, movingTabs);
tab.ownerGlobal.gZenWorkspaces.moveTabToWorkspace(tab, workspaceId);
tab.documentGlobal.gBrowser.selectedTab =
tab.documentGlobal.gBrowser._findTabToBlurTo(tab, movingTabs);
tab.documentGlobal.gZenWorkspaces.moveTabToWorkspace(tab, workspaceId);
}
// Move the tabs into this window. To avoid multiple tab-switches in
// the original window, the selected tab should be adopted last.

View File

@@ -373,7 +373,7 @@
& .tabbrowser-tab {
pointer-events: none;
margin: 0 0 0 4px !important;
--toolbarbutton-inner-padding: 0;
--toolbarbutton-padding-inner: 0;
--border-radius-medium: 8px;
width: var(--size-item-medium);
height: var(--size-item-medium);
@@ -401,7 +401,7 @@
/* Style glance tab icon */
& .tab-icon-image {
--toolbarbutton-inner-padding: 0 !important;
--toolbarbutton-padding-inner: 0 !important;
width: 14px;
height: 14px;
}
@@ -515,8 +515,8 @@
}
#tabbrowser-tabs {
--toolbarbutton-inner-padding: 10px !important;
--tab-icon-end-margin: var(--toolbarbutton-inner-padding) !important;
--toolbarbutton-padding-inner: 10px !important;
--tab-icon-end-margin: var(--toolbarbutton-padding-inner) !important;
}
& .tab-audio-button {
@@ -687,8 +687,8 @@
.tab-icon-image,
.tab-sharing-icon-overlay,
.tab-icon-overlay {
margin-inline-end: var(--toolbarbutton-inner-padding) !important;
margin-inline-start: calc(var(--toolbarbutton-inner-padding) / 3) !important;
margin-inline-end: var(--toolbarbutton-padding-inner) !important;
margin-inline-start: calc(var(--toolbarbutton-padding-inner) / 3) !important;
}
}
}
@@ -952,7 +952,7 @@
height: calc(100% - var(--tab-block-margin) * 2);
margin-left: calc(-1 * var(--tab-inline-padding) + var(--tab-block-margin));
margin-right: 8px;
padding: 0 calc(var(--toolbarbutton-inner-padding) - 2px) 0 calc(var(--toolbarbutton-inner-padding) / 3 + var(--tab-inline-padding) - 2px);
padding: 0 calc(var(--toolbarbutton-padding-inner) - 2px) 0 calc(var(--toolbarbutton-padding-inner) / 3 + var(--tab-inline-padding) - 2px);
border-radius: 0;
border-top-left-radius: var(--border-radius-medium);
width: unset;
@@ -1029,7 +1029,7 @@
min-width: unset !important;
:root[zen-sidebar-expanded="true"] & {
--toolbarbutton-inner-padding: var(--zen-toolbar-button-inner-padding) !important;
--toolbarbutton-padding-inner: var(--zen-toolbar-button-inner-padding) !important;
}
:root[zen-single-toolbar="true"] & {
@@ -1048,7 +1048,7 @@
align-items: center;
#nav-bar & {
padding-inline-end: var(--toolbarbutton-outer-padding);
padding-inline-end: var(--toolbarbutton-padding-outer);
}
:root:not([zen-sidebar-expanded="true"]) & toolbarspring {
@@ -1171,7 +1171,7 @@
.tabbrowser-tab[zen-essential="true"],
#zen-welcome-initial-essentials-browser-sidebar-essentials .tabbrowser-tab {
--toolbarbutton-inner-padding: 0;
--toolbarbutton-padding-inner: 0;
max-width: unset;
width: 100% !important;

View File

@@ -528,7 +528,7 @@ function setScrollPosition(bc, x, y) {
content.addEventListener(
"mozvisualscroll",
function onScroll(event) {
if (content.document.ownerGlobal.visualViewport == event.target) {
if (content.document.documentGlobal.visualViewport == event.target) {
content.removeEventListener("mozvisualscroll", onScroll, {
mozSystemGroup: true,
});
@@ -576,7 +576,7 @@ function setPropertyOfFormField(browserContext, selector, propName, newValue) {
node[propNameChild] = newValueChild;
let event = node.ownerDocument.createEvent("UIEvents");
event.initUIEvent("input", true, true, node.ownerGlobal, 0);
event.initUIEvent("input", true, true, node.documentGlobal, 0);
node.dispatchEvent(event);
}
);
@@ -678,7 +678,7 @@ async function openTabMenuFor(tab) {
EventUtils.synthesizeMouseAtCenter(
tab,
{ type: "contextmenu" },
tab.ownerGlobal
tab.documentGlobal
);
await tabMenuShown;

View File

@@ -610,7 +610,7 @@ async function removeTabGroup(group) {
* @returns {Promise<XULMenuElement|XULPopupElement>}
*/
async function getContextMenu(triggerNode, contextMenuId) {
let win = triggerNode.ownerGlobal;
let win = triggerNode.documentGlobal;
triggerNode.scrollIntoView({ behavior: "instant" });
const contextMenu = win.document.getElementById(contextMenuId);
const contextMenuShown = BrowserTestUtils.waitForPopupEvent(

View File

@@ -19,28 +19,28 @@ function selectWithMouseDrag(fromX, toX, win = window) {
fromX,
rect.height / 2,
{ type: "mousemove" },
target.ownerGlobal
target.documentGlobal
);
EventUtils.synthesizeMouse(
target,
fromX,
rect.height / 2,
{ type: "mousedown" },
target.ownerGlobal
target.documentGlobal
);
EventUtils.synthesizeMouse(
target,
toX,
rect.height / 2,
{ type: "mousemove" },
target.ownerGlobal
target.documentGlobal
);
EventUtils.synthesizeMouse(
target,
toX,
rect.height / 2,
{ type: "mouseup" },
target.ownerGlobal
target.documentGlobal
);
return promise;
}

View File

@@ -550,7 +550,7 @@ export class ZenUrlbarProviderGlobalActions extends UrlbarProvider {
const result = details.result;
const payload = result.payload;
const command = payload.zenCommand;
const ownerGlobal = details.element.ownerGlobal;
const ownerGlobal = details.element.documentGlobal;
ownerGlobal.gBrowser.selectedBrowser.focus();
if (typeof command === "function") {
command(ownerGlobal);