mirror of
https://github.com/zen-browser/desktop.git
synced 2026-08-28 01:11:32 +00:00
Merge branch 'dev' into boosts
This commit is contained in:
@@ -1,32 +1,40 @@
|
||||
diff --git a/browser/base/content/browser-box.inc.xhtml b/browser/base/content/browser-box.inc.xhtml
|
||||
index d58fcdf99843d110b708f3fbf9fb317787fadfcf..ba37068c52b24c6ebcb835c59b43ca2f1621a001 100644
|
||||
index d58fcdf99843d110b708f3fbf9fb317787fadfcf..cfc2aad902641609c3804e615c4cb66ce65299b7 100644
|
||||
--- a/browser/base/content/browser-box.inc.xhtml
|
||||
+++ b/browser/base/content/browser-box.inc.xhtml
|
||||
@@ -3,6 +3,9 @@
|
||||
@@ -3,12 +3,22 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
<hbox flex="1" id="browser">
|
||||
+#include navigator-toolbox.inc.xhtml
|
||||
+ <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">
|
||||
<html:sidebar-main flex="1">
|
||||
<box id="vertical-tabs" slot="tabstrip" customizable="true" contextmenu="toolbar-context-menu"></box>
|
||||
@@ -25,7 +28,13 @@
|
||||
</stack>
|
||||
</vbox>
|
||||
<splitter id="sidebar-splitter" class="chromeclass-extrachrome sidebar-splitter" resizebefore="sibling" resizeafter="none" hidden="true"/>
|
||||
</html:sidebar-main>
|
||||
</box>
|
||||
<splitter id="sidebar-launcher-splitter" class="chromeclass-extrachrome sidebar-splitter" resizebefore="sibling" resizeafter="none" hidden="true"/>
|
||||
+<vbox flex="1" id="zen-appcontent-wrapper">
|
||||
+ <html:div id="zen-appcontent-navbar-wrapper" class="chromeclass-location">
|
||||
+ <html:div id="zen-appcontent-navbar-container"></html:div>
|
||||
+ </html:div>
|
||||
+ <hbox id="zen-tabbox-wrapper" flex="1">
|
||||
<tabbox id="tabbrowser-tabbox" flex="1" tabcontainer="tabbrowser-tabs">
|
||||
+<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">
|
||||
<box id="sidebar-header" align="center">
|
||||
<toolbarbutton id="sidebar-switcher-target" class="tabbable" aria-expanded="false">
|
||||
@@ -25,7 +35,7 @@
|
||||
</stack>
|
||||
</vbox>
|
||||
<splitter id="sidebar-splitter" class="chromeclass-extrachrome sidebar-splitter" resizebefore="sibling" resizeafter="none" hidden="true"/>
|
||||
- <tabbox id="tabbrowser-tabbox" flex="1" tabcontainer="tabbrowser-tabs">
|
||||
+#include zen-tabbrowser-elements.inc.xhtml
|
||||
<tabpanels id="tabbrowser-tabpanels" flex="1" selectedIndex="0"/>
|
||||
</tabbox>
|
||||
<splitter id="ai-window-splitter" class="chromeclass-extrachrome sidebar-splitter" resizebefore="none" resizeafter="sibling" collapsed="true"/>
|
||||
@@ -34,3 +43,5 @@
|
||||
@@ -34,3 +44,5 @@
|
||||
</stack>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/base/content/browser.xhtml b/browser/base/content/browser.xhtml
|
||||
index b42287485c2baeabe831b0d54c6f09330b0caabd..6426bb6742401470e4e48b4049cd365e2a5952e8 100644
|
||||
index b42287485c2baeabe831b0d54c6f09330b0caabd..e404c2e028e24eb4fa9b97f143ba476c1b1461fd 100644
|
||||
--- a/browser/base/content/browser.xhtml
|
||||
+++ b/browser/base/content/browser.xhtml
|
||||
@@ -19,6 +19,7 @@
|
||||
@@ -21,12 +21,12 @@ index b42287485c2baeabe831b0d54c6f09330b0caabd..6426bb6742401470e4e48b4049cd365e
|
||||
</head>
|
||||
<html:body xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
# All sets except for popupsets (commands, keys, and stringbundles)
|
||||
@@ -135,9 +138,11 @@
|
||||
@@ -135,9 +138,10 @@
|
||||
</vbox>
|
||||
</html:template>
|
||||
|
||||
-#include navigator-toolbox.inc.xhtml
|
||||
+<hbox id="zen-main-app-wrapper" flex="1" class="browser-toolbox-background">
|
||||
#include navigator-toolbox.inc.xhtml
|
||||
|
||||
#include browser-box.inc.xhtml
|
||||
+</hbox>
|
||||
|
||||
@@ -39,15 +39,3 @@
|
||||
# file so that ESLint works correctly:
|
||||
# tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js
|
||||
<script type="text/javascript" src="chrome://browser/content/ZenPreloadedScripts.js"></script>
|
||||
|
||||
# Scripts used all over the browser
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenMediaController.mjs"></script>
|
||||
<script type="module" src="resource:///modules/zen/ZenSpaceCreation.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenGlanceManager.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenPinnedTabManager.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenViewSplitter.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenFolder.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenFolders.mjs"></script>s
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenDownloadAnimation.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenEmojiPicker.mjs"></script>
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenLiveFoldersUI.mjs"></script>
|
||||
|
||||
@@ -8,5 +8,3 @@
|
||||
<script type="text/javascript" src="chrome://browser/content/zen-sets.js"></script>
|
||||
|
||||
<script type="module" src="chrome://browser/content/zen-components/ZenHasPolyfill.mjs"></script>
|
||||
<script type="module" src="resource:///modules/zen/ZenSpace.mjs"></script>
|
||||
<script type="module" src="resource:///modules/zen/ZenSpaceIcons.mjs"></script>
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/preferences/main.js b/browser/components/preferences/main.js
|
||||
index 8f8da3c4cabb4a05b50431b1feeff8f1f1abcf6e..97c651cb3728353b9a0d09d1aaa9ba87f8c05b57 100644
|
||||
index 8f8da3c4cabb4a05b50431b1feeff8f1f1abcf6e..e57102247eb739ed431bd838a3004b353342defb 100644
|
||||
--- a/browser/components/preferences/main.js
|
||||
+++ b/browser/components/preferences/main.js
|
||||
@@ -2658,6 +2658,11 @@ function createStartupConfig(hidden = false) {
|
||||
@@ -14,6 +14,15 @@ index 8f8da3c4cabb4a05b50431b1feeff8f1f1abcf6e..97c651cb3728353b9a0d09d1aaa9ba87
|
||||
{
|
||||
id: "windowsLaunchOnLogin",
|
||||
l10nId: "windows-launch-on-login",
|
||||
@@ -2755,7 +2760,7 @@ SettingGroupManager.registerGroups({
|
||||
},
|
||||
defaultBrowser: createDefaultBrowserConfig(),
|
||||
startup: createStartupConfig(
|
||||
- Services.prefs.getBoolPref("browser.settings-redesign.enabled", false)
|
||||
+ false
|
||||
),
|
||||
importBrowserData: {
|
||||
l10nId: "preferences-data-migration-group",
|
||||
@@ -5174,7 +5179,7 @@ function getBundleForLocales(newLocales) {
|
||||
])
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs
|
||||
index 71921cec2b6aa0f103856c31254fd6c4affefccb..fbb44402e3201a00eb37765d60829828d40e70ea 100644
|
||||
index 71921cec2b6aa0f103856c31254fd6c4affefccb..ed13d7e2aa5ff1199872fedbc26494aae463ace4 100644
|
||||
--- a/browser/components/sessionstore/SessionStore.sys.mjs
|
||||
+++ b/browser/components/sessionstore/SessionStore.sys.mjs
|
||||
@@ -129,6 +129,9 @@ const TAB_EVENTS = [
|
||||
@@ -350,3 +350,19 @@ index 71921cec2b6aa0f103856c31254fd6c4affefccb..fbb44402e3201a00eb37765d60829828
|
||||
// Convert any open groups into saved groups.
|
||||
let groupStateToSave = window.groups.find(
|
||||
groupState => groupState.id == window.tabs[tIndex].groupId
|
||||
@@ -8076,7 +8139,6 @@ var SessionStoreInternal = {
|
||||
timer.initWithCallback(
|
||||
function () {
|
||||
if (beats <= 0) {
|
||||
- this._log.debug(`looseTimer of ${delay} timed out`);
|
||||
Glean.sessionRestore.shutdownFlushAllOutcomes.timed_out.add(1);
|
||||
deferred.resolve();
|
||||
}
|
||||
@@ -8552,6 +8614,7 @@ var SessionStoreInternal = {
|
||||
if (
|
||||
!savedTabGroupState.tabs.length ||
|
||||
this.getSavedTabGroup(savedTabGroupState.id)
|
||||
+ && false
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/tabbrowser/content/tab.js b/browser/components/tabbrowser/content/tab.js
|
||||
index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..439766a40df5632ad790ab54a0c6af78a831e8ee 100644
|
||||
index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..3ac8d2facb224ae39d2199f2c5ec08b77e0c1dfd 100644
|
||||
--- a/browser/components/tabbrowser/content/tab.js
|
||||
+++ b/browser/components/tabbrowser/content/tab.js
|
||||
@@ -21,6 +21,7 @@
|
||||
@@ -151,7 +151,18 @@ index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..439766a40df5632ad790ab54a0c6af78
|
||||
on_click(event) {
|
||||
if (event.button != 0) {
|
||||
return;
|
||||
@@ -620,11 +659,12 @@
|
||||
@@ -617,14 +656,23 @@
|
||||
trigger: "alt_click",
|
||||
});
|
||||
}
|
||||
+ if (
|
||||
+ !event.target.classList.contains("tab-close-button") &&
|
||||
+ !event.target.classList.contains("tab-icon-overlay") &&
|
||||
+ !event.target.classList.contains("tab-audio-button") &&
|
||||
+ !this.splitView
|
||||
+ ) {
|
||||
+ gZenViewSplitter.contextSplitTabs(this);
|
||||
+ }
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -165,7 +176,7 @@ index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..439766a40df5632ad790ab54a0c6af78
|
||||
gBrowser.multiSelectedTabsCount > 0 &&
|
||||
!event.target.classList.contains("tab-close-button") &&
|
||||
!event.target.classList.contains("tab-icon-overlay") &&
|
||||
@@ -636,8 +676,9 @@
|
||||
@@ -636,8 +684,9 @@
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -177,7 +188,7 @@ index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..439766a40df5632ad790ab54a0c6af78
|
||||
) {
|
||||
if (this.activeMediaBlocked) {
|
||||
if (this.multiselected) {
|
||||
@@ -655,7 +696,7 @@
|
||||
@@ -655,7 +704,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -186,7 +197,7 @@ index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..439766a40df5632ad790ab54a0c6af78
|
||||
if (this.multiselected) {
|
||||
gBrowser.removeMultiSelectedTabs(
|
||||
lazy.TabMetrics.userTriggeredContext(
|
||||
@@ -675,6 +716,14 @@
|
||||
@@ -675,6 +724,14 @@
|
||||
// (see tabbrowser-tabs 'click' handler).
|
||||
gBrowser.tabContainer._blockDblClick = true;
|
||||
}
|
||||
@@ -201,7 +212,7 @@ index 2e02bad1a7c89b4c3b5aee1e14c13bb953a64eb6..439766a40df5632ad790ab54a0c6af78
|
||||
}
|
||||
|
||||
on_dblclick(event) {
|
||||
@@ -698,6 +747,8 @@
|
||||
@@ -698,6 +755,8 @@
|
||||
animate: true,
|
||||
triggeringEvent: event,
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
|
||||
index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25b964ccbb 100644
|
||||
index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..d16fe62c8a67913dd1499b2665a22ff606d98f1e 100644
|
||||
--- a/browser/components/tabbrowser/content/tabbrowser.js
|
||||
+++ b/browser/components/tabbrowser/content/tabbrowser.js
|
||||
@@ -413,6 +413,7 @@
|
||||
@@ -466,7 +466,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
);
|
||||
tabsFragment.appendChild(tabGroup.node);
|
||||
}
|
||||
@@ -4598,9 +4729,22 @@
|
||||
@@ -4598,9 +4729,23 @@
|
||||
// to remove the old selected tab.
|
||||
if (tabToSelect) {
|
||||
let leftoverTab = this.selectedTab;
|
||||
@@ -483,13 +483,14 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ gZenWorkspaces._keepSelectedTab = true;
|
||||
+ gZenWorkspaces._keepSelectedTab = !window.__isNewZenWindow;
|
||||
}
|
||||
+ delete window.__isNewZenWindow;
|
||||
+ this._hasAlreadyInitializedZenSessionStore = true;
|
||||
|
||||
if (tabs.length > 1 || !tabs[0].selected) {
|
||||
this._updateTabsAfterInsert();
|
||||
@@ -4791,11 +4935,14 @@
|
||||
@@ -4791,11 +4936,14 @@
|
||||
if (ownerTab) {
|
||||
tab.owner = ownerTab;
|
||||
}
|
||||
@@ -505,7 +506,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
if (
|
||||
!bulkOrderedOpen &&
|
||||
((openerTab &&
|
||||
@@ -4807,7 +4954,7 @@
|
||||
@@ -4807,7 +4955,7 @@
|
||||
let lastRelatedTab =
|
||||
openerTab && this._lastRelatedTabMap.get(openerTab);
|
||||
let previousTab = lastRelatedTab || openerTab || this.selectedTab;
|
||||
@@ -514,7 +515,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
tabGroup = previousTab.group;
|
||||
}
|
||||
if (
|
||||
@@ -4823,7 +4970,7 @@
|
||||
@@ -4823,7 +4971,7 @@
|
||||
previousTab.splitview
|
||||
) + 1;
|
||||
} else if (previousTab.visible) {
|
||||
@@ -523,7 +524,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
} else if (previousTab == FirefoxViewHandler.tab) {
|
||||
elementIndex = 0;
|
||||
}
|
||||
@@ -4851,14 +4998,14 @@
|
||||
@@ -4851,14 +4999,14 @@
|
||||
}
|
||||
// Ensure index is within bounds.
|
||||
if (tab.pinned) {
|
||||
@@ -542,7 +543,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
|
||||
if (pinned && !itemAfter?.pinned) {
|
||||
itemAfter = null;
|
||||
@@ -4875,7 +5022,7 @@
|
||||
@@ -4875,7 +5023,7 @@
|
||||
|
||||
this.tabContainer._invalidateCachedTabs();
|
||||
|
||||
@@ -551,7 +552,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
if (
|
||||
(this.isTab(itemAfter) && itemAfter.group == tabGroup) ||
|
||||
this.isSplitViewWrapper(itemAfter)
|
||||
@@ -4906,7 +5053,11 @@
|
||||
@@ -4906,7 +5054,11 @@
|
||||
const tabContainer = pinned
|
||||
? this.tabContainer.pinnedTabsContainer
|
||||
: this.tabContainer;
|
||||
@@ -563,7 +564,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
}
|
||||
|
||||
if (tab.group?.collapsed) {
|
||||
@@ -4921,6 +5072,7 @@
|
||||
@@ -4921,6 +5073,7 @@
|
||||
if (pinned) {
|
||||
this._updateTabBarForPinnedTabs();
|
||||
}
|
||||
@@ -571,7 +572,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
|
||||
TabBarVisibility.update();
|
||||
}
|
||||
@@ -5469,6 +5621,7 @@
|
||||
@@ -5469,6 +5622,7 @@
|
||||
telemetrySource,
|
||||
} = {}
|
||||
) {
|
||||
@@ -579,7 +580,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
// When 'closeWindowWithLastTab' pref is enabled, closing all tabs
|
||||
// can be considered equivalent to closing the window.
|
||||
if (
|
||||
@@ -5558,6 +5711,7 @@
|
||||
@@ -5558,6 +5712,7 @@
|
||||
if (lastToClose) {
|
||||
this.removeTab(lastToClose, aParams);
|
||||
}
|
||||
@@ -587,7 +588,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
@@ -5603,6 +5757,13 @@
|
||||
@@ -5603,6 +5758,14 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -597,11 +598,12 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
+ this.selectedTab = newTab;
|
||||
+ }
|
||||
+ }
|
||||
+ animate &&= !aTab.group?.hasAttribute("split-view-group");
|
||||
+
|
||||
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
|
||||
@@ -5610,6 +5771,9 @@
|
||||
@@ -5610,6 +5773,9 @@
|
||||
// state).
|
||||
let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width;
|
||||
let isLastTab = this.#isLastTabInWindow(aTab);
|
||||
@@ -611,7 +613,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
if (
|
||||
!this._beginRemoveTab(aTab, {
|
||||
closeWindowFastpath: true,
|
||||
@@ -5621,13 +5785,14 @@
|
||||
@@ -5621,13 +5787,14 @@
|
||||
telemetrySource,
|
||||
})
|
||||
) {
|
||||
@@ -627,7 +629,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
let lockTabSizing =
|
||||
!this.tabContainer.verticalMode &&
|
||||
!aTab.pinned &&
|
||||
@@ -5658,7 +5823,13 @@
|
||||
@@ -5658,7 +5825,13 @@
|
||||
// We're not animating, so we can cancel the animation stopwatch.
|
||||
Glean.browserTabclose.timeAnim.cancel(aTab._closeTimeAnimTimerId);
|
||||
aTab._closeTimeAnimTimerId = null;
|
||||
@@ -642,7 +644,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5792,7 +5963,7 @@
|
||||
@@ -5792,7 +5965,7 @@
|
||||
closeWindowWithLastTab != null
|
||||
? closeWindowWithLastTab
|
||||
: !window.toolbar.visible ||
|
||||
@@ -651,7 +653,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
|
||||
if (closeWindow) {
|
||||
// We've already called beforeunload on all the relevant tabs if we get here,
|
||||
@@ -5816,6 +5987,7 @@
|
||||
@@ -5816,6 +5989,7 @@
|
||||
|
||||
newTab = true;
|
||||
}
|
||||
@@ -659,7 +661,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
aTab._endRemoveArgs = [closeWindow, newTab];
|
||||
|
||||
// swapBrowsersAndCloseOther will take care of closing the window without animation.
|
||||
@@ -5856,13 +6028,7 @@
|
||||
@@ -5856,13 +6030,7 @@
|
||||
aTab._mouseleave();
|
||||
|
||||
if (newTab) {
|
||||
@@ -674,7 +676,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
} else {
|
||||
TabBarVisibility.update();
|
||||
}
|
||||
@@ -5995,6 +6161,7 @@
|
||||
@@ -5995,6 +6163,7 @@
|
||||
this.tabs[i]._tPos = i;
|
||||
}
|
||||
|
||||
@@ -682,7 +684,15 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
if (!this._windowIsClosing) {
|
||||
// update tab close buttons state
|
||||
this.tabContainer._updateCloseButtons();
|
||||
@@ -6225,6 +6392,7 @@
|
||||
@@ -6180,6 +6349,7 @@
|
||||
memory_after: await getTotalMemoryUsage(),
|
||||
time_to_unload_in_ms: timeElapsed,
|
||||
});
|
||||
+ return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6225,6 +6395,7 @@
|
||||
}
|
||||
|
||||
let excludeTabs = new Set(aExcludeTabs);
|
||||
@@ -690,7 +700,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
|
||||
// If this tab has a successor, it should be selectable, since
|
||||
// hiding or closing a tab removes that tab as a successor.
|
||||
@@ -6237,15 +6405,22 @@
|
||||
@@ -6237,15 +6408,22 @@
|
||||
!excludeTabs.has(aTab.owner) &&
|
||||
Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose")
|
||||
) {
|
||||
@@ -715,7 +725,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
let tab = this.tabContainer.findNextTab(aTab, {
|
||||
direction: 1,
|
||||
filter: _tab => remainingTabs.includes(_tab),
|
||||
@@ -6259,7 +6434,7 @@
|
||||
@@ -6259,7 +6437,7 @@
|
||||
}
|
||||
|
||||
if (tab) {
|
||||
@@ -724,7 +734,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
}
|
||||
|
||||
// If no qualifying visible tab was found, see if there is a tab in
|
||||
@@ -6280,7 +6455,7 @@
|
||||
@@ -6280,7 +6458,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
@@ -733,7 +743,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
}
|
||||
|
||||
_blurTab(aTab) {
|
||||
@@ -6291,7 +6466,7 @@
|
||||
@@ -6291,7 +6469,7 @@
|
||||
* @returns {boolean}
|
||||
* False if swapping isn't permitted, true otherwise.
|
||||
*/
|
||||
@@ -742,7 +752,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
// Do not allow transfering a private tab to a non-private window
|
||||
// and vice versa.
|
||||
if (
|
||||
@@ -6345,6 +6520,7 @@
|
||||
@@ -6345,6 +6523,7 @@
|
||||
// fire the beforeunload event in the process. Close the other
|
||||
// window if this was its last tab.
|
||||
if (
|
||||
@@ -750,7 +760,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
!remoteBrowser._beginRemoveTab(aOtherTab, {
|
||||
adoptedByTab: aOurTab,
|
||||
closeWindowWithLastTab: true,
|
||||
@@ -6356,7 +6532,7 @@
|
||||
@@ -6356,7 +6535,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.
|
||||
@@ -759,7 +769,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
if (closeWindow) {
|
||||
let win = aOtherTab.ownerGlobal;
|
||||
win.windowUtils.suppressAnimation(true);
|
||||
@@ -6484,11 +6660,13 @@
|
||||
@@ -6484,11 +6663,13 @@
|
||||
}
|
||||
|
||||
// Finish tearing down the tab that's going away.
|
||||
@@ -773,7 +783,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
|
||||
this.setTabTitle(aOurTab);
|
||||
|
||||
@@ -6690,10 +6868,10 @@
|
||||
@@ -6690,10 +6871,10 @@
|
||||
SessionStore.deleteCustomTabValue(aTab, "hiddenBy");
|
||||
}
|
||||
|
||||
@@ -786,7 +796,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
aTab.selected ||
|
||||
aTab.closing ||
|
||||
// Tabs that are sharing the screen, microphone or camera cannot be hidden.
|
||||
@@ -6753,7 +6931,8 @@
|
||||
@@ -6753,7 +6934,8 @@
|
||||
* @param {object} [aOptions={}]
|
||||
* Key-value pairs that will be serialized into the features string.
|
||||
*/
|
||||
@@ -796,7 +806,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
if (this.tabs.length == 1) {
|
||||
return null;
|
||||
}
|
||||
@@ -6770,7 +6949,7 @@
|
||||
@@ -6770,7 +6952,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);
|
||||
@@ -805,7 +815,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
private: PrivateBrowsingUtils.isWindowPrivate(window),
|
||||
features: Object.entries(aOptions)
|
||||
.map(([key, value]) => `${key}=${value}`)
|
||||
@@ -6778,6 +6957,8 @@
|
||||
@@ -6778,6 +6960,8 @@
|
||||
openerWindow: window,
|
||||
args,
|
||||
});
|
||||
@@ -814,7 +824,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6890,7 +7071,7 @@
|
||||
@@ -6890,7 +7074,7 @@
|
||||
* `true` if element is a `<tab-group>`
|
||||
*/
|
||||
isTabGroup(element) {
|
||||
@@ -823,7 +833,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6975,8 +7156,8 @@
|
||||
@@ -6975,8 +7159,8 @@
|
||||
}
|
||||
|
||||
// Don't allow mixing pinned and unpinned tabs.
|
||||
@@ -834,7 +844,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
} else {
|
||||
tabIndex = Math.max(tabIndex, this.pinnedTabCount);
|
||||
}
|
||||
@@ -7005,13 +7186,19 @@
|
||||
@@ -7005,13 +7189,19 @@
|
||||
this.#handleTabMove(
|
||||
element,
|
||||
() => {
|
||||
@@ -856,7 +866,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
let useAfter = false;
|
||||
if (this.isTab(element)) {
|
||||
useAfter = neighbor && tabIndex > element._tPos;
|
||||
@@ -7076,23 +7263,31 @@
|
||||
@@ -7076,23 +7266,31 @@
|
||||
#moveTabNextTo(element, targetElement, moveBefore = false, metricsContext) {
|
||||
if (this.isTabGroupLabel(targetElement)) {
|
||||
targetElement = targetElement.group;
|
||||
@@ -894,7 +904,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
} 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
|
||||
@@ -7105,12 +7300,35 @@
|
||||
@@ -7105,12 +7303,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.
|
||||
@@ -931,7 +941,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
|
||||
// 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.
|
||||
@@ -7119,6 +7337,7 @@
|
||||
@@ -7119,6 +7340,7 @@
|
||||
}
|
||||
|
||||
let getContainer = () =>
|
||||
@@ -939,7 +949,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
element.pinned
|
||||
? this.tabContainer.pinnedTabsContainer
|
||||
: this.tabContainer;
|
||||
@@ -7127,11 +7346,15 @@
|
||||
@@ -7127,11 +7349,15 @@
|
||||
element,
|
||||
() => {
|
||||
if (moveBefore) {
|
||||
@@ -956,7 +966,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
}
|
||||
},
|
||||
metricsContext
|
||||
@@ -7205,10 +7428,10 @@
|
||||
@@ -7205,11 +7431,15 @@
|
||||
* @param {TabMetricsContext} [metricsContext]
|
||||
*/
|
||||
moveTabToExistingGroup(aTab, aGroup, metricsContext) {
|
||||
@@ -965,11 +975,17 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
throw new Error("Can only move a tab into a tab group");
|
||||
}
|
||||
- if (aTab.pinned) {
|
||||
- return;
|
||||
+ if (aTab.pinned != !!aGroup.pinned) {
|
||||
return;
|
||||
+ if (aGroup.pinned) {
|
||||
+ this.pinTab(aTab);
|
||||
+ } else {
|
||||
+ this.unpinTab(aTab);
|
||||
+ }
|
||||
}
|
||||
if (aTab.group && aTab.group.id === aGroup.id) {
|
||||
@@ -7281,6 +7504,7 @@
|
||||
return;
|
||||
@@ -7281,6 +7511,7 @@
|
||||
|
||||
let state = {
|
||||
tabIndex: tab._tPos,
|
||||
@@ -977,7 +993,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
};
|
||||
if (tab.visible) {
|
||||
state.elementIndex = tab.elementIndex;
|
||||
@@ -7312,7 +7536,7 @@
|
||||
@@ -7312,7 +7543,7 @@
|
||||
let changedSplitView =
|
||||
previousTabState.splitViewId != currentTabState.splitViewId;
|
||||
|
||||
@@ -986,7 +1002,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
tab.dispatchEvent(
|
||||
new CustomEvent("TabMove", {
|
||||
bubbles: true,
|
||||
@@ -7354,6 +7578,10 @@
|
||||
@@ -7354,6 +7585,10 @@
|
||||
|
||||
moveActionCallback();
|
||||
|
||||
@@ -997,7 +1013,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
// Clear tabs cache after moving nodes because the order of tabs may have
|
||||
// changed.
|
||||
this.tabContainer._invalidateCachedTabs();
|
||||
@@ -7404,7 +7632,22 @@
|
||||
@@ -7404,7 +7639,22 @@
|
||||
* @returns {object}
|
||||
* The new tab in the current window, null if the tab couldn't be adopted.
|
||||
*/
|
||||
@@ -1021,7 +1037,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
// 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
|
||||
@@ -7447,6 +7690,8 @@
|
||||
@@ -7447,6 +7697,8 @@
|
||||
}
|
||||
params.skipLoad = true;
|
||||
let newTab = this.addWebTab("about:blank", params);
|
||||
@@ -1030,7 +1046,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
|
||||
aTab.container.tabDragAndDrop.finishAnimateTabMove();
|
||||
|
||||
@@ -8149,7 +8394,7 @@
|
||||
@@ -8149,7 +8401,7 @@
|
||||
// preventDefault(). It will still raise the window if appropriate.
|
||||
return;
|
||||
}
|
||||
@@ -1039,7 +1055,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
window.focus();
|
||||
aEvent.preventDefault();
|
||||
}
|
||||
@@ -8166,7 +8411,6 @@
|
||||
@@ -8166,7 +8418,6 @@
|
||||
|
||||
on_TabGroupCollapse(aEvent) {
|
||||
aEvent.target.tabs.forEach(tab => {
|
||||
@@ -1047,7 +1063,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8500,7 +8744,9 @@
|
||||
@@ -8500,7 +8751,9 @@
|
||||
|
||||
let filter = this._tabFilters.get(tab);
|
||||
if (filter) {
|
||||
@@ -1057,7 +1073,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
|
||||
let listener = this._tabListeners.get(tab);
|
||||
if (listener) {
|
||||
@@ -9306,6 +9552,7 @@
|
||||
@@ -9306,6 +9559,7 @@
|
||||
aWebProgress.isTopLevel
|
||||
) {
|
||||
this.mTab.setAttribute("busy", "true");
|
||||
@@ -1065,7 +1081,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
gBrowser._tabAttrModified(this.mTab, ["busy"]);
|
||||
this.mTab._notselectedsinceload = !this.mTab.selected;
|
||||
}
|
||||
@@ -9386,6 +9633,7 @@
|
||||
@@ -9386,6 +9640,7 @@
|
||||
// known defaults. Note we use the original URL since about:newtab
|
||||
// redirects to a prerendered page.
|
||||
const shouldRemoveFavicon =
|
||||
@@ -1073,7 +1089,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
!this.mBrowser.mIconURL &&
|
||||
!ignoreBlank &&
|
||||
!(originalLocation.spec in FAVICON_DEFAULTS);
|
||||
@@ -9560,13 +9808,6 @@
|
||||
@@ -9560,13 +9815,6 @@
|
||||
this.mBrowser.originalURI = aRequest.originalURI;
|
||||
}
|
||||
|
||||
@@ -1087,7 +1103,7 @@ index 2643e1a2aa14ba5cb4a64a92e1c2dfa5f07d242f..642b74cdf0edc63e5cf4ca8c69481e25
|
||||
}
|
||||
|
||||
let userContextId = this.mBrowser.getAttribute("usercontextid") || 0;
|
||||
@@ -10450,7 +10691,7 @@ var TabContextMenu = {
|
||||
@@ -10450,7 +10698,7 @@ var TabContextMenu = {
|
||||
);
|
||||
contextUnpinSelectedTabs.hidden =
|
||||
!this.contextTab.pinned || !this.multiselected;
|
||||
|
||||
@@ -498,7 +498,7 @@ groupbox h2 {
|
||||
#category-ai-features,
|
||||
#setting-control-supportFirefox,
|
||||
.mission-message,
|
||||
html|setting-group[data-subcategory="layout"] {
|
||||
html|setting-group:is([data-subcategory="layout"], [groupid="support"]) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/themes/shared/tabbrowser/tabs.css b/browser/themes/shared/tabbrowser/tabs.css
|
||||
index 203b546933842f4b0134188fda020c4db4dcd0d2..011bcfb023d0cabd55dfa7e49d3409383217e2ca 100644
|
||||
index 203b546933842f4b0134188fda020c4db4dcd0d2..0d67deabac2984574636248a16e58d1669f2e1a4 100644
|
||||
--- a/browser/themes/shared/tabbrowser/tabs.css
|
||||
+++ b/browser/themes/shared/tabbrowser/tabs.css
|
||||
@@ -24,7 +24,7 @@
|
||||
@@ -97,7 +97,15 @@ index 203b546933842f4b0134188fda020c4db4dcd0d2..011bcfb023d0cabd55dfa7e49d340938
|
||||
&:is([soundplaying], [muted], [activemedia-blocked]) {
|
||||
display: flex;
|
||||
}
|
||||
@@ -1614,7 +1606,7 @@ tab-group {
|
||||
@@ -1048,7 +1040,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]) {
|
||||
- background-image: radial-gradient(circle, var(--tab-attention-dot-color), var(--tab-attention-dot-color) 2px, transparent 2px);
|
||||
background-position: center bottom 6.5px;
|
||||
background-size: 4px 4px;
|
||||
background-repeat: no-repeat;
|
||||
@@ -1614,7 +1605,7 @@ tab-group {
|
||||
}
|
||||
|
||||
#tabbrowser-tabs[orient="vertical"][expanded] {
|
||||
@@ -106,7 +114,7 @@ index 203b546933842f4b0134188fda020c4db4dcd0d2..011bcfb023d0cabd55dfa7e49d340938
|
||||
&[movingtab][movingtab-addToGroup]:not([movingtab-group], [movingtab-ungroup]) tab-group > .tabbrowser-tab:is(:active, [multiselected]) {
|
||||
margin-inline-start: var(--space-medium);
|
||||
}
|
||||
@@ -2089,7 +2081,7 @@ tab-group {
|
||||
@@ -2089,7 +2080,7 @@ tab-group {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +123,7 @@ index 203b546933842f4b0134188fda020c4db4dcd0d2..011bcfb023d0cabd55dfa7e49d340938
|
||||
#vertical-tabs-newtab-button {
|
||||
appearance: none;
|
||||
min-height: var(--tab-min-height);
|
||||
@@ -2100,7 +2092,7 @@ tab-group {
|
||||
@@ -2100,7 +2091,7 @@ tab-group {
|
||||
margin-inline: var(--tab-inner-inline-margin);
|
||||
|
||||
#tabbrowser-tabs[orient="vertical"]:not([expanded]) & > .toolbarbutton-text {
|
||||
@@ -124,7 +132,7 @@ index 203b546933842f4b0134188fda020c4db4dcd0d2..011bcfb023d0cabd55dfa7e49d340938
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@@ -2124,7 +2116,7 @@ tab-group {
|
||||
@@ -2124,7 +2115,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.
|
||||
*/
|
||||
@@ -133,7 +141,7 @@ index 203b546933842f4b0134188fda020c4db4dcd0d2..011bcfb023d0cabd55dfa7e49d340938
|
||||
margin-block: var(--tab-block-margin);
|
||||
}
|
||||
|
||||
@@ -2312,7 +2304,6 @@ tab-group {
|
||||
@@ -2312,7 +2303,6 @@ tab-group {
|
||||
|
||||
&:not([expanded]) {
|
||||
.tabbrowser-tab[pinned] {
|
||||
@@ -141,7 +149,7 @@ index 203b546933842f4b0134188fda020c4db4dcd0d2..011bcfb023d0cabd55dfa7e49d340938
|
||||
}
|
||||
|
||||
.tab-background {
|
||||
@@ -2352,8 +2343,8 @@ tab-group {
|
||||
@@ -2352,8 +2342,8 @@ tab-group {
|
||||
display: block;
|
||||
position: absolute;
|
||||
inset: auto;
|
||||
@@ -152,7 +160,7 @@ index 203b546933842f4b0134188fda020c4db4dcd0d2..011bcfb023d0cabd55dfa7e49d340938
|
||||
|
||||
&:-moz-window-inactive {
|
||||
background-image:
|
||||
@@ -2438,9 +2429,6 @@ tab-group {
|
||||
@@ -2438,9 +2428,6 @@ tab-group {
|
||||
|
||||
:root:not([privatebrowsingmode]) :is(toolbarbutton, toolbarpaletteitem) ~ #tabbrowser-tabs,
|
||||
:root[privatebrowsingmode] :is(toolbarbutton:not(#firefox-view-button), toolbarpaletteitem:not(#wrapper-firefox-view-button)) ~ #tabbrowser-tabs {
|
||||
@@ -162,7 +170,7 @@ index 203b546933842f4b0134188fda020c4db4dcd0d2..011bcfb023d0cabd55dfa7e49d340938
|
||||
}
|
||||
|
||||
:root[privatebrowsingmode] :is(#firefox-view-button, #menu_openFirefoxView) {
|
||||
@@ -2472,7 +2460,6 @@ toolbar:not(#TabsToolbar) #firefox-view-button {
|
||||
@@ -2472,7 +2459,6 @@ toolbar:not(#TabsToolbar) #firefox-view-button {
|
||||
list-style-image: url(chrome://global/skin/icons/plus.svg);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
diff --git a/build/moz.configure/lto-pgo.configure b/build/moz.configure/lto-pgo.configure
|
||||
index df2b0bf0081edfdc2c7bccaefc780d2b0c6555ff..8619fc5fbf284c7a5660d5b7a77494404e448e44 100644
|
||||
index df2b0bf0081edfdc2c7bccaefc780d2b0c6555ff..53a3b55de7650799e3730372e72ad7b4bb2eea03 100644
|
||||
--- a/build/moz.configure/lto-pgo.configure
|
||||
+++ b/build/moz.configure/lto-pgo.configure
|
||||
@@ -256,7 +256,6 @@ option(
|
||||
@@ -234,6 +234,7 @@ def moz_pgo_rust(pgo, profile_use, profile_generate, c_compiler):
|
||||
if c_compiler.type == "gcc":
|
||||
die("Cannot use cross-language PGO with GCC.")
|
||||
|
||||
+ log.info("Enabling cross-language PGO for Rust")
|
||||
return True
|
||||
|
||||
|
||||
@@ -256,7 +257,6 @@ option(
|
||||
help="Indicate that ld64 is free of symbol aliasing bugs",
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +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
|
||||
--- 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);
|
||||
}
|
||||
}
|
||||
|
||||
13
src/tools/update-packaging/common-sh.patch
Normal file
13
src/tools/update-packaging/common-sh.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/tools/update-packaging/common.sh b/tools/update-packaging/common.sh
|
||||
index be2061b98cbba0d472e5f4d03cab2b058b249cb8..caa3379cd09efc2ded9686929fc658985a9dda51 100755
|
||||
--- a/tools/update-packaging/common.sh
|
||||
+++ b/tools/update-packaging/common.sh
|
||||
@@ -94,8 +94,6 @@ check_for_add_if_not_update() {
|
||||
|
||||
if [[ "$(basename "$add_if_not_file_chk")" = "channel-prefs.js" || \
|
||||
"$add_if_not_file_chk" =~ (^|/)ChannelPrefs\.framework/ || \
|
||||
- "$(basename "$add_if_not_file_chk")" = "update-settings.ini" || \
|
||||
- "$add_if_not_file_chk" =~ (^|/)UpdateSettings\.framework/ || \
|
||||
"$(basename "$add_if_not_file_chk")" = "distribution.ini" ]]; then
|
||||
## "true"
|
||||
return 0;
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/widget/cocoa/VibrancyManager.mm b/widget/cocoa/VibrancyManager.mm
|
||||
index 5df70a63afb235d2db11712276bb63f756222a0f..8ba0bf1b046f58d9776981e0872a78144bed5139 100644
|
||||
index 5df70a63afb235d2db11712276bb63f756222a0f..a2865aa2748433cbfd956ae46d197200fbbcfadd 100644
|
||||
--- a/widget/cocoa/VibrancyManager.mm
|
||||
+++ b/widget/cocoa/VibrancyManager.mm
|
||||
@@ -11,6 +11,7 @@
|
||||
@@ -10,7 +10,17 @@ index 5df70a63afb235d2db11712276bb63f756222a0f..8ba0bf1b046f58d9776981e0872a7814
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@@ -36,7 +37,23 @@ static NSVisualEffectMaterial VisualEffectMaterialForVibrancyType(
|
||||
@@ -29,6 +30,9 @@ static NSVisualEffectState VisualEffectStateForVibrancyType(
|
||||
case VibrancyType::Sidebar:
|
||||
break;
|
||||
}
|
||||
+ if (!StaticPrefs::zen_view_grey_out_inactive_windows()) {
|
||||
+ return NSVisualEffectStateActive;
|
||||
+ }
|
||||
return NSVisualEffectStateFollowsWindowActiveState;
|
||||
}
|
||||
|
||||
@@ -36,7 +40,23 @@ static NSVisualEffectMaterial VisualEffectMaterialForVibrancyType(
|
||||
VibrancyType aType) {
|
||||
switch (aType) {
|
||||
case VibrancyType::Sidebar:
|
||||
@@ -35,7 +45,7 @@ index 5df70a63afb235d2db11712276bb63f756222a0f..8ba0bf1b046f58d9776981e0872a7814
|
||||
case VibrancyType::Titlebar:
|
||||
return NSVisualEffectMaterialTitlebar;
|
||||
}
|
||||
@@ -76,6 +93,7 @@ static NSVisualEffectBlendingMode VisualEffectBlendingModeForVibrancyType(
|
||||
@@ -76,6 +96,7 @@ - (NSView*)hitTest:(NSPoint)aPoint {
|
||||
|
||||
- (void)prefChanged {
|
||||
self.blendingMode = VisualEffectBlendingModeForVibrancyType(mType);
|
||||
@@ -43,7 +53,7 @@ index 5df70a63afb235d2db11712276bb63f756222a0f..8ba0bf1b046f58d9776981e0872a7814
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -86,6 +104,7 @@ static void PrefChanged(const char* aPref, void* aClosure) {
|
||||
@@ -86,6 +107,7 @@ static void PrefChanged(const char* aPref, void* aClosure) {
|
||||
static constexpr nsLiteralCString kObservedPrefs[] = {
|
||||
"widget.macos.sidebar-blend-mode.behind-window"_ns,
|
||||
"widget.macos.titlebar-blend-mode.behind-window"_ns,
|
||||
|
||||
@@ -7,13 +7,52 @@
|
||||
{
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenSpaceBookmarksStorage.js", this);
|
||||
|
||||
ChromeUtils.importESModule("chrome://browser/content/ZenStartup.mjs", { global: "current" });
|
||||
ChromeUtils.importESModule("resource:///modules/zen/ZenSpaceManager.mjs", { global: "current" });
|
||||
ChromeUtils.importESModule("chrome://browser/content/zen-components/ZenCompactMode.mjs", { global: "current" });
|
||||
ChromeUtils.importESModule("chrome://browser/content/ZenUIManager.mjs", { global: "current" });
|
||||
ChromeUtils.importESModule("chrome://browser/content/zen-components/ZenMods.mjs", { global: "current" });
|
||||
ChromeUtils.importESModule("chrome://browser/content/zen-components/ZenKeyboardShortcuts.mjs", { global: "current" });
|
||||
ChromeUtils.importESModule("chrome://browser/content/zen-components/ZenSessionStore.mjs", { global: "current" });
|
||||
let scripts = [
|
||||
"chrome://browser/content/ZenStartup.mjs",
|
||||
"resource:///modules/zen/ZenSpaceManager.mjs",
|
||||
"chrome://browser/content/zen-components/ZenCompactMode.mjs",
|
||||
"chrome://browser/content/ZenUIManager.mjs",
|
||||
"chrome://browser/content/zen-components/ZenMods.mjs",
|
||||
"chrome://browser/content/zen-components/ZenKeyboardShortcuts.mjs",
|
||||
"chrome://browser/content/zen-components/ZenSessionStore.mjs",
|
||||
"chrome://browser/content/zen-components/ZenMediaController.mjs",
|
||||
"chrome://browser/content/zen-components/ZenGlanceManager.mjs",
|
||||
"chrome://browser/content/zen-components/ZenPinnedTabManager.mjs",
|
||||
"chrome://browser/content/zen-components/ZenViewSplitter.mjs",
|
||||
"chrome://browser/content/zen-components/ZenFolders.mjs",
|
||||
"chrome://browser/content/zen-components/ZenEmojiPicker.mjs",
|
||||
"chrome://browser/content/zen-components/ZenLiveFoldersUI.mjs",
|
||||
"chrome://browser/content/zen-components/ZenDownloadAnimation.mjs",
|
||||
];
|
||||
|
||||
for (let script of scripts) {
|
||||
ChromeUtils.importESModule(script, { global: "current" });
|
||||
}
|
||||
|
||||
let customZenElements = [
|
||||
["zen-folder", "chrome://browser/content/zen-components/ZenFolder.mjs"],
|
||||
["zen-workspace-creation", "resource:///modules/zen/ZenSpaceCreation.mjs"],
|
||||
["zen-workspace", "resource:///modules/zen/ZenSpace.mjs"],
|
||||
["zen-workspace-icons", "resource:///modules/zen/ZenSpaceIcons.mjs"]
|
||||
];
|
||||
|
||||
document.addEventListener(
|
||||
"DOMContentLoaded",
|
||||
() => {
|
||||
// Only sync-import widgets once the document has loaded. If a widget is
|
||||
// used before DOMContentLoaded it will be imported and upgraded when
|
||||
// registering the customElements.setElementCreationCallback().
|
||||
for (let [tag, script] of customZenElements) {
|
||||
customElements.setElementCreationCallback(
|
||||
tag,
|
||||
function customElementCreationCallback() {
|
||||
ChromeUtils.importESModule(script, { global: "current" });
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
|
||||
Services.scriptloader.loadSubScript("chrome://browser/content/zen-components/ZenDragAndDrop.js", this);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ class ZenStartup {
|
||||
|
||||
init() {
|
||||
this.openWatermark();
|
||||
this.#changeSidebarLocation();
|
||||
this.#zenInitBrowserLayout();
|
||||
}
|
||||
|
||||
@@ -147,21 +146,6 @@ class ZenStartup {
|
||||
});
|
||||
}
|
||||
|
||||
#changeSidebarLocation() {
|
||||
const kElementsToAppend = ["sidebar-splitter", "sidebar-box"];
|
||||
|
||||
const browser = document.getElementById("browser");
|
||||
browser.prepend(gNavToolbox);
|
||||
|
||||
const sidebarPanelWrapper = document.getElementById("tabbrowser-tabbox");
|
||||
for (let id of kElementsToAppend) {
|
||||
const elem = document.getElementById(id);
|
||||
if (elem) {
|
||||
sidebarPanelWrapper.prepend(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#initUIComponents() {
|
||||
const kUIComponents = ["ZenProgressBar"];
|
||||
for (let component of kUIComponents) {
|
||||
|
||||
@@ -101,10 +101,12 @@ window.gZenUIManager = {
|
||||
) {
|
||||
const yValues = rawKeyframes.y || [];
|
||||
const xValues = rawKeyframes.x || [];
|
||||
const scaleValues = rawKeyframes.scale || [];
|
||||
const scaleYValues = rawKeyframes.scaleY || [];
|
||||
const scaleXValues = rawKeyframes.scaleX || [];
|
||||
delete rawKeyframes.y;
|
||||
delete rawKeyframes.x;
|
||||
delete rawKeyframes.scale;
|
||||
delete rawKeyframes.scaleY;
|
||||
delete rawKeyframes.scaleX;
|
||||
rawKeyframes.transform = [];
|
||||
if (
|
||||
yValues.length !== 0 &&
|
||||
@@ -116,14 +118,17 @@ window.gZenUIManager = {
|
||||
const keyframeLength = Math.max(
|
||||
yValues.length,
|
||||
xValues.length,
|
||||
scaleValues.length
|
||||
scaleYValues.length,
|
||||
scaleXValues.length
|
||||
);
|
||||
for (let i = 0; i < keyframeLength; i++) {
|
||||
const y = yValues[i] !== undefined ? `translateY(${yValues[i]}px)` : "";
|
||||
const x = xValues[i] !== undefined ? `translateX(${xValues[i]}px)` : "";
|
||||
const scale =
|
||||
scaleValues[i] !== undefined ? `scale(${scaleValues[i]})` : "";
|
||||
rawKeyframes.transform.push(`${x} ${y} ${scale}`.trim());
|
||||
const scaleY =
|
||||
scaleYValues[i] !== undefined ? `scaleY(${scaleYValues[i]})` : "";
|
||||
const scaleX =
|
||||
scaleXValues[i] !== undefined ? `scaleX(${scaleXValues[i]})` : "";
|
||||
rawKeyframes.transform.push(`${x} ${y} ${scaleX} ${scaleY}`.trim());
|
||||
}
|
||||
}
|
||||
let keyframes = [];
|
||||
@@ -259,7 +264,7 @@ window.gZenUIManager = {
|
||||
);
|
||||
gURLBar.style.setProperty(
|
||||
"--zen-urlbar-width",
|
||||
`${Math.min(window.innerWidth / 2, 750)}px`
|
||||
`${Math.min(window.innerWidth / 1.5, 750)}px`
|
||||
);
|
||||
gZenVerticalTabsManager.actualWindowButtons.removeAttribute(
|
||||
"zen-has-hover"
|
||||
|
||||
@@ -58,18 +58,15 @@
|
||||
}
|
||||
|
||||
@keyframes zen-progress-bar-pulse {
|
||||
0% {
|
||||
transform: scale(0.8) translate(-50%, -50%);
|
||||
from {
|
||||
transform: scale(0.85) translate(-50%, -50%);
|
||||
opacity: 0.6;
|
||||
}
|
||||
50% {
|
||||
|
||||
to {
|
||||
transform: scale(0.95) translate(-50%, -50%);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(0.8) translate(-50%, -50%);
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes zen-progress-bar-long-load {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
}
|
||||
|
||||
&[transparent="true"] {
|
||||
background: light-dark(rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.1));
|
||||
background: light-dark(rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0.1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
body,
|
||||
#tabbrowser-tabpanels {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@
|
||||
background-color: var(--zen-urlbar-background-transparent, var(--zen-urlbar-background-base)) !important;
|
||||
box-shadow: 0 30px 140px -15px light-dark(rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0.6)) !important;
|
||||
backdrop-filter: none !important;
|
||||
outline: 0.5px solid light-dark(rgba(0, 0, 0, 0.3), rgba(255, 255, 255, 0.2)) !important;
|
||||
outline: 0.5px solid light-dark(rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.2)) !important;
|
||||
outline-offset: var(--zen-urlbar-outline-offset) !important;
|
||||
|
||||
/* stylelint-disable-next-line media-query-no-invalid */
|
||||
@@ -300,7 +300,7 @@
|
||||
|
||||
:root[zen-single-toolbar="true"] {
|
||||
--urlbar-icon-border-radius: 8px !important;
|
||||
--urlbar-inner-border-radius: var(--toolbarbutton-border-radius) !important;
|
||||
--urlbar-inner-border-radius: 6px !important;
|
||||
|
||||
#identity-permission-box > *:not(#zen-site-data-icon-button) {
|
||||
visibility: collapse;
|
||||
@@ -517,7 +517,7 @@
|
||||
margin-left: 0 !important;
|
||||
margin-right: 12px !important;
|
||||
padding: 6px !important;
|
||||
border-radius: 4px !important;
|
||||
border-radius: 3px !important;
|
||||
}
|
||||
|
||||
.urlbarView-userContext {
|
||||
@@ -584,6 +584,11 @@
|
||||
position: relative;
|
||||
scale: 0.93;
|
||||
transform-origin: right;
|
||||
opacity: 0.7;
|
||||
|
||||
.urlbarView-row[selected] & {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
@@ -635,7 +640,7 @@
|
||||
}
|
||||
|
||||
&[selected] {
|
||||
--zen-selected-bg: color-mix(in srgb, var(--zen-primary-color) 55%, light-dark(rgba(0, 0, 0, 0.5), rgba(255, 255, 255, 0.2)) 50%);
|
||||
--zen-selected-bg: color-mix(in srgb, var(--zen-primary-color) 50%, light-dark(rgba(0, 0, 0, 0.5), rgba(255, 255, 255, 0.1)));
|
||||
--zen-selected-color: color-mix(in srgb, var(--zen-selected-bg), black 30%);
|
||||
background-color: var(--zen-selected-bg) !important;
|
||||
|
||||
@@ -653,7 +658,7 @@
|
||||
color: var(--zen-selected-color) !important;
|
||||
}
|
||||
|
||||
&:where([type="switchtab"], [type="dynamic"], [type^="history"], [type^="autofill_"], [type="top_site"]) .urlbarView-favicon,
|
||||
&:where([type="switchtab"], [type="dynamic"], [type^="history"], [type^="autofill_"], [type="top_site"], [type="bookmark"]) .urlbarView-favicon,
|
||||
& .urlbarView-shortcutContent {
|
||||
fill: var(--zen-selected-color) !important;
|
||||
background-color: rgba(255, 255, 255, 0.9) !important;
|
||||
|
||||
@@ -736,7 +736,7 @@
|
||||
|
||||
/* Loading progress bar */
|
||||
#zen-loading-progress-bar {
|
||||
--zen-loading-progress-bar-color: color-mix(in srgb, var(--zen-primary-color), light-dark(rgba(0, 0, 0, 0.7), rgba(255, 255, 255, 0.7)) 70%);
|
||||
--zen-loading-progress-bar-color: color-mix(in srgb, var(--zen-primary-color), light-dark(rgba(0, 0, 0, 0.5), rgba(255, 255, 255, 0.5)) 70%);
|
||||
|
||||
position: fixed;
|
||||
|
||||
@@ -745,6 +745,7 @@
|
||||
:root:is([zen-no-padding="true"], [inDOMFullscreen="true"]) & {
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%) scale(0);
|
||||
background: var(--zen-loading-progress-bar-color);
|
||||
@@ -757,8 +758,10 @@
|
||||
transform .3s ease-in-out;
|
||||
overflow: clip;
|
||||
pointer-events: none;
|
||||
animation: zen-progress-bar-pulse 1.5s linear infinite forwards;
|
||||
animation: zen-progress-bar-pulse 1s ease-in-out infinite forwards;
|
||||
animation-direction: alternate;
|
||||
transform-origin: 0 0;
|
||||
contain: content;
|
||||
|
||||
&[long-load="true"] {
|
||||
opacity: 1;
|
||||
|
||||
@@ -70,18 +70,18 @@
|
||||
|
||||
--in-content-primary-button-background: color-mix(
|
||||
in srgb,
|
||||
var(--zen-primary-color) 30%,
|
||||
var(--zen-branding-bg-reverse) 70%
|
||||
var(--zen-primary-color) 40%,
|
||||
var(--zen-branding-bg-reverse)
|
||||
) !important;
|
||||
--in-content-primary-button-background-hover: color-mix(
|
||||
in srgb,
|
||||
var(--zen-primary-color) 35%,
|
||||
var(--zen-branding-bg-reverse) 65%
|
||||
var(--zen-primary-color) 45%,
|
||||
var(--zen-branding-bg-reverse)
|
||||
) !important;
|
||||
--in-content-primary-button-background-active: color-mix(
|
||||
in srgb,
|
||||
var(--zen-primary-color) 40%,
|
||||
var(--zen-branding-bg-reverse) 60%
|
||||
var(--zen-primary-color) 50%,
|
||||
var(--zen-branding-bg-reverse)
|
||||
) !important;
|
||||
--in-content-primary-button-text-color: var(--zen-branding-bg) !important;
|
||||
--in-content-primary-button-border-color: transparent !important;
|
||||
@@ -214,7 +214,7 @@
|
||||
--urlbar-margin-inline: 1px !important;
|
||||
|
||||
--tab-icon-overlay-stroke: light-dark(white, black) !important;
|
||||
--tab-close-button-padding: 5px !important;
|
||||
--tab-close-button-padding: 4px !important;
|
||||
|
||||
--input-border-color: var(--zen-input-border-color) !important;
|
||||
--zen-themed-toolbar-bg-transparent: light-dark(var(--zen-branding-bg), #171717);
|
||||
@@ -250,7 +250,7 @@
|
||||
--panel-separator-color: color-mix(in srgb, currentColor 15%, transparent) !important;
|
||||
|
||||
--zen-big-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
|
||||
--zen-active-tab-scale: 0.98;
|
||||
--zen-active-tab-scale: 0.99;
|
||||
|
||||
/* Define tab hover background color */
|
||||
--tab-hover-background-color: var(--toolbarbutton-hover-background);
|
||||
@@ -258,11 +258,13 @@
|
||||
/* Sidebar Notifications */
|
||||
--zen-sidebar-notification-bg: color-mix(
|
||||
in srgb,
|
||||
var(--zen-primary-color) 15%,
|
||||
var(--zen-primary-color) 5%,
|
||||
light-dark(white, black)
|
||||
);
|
||||
--zen-sidebar-notification-shadow: 0 0 6px light-dark(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.3));
|
||||
|
||||
--zen-sidebar-themed-icon-fill: light-dark(color-mix(in srgb, var(--zen-primary-color) 50%, black), color-mix(in srgb, var(--zen-colors-primary) 15%, #ebebeb));
|
||||
|
||||
--zen-native-inner-radius: var(
|
||||
--zen-webview-border-radius,
|
||||
/* Inner radius calculation:
|
||||
|
||||
@@ -10,6 +10,7 @@ export class ZenProgressBar extends ZenUIComponent {
|
||||
#element = null;
|
||||
#loadingTab = null;
|
||||
#longLoadTimer = null;
|
||||
#promise = null;
|
||||
|
||||
init() {
|
||||
this.listenBrowserTabsProgress();
|
||||
@@ -50,7 +51,7 @@ export class ZenProgressBar extends ZenUIComponent {
|
||||
this.window.gZenUIManager.elementAnimate(
|
||||
this.#element,
|
||||
{
|
||||
opacity: [0, 0.6],
|
||||
opacity: [0, 0.8],
|
||||
},
|
||||
{
|
||||
duration: 400,
|
||||
@@ -60,7 +61,8 @@ export class ZenProgressBar extends ZenUIComponent {
|
||||
return this.#element;
|
||||
}
|
||||
|
||||
#checkBrowserProgress(webProgress) {
|
||||
async #checkBrowserProgress(webProgress) {
|
||||
await this.#promise;
|
||||
const window = this.window;
|
||||
const gBrowser = window.gBrowser;
|
||||
const tab = gBrowser.getTabForBrowser(webProgress);
|
||||
@@ -74,7 +76,7 @@ export class ZenProgressBar extends ZenUIComponent {
|
||||
}
|
||||
}
|
||||
|
||||
#hideProgressBar() {
|
||||
#hideProgressBar(aInstant = false) {
|
||||
const progressBar = this.#element;
|
||||
const window = this.window;
|
||||
if (this.#longLoadTimer) {
|
||||
@@ -86,12 +88,15 @@ export class ZenProgressBar extends ZenUIComponent {
|
||||
if (!progressBar) {
|
||||
return;
|
||||
}
|
||||
let { promise, resolve } = Promise.withResolvers();
|
||||
this.#promise = promise;
|
||||
const callback = () => {
|
||||
delete progressBar._loadingTab;
|
||||
progressBar.remove();
|
||||
this.#element = null;
|
||||
resolve();
|
||||
};
|
||||
if (this.window.gReduceMotion) {
|
||||
if (this.window.gReduceMotion || aInstant) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
@@ -113,6 +118,11 @@ export class ZenProgressBar extends ZenUIComponent {
|
||||
if (this.#loadingTab === aTab) {
|
||||
return;
|
||||
}
|
||||
if (this.#element) {
|
||||
return;
|
||||
}
|
||||
let { promise, resolve } = Promise.withResolvers();
|
||||
this.#promise = promise;
|
||||
this.#loadingTab = aTab;
|
||||
const progressBar = this.#progressBar;
|
||||
progressBar.removeAttribute("fade-out");
|
||||
@@ -123,5 +133,6 @@ export class ZenProgressBar extends ZenUIComponent {
|
||||
}
|
||||
this.#longLoadTimer = null;
|
||||
}, WAIT_BEFORE_SHOWING_LONG_LOAD);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
#maxTabsPerRow = 0;
|
||||
#changeSpaceTimer = null;
|
||||
#isAnimatingTabMove = false;
|
||||
#firstHapticFeedbackPlayed = false;
|
||||
|
||||
#dragOverSplit = {};
|
||||
|
||||
@@ -119,6 +120,12 @@
|
||||
init() {
|
||||
super.init();
|
||||
this.handle_windowDragEnter = this.handle_windowDragEnter.bind(this);
|
||||
if (gZenWorkspaces.workspaceEnabled) {
|
||||
gZenWorkspaces.workspaceIcons.addEventListener(
|
||||
"dragover",
|
||||
this.handle_spaceIconDragOver.bind(this)
|
||||
);
|
||||
}
|
||||
window.addEventListener(
|
||||
"dragleave",
|
||||
this.handle_windowDragLeave.bind(this),
|
||||
@@ -676,6 +683,31 @@
|
||||
}
|
||||
}
|
||||
|
||||
#onSpaceChanged(spaceChanged, dt) {
|
||||
if (AppConstants.platform !== "macosx") {
|
||||
// See the hack in #createDragImageForTabs for more details which
|
||||
// explains why we need to do this on non-macOS platforms.
|
||||
return;
|
||||
}
|
||||
let tabs = this.originalDragImageArgs[0].children;
|
||||
const { isDarkMode, isExplicitMode } =
|
||||
gZenThemePicker.getGradientForWorkspace(spaceChanged, {
|
||||
getGradient: false,
|
||||
});
|
||||
for (let tab of tabs) {
|
||||
if (isExplicitMode) {
|
||||
tab.style.colorScheme = isDarkMode ? "dark" : "light";
|
||||
} else {
|
||||
tab.style.colorScheme = "";
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
dt.updateDragImage(...this.originalDragImageArgs);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#handle_sidebarDragOver(event) {
|
||||
const dt = event.dataTransfer;
|
||||
const draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
|
||||
@@ -696,28 +728,7 @@
|
||||
/* Disable wrapping */ true
|
||||
)
|
||||
.then(spaceChanged => {
|
||||
if (AppConstants.platform !== "macosx") {
|
||||
// See the hack in #createDragImageForTabs for more details which
|
||||
// explains why we need to do this on non-macOS platforms.
|
||||
return;
|
||||
}
|
||||
let tabs = this.originalDragImageArgs[0].children;
|
||||
const { isDarkMode, isExplicitMode } =
|
||||
gZenThemePicker.getGradientForWorkspace(spaceChanged, {
|
||||
getGradient: false,
|
||||
});
|
||||
for (let tab of tabs) {
|
||||
if (isExplicitMode) {
|
||||
tab.style.colorScheme = isDarkMode ? "dark" : "light";
|
||||
} else {
|
||||
tab.style.colorScheme = "";
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
dt.updateDragImage(...this.originalDragImageArgs);
|
||||
});
|
||||
});
|
||||
this.#onSpaceChanged(spaceChanged, dt);
|
||||
});
|
||||
this.#changeSpaceTimer = null;
|
||||
}, this._dndSwitchSpaceDelay);
|
||||
@@ -727,6 +738,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
handle_spaceIconDragOver(event) {
|
||||
const dt = event.dataTransfer;
|
||||
const draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
|
||||
if (draggedTab.hasAttribute("zen-essential")) {
|
||||
return;
|
||||
}
|
||||
const target = event.target;
|
||||
const spaceId = target.getAttribute("zen-workspace-id");
|
||||
if (!spaceId) {
|
||||
return;
|
||||
}
|
||||
this.clearDragOverVisuals();
|
||||
const currentSpaceId = gZenWorkspaces.activeWorkspace;
|
||||
if (spaceId === currentSpaceId || gZenWorkspaces._animatingChange) {
|
||||
return;
|
||||
}
|
||||
gZenWorkspaces.changeWorkspaceWithID(spaceId).then(spaceChanged => {
|
||||
this.#onSpaceChanged(spaceChanged, dt);
|
||||
});
|
||||
}
|
||||
|
||||
#handle_tabDragOverToSplit(event) {
|
||||
if (!this._dndSplitEnabled) {
|
||||
return;
|
||||
@@ -976,6 +1008,12 @@
|
||||
}
|
||||
|
||||
handle_drop_transition(dropElement, draggedTab, movingTabs, dropBefore) {
|
||||
if (
|
||||
dropElement?.hasAttribute("zen-empty-tab") &&
|
||||
dropElement.group?.isZenFolder
|
||||
) {
|
||||
dropElement = dropElement.group;
|
||||
}
|
||||
if (isTabGroupLabel(dropElement)) {
|
||||
dropElement = dropElement.group;
|
||||
}
|
||||
@@ -1119,12 +1157,17 @@
|
||||
// outside of a valid drop target.
|
||||
ownerGlobal.gZenFolders.highlightGroupOnDragOver(null);
|
||||
this.ZenDragAndDropService.onDragEnd();
|
||||
super.handle_dragend(event);
|
||||
try {
|
||||
super.handle_dragend(event);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
thisFromGlobal.clearDragOverVisuals();
|
||||
ownerGlobal.gZenPinnedTabManager.removeTabContainersDragoverClass();
|
||||
thisFromGlobal._clearDragOverSplit();
|
||||
this.#maybeClearVerticalPinnedGridDragOver();
|
||||
thisFromGlobal.originalDragImageArgs = [];
|
||||
this.#firstHapticFeedbackPlayed = false;
|
||||
window.removeEventListener(
|
||||
"dragenter",
|
||||
thisFromGlobal.handle_windowDragEnter,
|
||||
@@ -1242,13 +1285,13 @@
|
||||
// Only if there are no normal tabs to drop after
|
||||
showIndicatorUnderNewTabButton =
|
||||
lastTab.hasAttribute("zen-empty-tab");
|
||||
let useLastPinnd =
|
||||
let useLastPinned =
|
||||
(hoveringPeriphery ||
|
||||
(showIndicatorUnderNewTabButton &&
|
||||
!(pinnedTabsCount - gBrowser._numZenEssentials))) &&
|
||||
Services.prefs.getBoolPref("zen.view.show-newtab-button-top");
|
||||
dropElement =
|
||||
(useLastPinnd
|
||||
(useLastPinned
|
||||
? this._tabbrowserTabs.ariaFocusableItems.at(pinnedTabsCount)
|
||||
: this._tabbrowserTabs.ariaFocusableItems.at(-1)) || lastTab;
|
||||
}
|
||||
@@ -1379,6 +1422,12 @@
|
||||
dropBefore = true;
|
||||
}
|
||||
}
|
||||
if (shouldPlayHapticFeedback && !this.#firstHapticFeedbackPlayed) {
|
||||
// The first haptic feedback can often be too annoying,
|
||||
// so we skip it, but play for subsequent dragovers.
|
||||
this.#firstHapticFeedbackPlayed = true;
|
||||
shouldPlayHapticFeedback = false;
|
||||
}
|
||||
if (shouldPlayHapticFeedback) {
|
||||
// eslint-disable-next-line mozilla/valid-services
|
||||
Services.zen.playHapticFeedback();
|
||||
|
||||
@@ -65,9 +65,14 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
}
|
||||
|
||||
#initContextMenu() {
|
||||
const contextMenuItems = window.MozXULElement.parseXULToFragment(
|
||||
`<menuitem id="zen-context-menu-new-folder" data-l10n-id="zen-toolbar-context-new-folder"/>`
|
||||
);
|
||||
const contextMenuItems = window.MozXULElement.parseXULToFragment(`
|
||||
<menu data-l10n-id="zen-toolbar-context-move-to-folder" id="context_zenMoveToFolder">
|
||||
<menupopup>
|
||||
<menuseparator />
|
||||
<menuitem id="zen-context-menu-new-folder" data-l10n-id="zen-toolbar-context-new-folder"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
`);
|
||||
document.getElementById("context_moveTabToGroup").before(contextMenuItems);
|
||||
const contextMenuItemsToolbar = window.MozXULElement.parseXULToFragment(
|
||||
`<menuitem id="zen-context-menu-new-folder-toolbar" data-l10n-id="zen-toolbar-context-new-folder"/>
|
||||
@@ -227,6 +232,7 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
document
|
||||
.getElementById("zen-context-menu-new-folder-toolbar")
|
||||
.addEventListener("command", onNewFolder);
|
||||
this.#initMoveTabToFolder();
|
||||
SessionStore.promiseInitialized.then(() => {
|
||||
gBrowser.tabContainer.addEventListener(
|
||||
"dragstart",
|
||||
@@ -235,6 +241,67 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
});
|
||||
}
|
||||
|
||||
#initMoveTabToFolder() {
|
||||
const moveTabToFolderMenu = document.getElementById(
|
||||
"context_zenMoveToFolder"
|
||||
);
|
||||
moveTabToFolderMenu.addEventListener("popupshowing", () => {
|
||||
const separator = moveTabToFolderMenu.querySelector("menuseparator");
|
||||
let tabs = TabContextMenu.contextTab?.multiselected
|
||||
? gBrowser.selectedTabs
|
||||
: [TabContextMenu.contextTab];
|
||||
let groups = gBrowser.tabGroups.filter(group => {
|
||||
const isZenFolder = group?.isZenFolder;
|
||||
const isLiveFolder = group?.isLiveFolder;
|
||||
const spaceId = group?.getAttribute("zen-workspace-id");
|
||||
if (
|
||||
!isZenFolder ||
|
||||
isLiveFolder ||
|
||||
spaceId !== gZenWorkspaces.activeWorkspace
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return !tabs.some(tab => tab.group === group);
|
||||
});
|
||||
separator.hidden = groups.length === 0;
|
||||
for (const group of groups) {
|
||||
const icon = group.iconURL;
|
||||
const menuItem = document.createXULElement("menuitem");
|
||||
menuItem.setAttribute("label", group.label);
|
||||
menuItem.classList.add("context-zen-move-to-folder-item");
|
||||
if (icon) {
|
||||
menuItem.setAttribute("image", icon);
|
||||
}
|
||||
menuItem._group = group;
|
||||
separator.before(menuItem);
|
||||
}
|
||||
});
|
||||
|
||||
moveTabToFolderMenu.addEventListener("popuphidden", () => {
|
||||
const items = moveTabToFolderMenu.querySelectorAll(
|
||||
".context-zen-move-to-folder-item"
|
||||
);
|
||||
for (const item of items) {
|
||||
delete item._group;
|
||||
item.remove();
|
||||
}
|
||||
});
|
||||
|
||||
moveTabToFolderMenu.addEventListener("command", event => {
|
||||
if (!event.target.classList.contains("context-zen-move-to-folder-item")) {
|
||||
return;
|
||||
}
|
||||
const group = event.target._group;
|
||||
if (!group) {
|
||||
return;
|
||||
}
|
||||
let tabs = TabContextMenu.contextTab?.multiselected
|
||||
? gBrowser.selectedTabs
|
||||
: [TabContextMenu.contextTab];
|
||||
group.addTabs(tabs);
|
||||
});
|
||||
}
|
||||
|
||||
handleEvent(aEvent) {
|
||||
let methodName = `on_${aEvent.type}`;
|
||||
if (methodName in this) {
|
||||
@@ -744,8 +811,14 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
|
||||
const onKeyDown = event => {
|
||||
// Arrow down and up to navigate through the list
|
||||
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
||||
if (
|
||||
event.key === "ArrowDown" ||
|
||||
event.key === "ArrowUp" ||
|
||||
event.key === "Tab"
|
||||
) {
|
||||
event.preventDefault();
|
||||
let isUp =
|
||||
event.key === "ArrowUp" || (event.key === "Tab" && event.shiftKey);
|
||||
const items = Array.from(tabsList.children).filter(
|
||||
item => !item.hidden
|
||||
);
|
||||
@@ -755,9 +828,9 @@ class nsZenFolders extends nsZenDOMOperatedFeature {
|
||||
let index = items.indexOf(
|
||||
tabsList.querySelector(".folders-tabs-list-item[selected]")
|
||||
);
|
||||
if (event.key === "ArrowDown") {
|
||||
if (!isUp) {
|
||||
index = (index + 1) % items.length;
|
||||
} else if (event.key === "ArrowUp") {
|
||||
} else {
|
||||
index = (index - 1 + items.length) % items.length;
|
||||
}
|
||||
items.forEach(item => item.removeAttribute("selected"));
|
||||
|
||||
@@ -177,7 +177,7 @@ zen-folder {
|
||||
& > label {
|
||||
width: 100% !important;
|
||||
border: none !important;
|
||||
color: var(--sidebar-text-color) !important;
|
||||
color: var(--toolbar-color) !important;
|
||||
margin: 0 !important;
|
||||
font-weight: 600;
|
||||
align-self: center !important;
|
||||
|
||||
@@ -39,8 +39,9 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
|
||||
ARC_HEIGHT_RATIO: 0.2, // Arc height = distance * ratio (capped at MAX_ARC_HEIGHT)
|
||||
});
|
||||
|
||||
#GLANCE_ANIMATION_DURATION =
|
||||
Services.prefs.getIntPref("zen.glance.animation-duration") / 1000;
|
||||
#GLANCE_ANIMATION_DURATION = Services.prefs.getIntPref(
|
||||
"zen.glance.animation-duration"
|
||||
);
|
||||
|
||||
init() {
|
||||
this.#setupEventListeners();
|
||||
@@ -294,7 +295,7 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
|
||||
{
|
||||
duration: 0.2,
|
||||
type: "spring",
|
||||
delay: this.#GLANCE_ANIMATION_DURATION - 0.2,
|
||||
delay: this.#GLANCE_ANIMATION_DURATION / 1000 - 0.2,
|
||||
bounce: 0,
|
||||
}
|
||||
);
|
||||
@@ -450,7 +451,7 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
|
||||
opacity: [1, 0.3],
|
||||
},
|
||||
{
|
||||
duration: this.#GLANCE_ANIMATION_DURATION,
|
||||
duration: this.#GLANCE_ANIMATION_DURATION / 1000,
|
||||
type: "spring",
|
||||
bounce: 0.2,
|
||||
}
|
||||
@@ -536,13 +537,13 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
|
||||
// nice fade-in effect to the content. But if it doesn't exist,
|
||||
// we just fall back to always showing the browser directly.
|
||||
if (data.elementData) {
|
||||
gZenUIManager.motion
|
||||
.animate(
|
||||
gZenUIManager
|
||||
.elementAnimate(
|
||||
this.contentWrapper,
|
||||
{ opacity: [0, 1] },
|
||||
{
|
||||
duration: this.#GLANCE_ANIMATION_DURATION / 4,
|
||||
easing: "easeInOut",
|
||||
easing: "ease-in-out",
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
@@ -559,12 +560,12 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
|
||||
browserElement.zenModeActive = false;
|
||||
browserElement.docShellIsActive = false;
|
||||
}
|
||||
gZenUIManager.motion
|
||||
.animate(this.browserWrapper, arcSequence, {
|
||||
gZenUIManager
|
||||
.elementAnimate(this.browserWrapper, arcSequence, {
|
||||
duration: gZenUIManager.testingEnabled
|
||||
? 0
|
||||
: this.#GLANCE_ANIMATION_DURATION,
|
||||
ease: "easeInOut",
|
||||
easing: "ease-in-out",
|
||||
})
|
||||
.then(() => {
|
||||
if (shouldDeactivateDocShell) {
|
||||
@@ -971,7 +972,7 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
|
||||
{
|
||||
duration: 0.2,
|
||||
type: "spring",
|
||||
bounce: this.#GLANCE_ANIMATION_DURATION - 0.1,
|
||||
bounce: this.#GLANCE_ANIMATION_DURATION / 1000 - 0.1,
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
@@ -1019,7 +1020,7 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
|
||||
opacity: [0.3, 1],
|
||||
},
|
||||
{
|
||||
duration: this.#GLANCE_ANIMATION_DURATION / 1.5,
|
||||
duration: this.#GLANCE_ANIMATION_DURATION / 1000 / 1.5,
|
||||
type: "spring",
|
||||
bounce: 0,
|
||||
}
|
||||
@@ -1062,10 +1063,10 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
|
||||
this.browserWrapper.style.width = "";
|
||||
this.browserWrapper.style.height = "";
|
||||
|
||||
gZenUIManager.motion
|
||||
.animate(this.browserWrapper, arcSequence, {
|
||||
gZenUIManager
|
||||
.elementAnimate(this.browserWrapper, arcSequence, {
|
||||
duration: this.#GLANCE_ANIMATION_DURATION,
|
||||
ease: "easeOut",
|
||||
easing: "ease-out",
|
||||
})
|
||||
.then(() => {
|
||||
// Remove element preview after closing animation
|
||||
@@ -1573,9 +1574,6 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
|
||||
this.#handleZenFolderPinning();
|
||||
gBrowser.moveTabAfter(this.#currentTab, this.#currentParentTab);
|
||||
|
||||
const browserRect = window.windowUtils.getBoundsWithoutFlushing(
|
||||
this.browserWrapper
|
||||
);
|
||||
this.#prepareTabForFullOpen();
|
||||
|
||||
const sidebarButtons = this.browserWrapper.querySelector(
|
||||
@@ -1596,7 +1594,7 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.#animateFullOpen(browserRect);
|
||||
await this.#animateFullOpen();
|
||||
this.finishOpeningGlance();
|
||||
}
|
||||
|
||||
@@ -1632,31 +1630,27 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
|
||||
|
||||
/**
|
||||
* Animate the full opening process
|
||||
*
|
||||
* @param {object} browserRect - The browser rectangle
|
||||
*/
|
||||
async #animateFullOpen(browserRect) {
|
||||
async #animateFullOpen() {
|
||||
// Write styles early to avoid flickering
|
||||
this.browserWrapper.style.opacity = 1;
|
||||
this.browserWrapper.style.width = `${browserRect.width}px`;
|
||||
this.browserWrapper.style.height = `${browserRect.height}px`;
|
||||
this.browserWrapper.style.width = "100%";
|
||||
this.browserWrapper.style.height = "100%";
|
||||
|
||||
await gZenUIManager.motion.animate(
|
||||
this.browserWrapper,
|
||||
await gZenUIManager.elementAnimate(
|
||||
this.browserWrapper.parentElement,
|
||||
{
|
||||
width: ["80%", "100%"],
|
||||
height: ["100%", "100%"],
|
||||
scale: [1, 1.005, 1],
|
||||
},
|
||||
{
|
||||
duration: this.#GLANCE_ANIMATION_DURATION,
|
||||
type: "spring",
|
||||
bounce: 0,
|
||||
duration: 250,
|
||||
easing: "ease-in-out",
|
||||
}
|
||||
);
|
||||
|
||||
this.browserWrapper.style.scale = "";
|
||||
this.browserWrapper.style.opacity = "";
|
||||
this.browserWrapper.style.width = "";
|
||||
this.browserWrapper.style.height = "";
|
||||
this.browserWrapper.style.opacity = "";
|
||||
gZenViewSplitter.deactivateCurrentSplitView({ removeDeckSelected: true });
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,9 @@ export class ZenGlanceChild extends JSWindowActorChild {
|
||||
|
||||
#sendClickDataToParent(node, originalTarget) {
|
||||
if (!node) {
|
||||
node = originalTarget;
|
||||
}
|
||||
if (!node?.getBoundingClientRect) {
|
||||
return;
|
||||
}
|
||||
// Get the largest element we can get. If the `A` element
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
display: flex;
|
||||
z-index: 999;
|
||||
|
||||
will-change: transform, opacity;
|
||||
contain: content;
|
||||
|
||||
top: 15px;
|
||||
padding: 12px;
|
||||
gap: 12px;
|
||||
@@ -121,6 +124,7 @@
|
||||
|
||||
&:not([has-finished-animation="true"]) {
|
||||
will-change: transform;
|
||||
contain: layout size;
|
||||
transform-origin: 0 0;
|
||||
|
||||
#statuspanel {
|
||||
|
||||
@@ -290,10 +290,13 @@ export class nsZenSessionManager {
|
||||
console.error("ZenSessionManager: Failed to read session file", e);
|
||||
}
|
||||
this.#sidebar = this._dataFromFile || {};
|
||||
if (!this.#sidebar.spaces?.length && !this._shouldRunMigration) {
|
||||
if (
|
||||
!this.#sidebarWithoutCloning.spaces?.length &&
|
||||
!this._shouldRunMigration
|
||||
) {
|
||||
this.log(
|
||||
"No spaces data found in session file, running migration",
|
||||
this.#sidebar
|
||||
this.#sidebarWithoutCloning
|
||||
);
|
||||
// If we have no spaces data, we should run migration
|
||||
// to restore them from the database. Note we also do a
|
||||
@@ -304,7 +307,7 @@ export class nsZenSessionManager {
|
||||
if (
|
||||
Services.prefs.getBoolPref("zen.session-store.log-tab-entries", false)
|
||||
) {
|
||||
for (const tab of this.#sidebar.tabs || []) {
|
||||
for (const tab of this.#sidebarWithoutCloning.tabs || []) {
|
||||
this.log("Tab entry in session file:", tab);
|
||||
}
|
||||
}
|
||||
@@ -357,6 +360,11 @@ export class nsZenSessionManager {
|
||||
if (this._shouldRunMigration) {
|
||||
initialState = this.#runStateMigration(initialState);
|
||||
}
|
||||
// Clear the memory of the groups saved in the session file,
|
||||
// as we don't really need them anyways.
|
||||
if (initialState?.savedGroups) {
|
||||
initialState.savedGroups = [];
|
||||
}
|
||||
if (!lazy.gWindowSyncEnabled) {
|
||||
if (initialState?.windows?.length && this.#shouldRestoreOnlyPinned) {
|
||||
this.log("Window sync disabled, restoring only pinned tabs");
|
||||
@@ -487,7 +495,7 @@ export class nsZenSessionManager {
|
||||
delete this._migrationData?.recoveryData;
|
||||
// Restore spaces into the sidebar object if we don't
|
||||
// have any yet.
|
||||
if (!this.#sidebar.spaces?.length) {
|
||||
if (!this.#sidebarWithoutCloning.spaces?.length) {
|
||||
this.#sidebar = {
|
||||
...this.#sidebar,
|
||||
spaces: this._migrationData?.spaces || [],
|
||||
@@ -712,10 +720,7 @@ export class nsZenSessionManager {
|
||||
// We only want to collect the sidebar data once from
|
||||
// a single window, as all windows share the same
|
||||
// sidebar data.
|
||||
let sidebarData = this.#sidebar;
|
||||
if (!sidebarData) {
|
||||
sidebarData = {};
|
||||
}
|
||||
let sidebarData = {};
|
||||
|
||||
sidebarData.lastCollected = Date.now();
|
||||
this.#collectTabsData(sidebarData, aStateWindows);
|
||||
@@ -895,6 +900,7 @@ export class nsZenSessionManager {
|
||||
const newState = { windows: [newWindow] };
|
||||
this.log(`Cloning window with ${newWindow.tabs.length} tabs`);
|
||||
|
||||
aWindow.__isNewZenWindow = true;
|
||||
SessionStoreInternal._deferredInitialState = newState;
|
||||
SessionStoreInternal.initializeWindow(aWindow, newState);
|
||||
}
|
||||
|
||||
@@ -297,6 +297,18 @@ class nsZenWindowSync {
|
||||
if (tab.pinned && !tab._zenPinnedInitialState) {
|
||||
await this.setPinnedTabState(tab);
|
||||
}
|
||||
// Lets clear extra values to save some memory, we only really
|
||||
// care about the URL and title for the initial state, and we want
|
||||
// to avoid keeping the whole session history around.
|
||||
if (tab._zenPinnedInitialState) {
|
||||
tab._zenPinnedInitialState = {
|
||||
...tab._zenPinnedInitialState,
|
||||
entry: {
|
||||
url: tab._zenPinnedInitialState.entry.url,
|
||||
title: tab._zenPinnedInitialState.entry.title,
|
||||
},
|
||||
};
|
||||
}
|
||||
if (
|
||||
!lazy.gWindowSyncEnabled ||
|
||||
(lazy.gSyncOnlyPinnedTabs && !tab.pinned)
|
||||
@@ -731,7 +743,14 @@ class nsZenWindowSync {
|
||||
return;
|
||||
}
|
||||
await this.#styleSwapedBrowsers(aOurTab, aOtherTab, () => {
|
||||
this.#swapBrowserDocShellsInner(aOurTab, aOtherTab);
|
||||
try {
|
||||
this.#swapBrowserDocShellsInner(aOurTab, aOtherTab);
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`Error swapping browsers for tabs ${aOurTab.id} and ${aOtherTab.id}:`,
|
||||
e
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -795,6 +814,16 @@ class nsZenWindowSync {
|
||||
);
|
||||
return false;
|
||||
}
|
||||
// Theoretical case where we are trying to swap two tabs in the same window.
|
||||
// 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) {
|
||||
this.log(
|
||||
`Cannot swap browsers between tabs ${aOurTab.id} and ${aOtherTab.id} because they are in the same window`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
// Can't swap between chrome and content processes.
|
||||
if (
|
||||
aOurTab.linkedBrowser.isRemoteBrowser !=
|
||||
@@ -1056,10 +1085,17 @@ class nsZenWindowSync {
|
||||
continue;
|
||||
}
|
||||
delete tab._zenContentsVisible;
|
||||
this.#swapBrowserDocShellsInner(targetTab, tab, {
|
||||
focus: targetTab.selected,
|
||||
onClose: true,
|
||||
});
|
||||
try {
|
||||
this.#swapBrowserDocShellsInner(targetTab, tab, {
|
||||
focus: targetTab.selected,
|
||||
onClose: true,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`Error swapping browsers for tabs ${tab.id} and ${targetTab.id} during close:`,
|
||||
e
|
||||
);
|
||||
}
|
||||
this.#swapedTabsEntriesForWC.set(
|
||||
tab.linkedBrowser.permanentKey,
|
||||
targetTab
|
||||
@@ -1191,8 +1227,12 @@ class nsZenWindowSync {
|
||||
activeIndex--;
|
||||
activeIndex = Math.min(activeIndex, entries.length - 1);
|
||||
activeIndex = Math.max(activeIndex, 0);
|
||||
let entryToUse = (entries[activeIndex] || entries[0]) ?? null;
|
||||
const initialState = {
|
||||
entry: (entries[activeIndex] || entries[0]) ?? null,
|
||||
entry: {
|
||||
url: entryToUse?.url,
|
||||
title: entryToUse?.title,
|
||||
},
|
||||
image,
|
||||
};
|
||||
this.#runOnAllWindows(null, win => {
|
||||
|
||||
@@ -1258,10 +1258,10 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
|
||||
let colorToBlendOpacity;
|
||||
if (this.isMica) {
|
||||
colorToBlend = this.isDarkMode ? [0, 0, 0] : [255, 255, 255];
|
||||
colorToBlendOpacity = 0.25;
|
||||
colorToBlendOpacity = 0.12;
|
||||
} else if (AppConstants.platform === "macosx") {
|
||||
colorToBlend = [255, 255, 255];
|
||||
colorToBlendOpacity = 0.35;
|
||||
colorToBlendOpacity = 0.18;
|
||||
}
|
||||
if (colorToBlend) {
|
||||
const blendedAlpha = Math.min(
|
||||
@@ -1473,7 +1473,15 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
|
||||
* @returns {string} The primary color in hex format.
|
||||
*/
|
||||
getAccentColorForUI(accentColor) {
|
||||
return `rgb(${accentColor[0]}, ${accentColor[1]}, ${accentColor[2]})`;
|
||||
const [h, s, l] = this.rgbToHsl(...accentColor);
|
||||
if (s < 0.1) {
|
||||
return `rgb(${accentColor[0]}, ${accentColor[1]}, ${accentColor[2]})`;
|
||||
}
|
||||
const saturation = Math.min(1, s + 0.3);
|
||||
const targetLightness = this.isDarkMode ? 0.62 : 0.42;
|
||||
const lightness = l * 0.4 + targetLightness * 0.6;
|
||||
const [r, g, b] = this.hslToRgb(h / 360, saturation, lightness);
|
||||
return `rgb(${r}, ${g}, ${b})`;
|
||||
}
|
||||
|
||||
getMostDominantColor(allColors) {
|
||||
@@ -1485,9 +1493,13 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
|
||||
return color;
|
||||
}
|
||||
|
||||
getToolbarColor(isDarkMode = false) {
|
||||
getToolbarColor(isDarkMode = false, accentColor = null) {
|
||||
const opacity = 0.8;
|
||||
return isDarkMode ? [255, 255, 255, opacity] : [0, 0, 0, opacity]; // Default toolbar
|
||||
let baseColor = isDarkMode ? [255, 255, 255, opacity] : [0, 0, 0, opacity]; // Default toolbar
|
||||
if (accentColor) {
|
||||
return this.blendColors(baseColor.slice(0, 3), accentColor, 75).concat(1);
|
||||
}
|
||||
return baseColor;
|
||||
}
|
||||
|
||||
get browserBackgroundElement() {
|
||||
@@ -1748,7 +1760,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
|
||||
}
|
||||
}
|
||||
// Set `--toolbox-textcolor` to have a contrast with the primary color
|
||||
const textColor = this.getToolbarColor(isDarkMode);
|
||||
let textColor = this.getToolbarColor(isDarkMode, dominantColor);
|
||||
docElement.style.setProperty(
|
||||
"--toolbox-textcolor",
|
||||
`rgba(${textColor[0]}, ${textColor[1]}, ${textColor[2]}, ${textColor[3]})`
|
||||
@@ -1994,7 +2006,7 @@ export class nsZenThemePicker extends nsZenMultiWindowFeature {
|
||||
grain: theme.texture ?? 0,
|
||||
isDarkMode,
|
||||
isExplicitMode,
|
||||
toolbarColor: this.getToolbarColor(isDarkMode),
|
||||
toolbarColor: this.getToolbarColor(isDarkMode, dominantColor),
|
||||
primaryColor: this.getAccentColorForUI(dominantColor),
|
||||
};
|
||||
this.currentOpacity = previousOpacity;
|
||||
|
||||
@@ -1602,7 +1602,6 @@ class nsZenWorkspaces {
|
||||
}
|
||||
|
||||
#prepareNewWorkspace(space) {
|
||||
document.documentElement.setAttribute("zen-workspace-id", space.uuid);
|
||||
let tabCount = 0;
|
||||
for (let tab of gBrowser.tabs) {
|
||||
const isEssential = tab.getAttribute("zen-essential") === "true";
|
||||
@@ -1643,12 +1642,12 @@ class nsZenWorkspaces {
|
||||
|
||||
async changeWorkspaceWithID(workspaceID, ...args) {
|
||||
const workspace = this.getWorkspaceFromId(workspaceID);
|
||||
await this.changeWorkspace(workspace, ...args);
|
||||
return await this.changeWorkspace(workspace, ...args);
|
||||
}
|
||||
|
||||
async changeWorkspace(workspace, ...args) {
|
||||
if (!this.workspaceEnabled) {
|
||||
return;
|
||||
return workspace;
|
||||
}
|
||||
this.#currentSpaceSwitchContext.animations.forEach(animation => {
|
||||
animation.complete();
|
||||
@@ -1668,6 +1667,7 @@ class nsZenWorkspaces {
|
||||
}
|
||||
this.#inChangingWorkspace = false;
|
||||
resolve();
|
||||
return workspace;
|
||||
}
|
||||
|
||||
_cancelSwipeAnimation() {
|
||||
@@ -2429,9 +2429,6 @@ class nsZenWorkspaces {
|
||||
tabToSelect,
|
||||
{ previousWorkspaceIndex, previousWorkspace } = {}
|
||||
) {
|
||||
// Update document state
|
||||
document.documentElement.setAttribute("zen-workspace-id", workspace.uuid);
|
||||
|
||||
// Recalculate new tab observers
|
||||
gBrowser.tabContainer.observe(
|
||||
null,
|
||||
@@ -2975,8 +2972,7 @@ class nsZenWorkspaces {
|
||||
}
|
||||
|
||||
let nextWorkspace = workspaces[targetIndex];
|
||||
await this.changeWorkspace(nextWorkspace, { whileScrolling });
|
||||
return nextWorkspace;
|
||||
return await this.changeWorkspace(nextWorkspace, { whileScrolling });
|
||||
}
|
||||
|
||||
#initializeWorkspaceTabContextMenus() {
|
||||
@@ -3000,9 +2996,8 @@ class nsZenWorkspaces {
|
||||
? gBrowser.selectedTabs
|
||||
: [TabContextMenu.contextTab];
|
||||
document.getElementById("tabContextMenu").hidePopup();
|
||||
const previousWorkspaceID =
|
||||
document.documentElement.getAttribute("zen-workspace-id");
|
||||
for (let tab of tabs) {
|
||||
const previousWorkspaceID = tab.getAttribute("zen-workspace-id");
|
||||
this.moveTabToWorkspace(tab, workspaceID);
|
||||
if (this.lastSelectedWorkspaceTabs[previousWorkspaceID] === tab) {
|
||||
// This tab is no longer the last selected tab in the previous workspace because it's being moved to
|
||||
|
||||
@@ -131,15 +131,14 @@ export class ZenSpacesSwipe {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const delta = event.delta * 300;
|
||||
const stripWidth =
|
||||
window.windowUtils.getBoundsWithoutFlushing(
|
||||
document.getElementById("navigator-toolbox")
|
||||
).width +
|
||||
window.windowUtils.getBoundsWithoutFlushing(
|
||||
document.getElementById("zen-sidebar-splitter")
|
||||
).width *
|
||||
2;
|
||||
).width;
|
||||
const delta = event.delta * stripWidth;
|
||||
let translateX = this._swipeState.lastDelta + delta;
|
||||
// Add a force multiplier as we are translating the strip depending on how close to the edge we are
|
||||
let forceMultiplier = Math.min(
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
align-items: center;
|
||||
position: relative;
|
||||
fill-opacity: 0.6;
|
||||
-moz-context-properties: fill-opacity, fill;
|
||||
fill: currentColor;
|
||||
|
||||
& .zen-workspace-icon {
|
||||
pointer-events: none;
|
||||
@@ -71,6 +73,11 @@
|
||||
width 0.1s,
|
||||
transform 0.2s;
|
||||
|
||||
&[active='true'] .zen-workspace-icon {
|
||||
fill: var(--zen-sidebar-themed-icon-fill);
|
||||
fill-opacity: 1;
|
||||
}
|
||||
|
||||
&[active='true'],
|
||||
&:hover,
|
||||
&[dragged='true'] {
|
||||
@@ -210,9 +217,9 @@
|
||||
height: 16px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
fill-opacity: 0.6;
|
||||
fill-opacity: 1;
|
||||
-moz-context-properties: fill-opacity, fill;
|
||||
fill: var(--toolbox-textcolor);
|
||||
fill: var(--zen-sidebar-themed-icon-fill);
|
||||
font-size: 16px;
|
||||
padding-top: 2px;
|
||||
color: light-dark(rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0.8));
|
||||
|
||||
@@ -220,14 +220,8 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
}
|
||||
const group = this._data[groupIndex];
|
||||
const tabIndex = group.tabs.indexOf(tab);
|
||||
group.tabs.splice(tabIndex, 1);
|
||||
|
||||
this.resetTabState(tab, forUnsplit);
|
||||
if (tab.group && tab.group.hasAttribute("split-view-group")) {
|
||||
gBrowser.ungroupTab(tab);
|
||||
this.#dispatchItemEvent("ZenTabRemovedFromSplit", tab);
|
||||
}
|
||||
if (group.tabs.length < 2) {
|
||||
if (group.tabs.length < 3) {
|
||||
// We need to remove all remaining tabs from the group when unsplitting
|
||||
let remainingTabs = [...group.tabs]; // Copy array since we'll modify it
|
||||
if (!dontRebuildGrid) {
|
||||
@@ -237,12 +231,20 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
}
|
||||
this.removeGroup(groupIndex);
|
||||
if (changeTab) {
|
||||
gBrowser.selectedTab = remainingTabs[remainingTabs.length - 1];
|
||||
gBrowser.selectedTab = remainingTabs[0];
|
||||
document
|
||||
.getElementById("cmd_zenNewEmptySplit")
|
||||
.removeAttribute("disabled");
|
||||
}
|
||||
} else {
|
||||
group.tabs.splice(tabIndex, 1);
|
||||
|
||||
this.resetTabState(tab, forUnsplit);
|
||||
if (tab.group && tab.group.hasAttribute("split-view-group")) {
|
||||
gBrowser.ungroupTab(tab);
|
||||
this.#dispatchItemEvent("ZenTabRemovedFromSplit", tab);
|
||||
}
|
||||
|
||||
const node = this.getSplitNodeFromTab(tab);
|
||||
const toUpdate = this.removeNode(node);
|
||||
this.applyGridLayout(toUpdate);
|
||||
@@ -1165,6 +1167,9 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
const contentAreaContextMenu = document.getElementById("tabContextMenu");
|
||||
contentAreaContextMenu.addEventListener("popupshowing", () => {
|
||||
let contextTab = TabContextMenu.contextTab;
|
||||
if (!contextTab) {
|
||||
return;
|
||||
}
|
||||
let selectedTabs = contextTab.multiselected
|
||||
? gBrowser.selectedTabs
|
||||
: [contextTab];
|
||||
@@ -1239,13 +1244,29 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
|
||||
/**
|
||||
* Splits the selected tabs.
|
||||
*
|
||||
* @param {Tab|null} otherTabHint - An optional hint for another tab to split with (used for glance tabs).
|
||||
*/
|
||||
contextSplitTabs() {
|
||||
contextSplitTabs(otherTabHint = null) {
|
||||
let tabs;
|
||||
if (TabContextMenu.contextTab.multiselected) {
|
||||
let currentTab = TabContextMenu.contextTab || gBrowser.selectedTab;
|
||||
if (currentTab.multiselected) {
|
||||
tabs = gBrowser.selectedTabs;
|
||||
} else if (!currentTab.selected) {
|
||||
tabs = [
|
||||
currentTab,
|
||||
...gBrowser.selectedTabs.filter(t => t !== currentTab),
|
||||
];
|
||||
} else {
|
||||
tabs = [TabContextMenu.contextTab];
|
||||
tabs = [currentTab];
|
||||
}
|
||||
if (otherTabHint && !tabs.includes(otherTabHint)) {
|
||||
tabs.push(otherTabHint);
|
||||
}
|
||||
if (tabs.length < 2) {
|
||||
gBrowser.selectedTab = tabs[0];
|
||||
this.createEmptySplit();
|
||||
return;
|
||||
}
|
||||
// If all are already in a split view, we unsplit them first.
|
||||
if (tabs.every(tab => tab.splitView)) {
|
||||
@@ -1265,10 +1286,7 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
* @returns {boolean} True if the tabs can be split, false otherwise.
|
||||
*/
|
||||
contextCanSplitTabs() {
|
||||
if (
|
||||
window.gBrowser.selectedTabs.length < 2 ||
|
||||
window.gBrowser.selectedTabs.length > this.MAX_TABS
|
||||
) {
|
||||
if (window.gBrowser.selectedTabs.length > this.MAX_TABS) {
|
||||
return false;
|
||||
}
|
||||
for (const tab of window.gBrowser.selectedTabs) {
|
||||
@@ -1323,7 +1341,7 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
* @param {Array} tabs
|
||||
* @param {Tab} relativeTab
|
||||
*/
|
||||
_moveTabsToContainer(tabs, relativeTab) {
|
||||
#moveTabsToContainer(tabs, relativeTab) {
|
||||
const relativeTabIsPinned = relativeTab.pinned;
|
||||
const relativeTabIsEssential = relativeTab.hasAttribute("zen-essential");
|
||||
|
||||
@@ -1340,6 +1358,32 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
}
|
||||
}
|
||||
|
||||
#useTabsToSplit(tabs) {
|
||||
// If there's ANY pinned tab on the list, we clone the pinned tab
|
||||
// state to all the tabs
|
||||
const allArePinned = tabs.every(tab => tab.pinned);
|
||||
const thereIsOnePinned = tabs.some(tab => tab.pinned);
|
||||
const thereIsOneEssential = tabs.some(tab =>
|
||||
tab.hasAttribute("zen-essential")
|
||||
);
|
||||
const thereIsOneLiveFolder = tabs.some(tab =>
|
||||
tab.hasAttribute("zen-live-folder-item-id")
|
||||
);
|
||||
|
||||
if (
|
||||
thereIsOneEssential ||
|
||||
(thereIsOnePinned && !allArePinned) ||
|
||||
thereIsOneLiveFolder
|
||||
) {
|
||||
for (let i = 0; i < tabs.length; i++) {
|
||||
const tab = tabs[i];
|
||||
if (tab.pinned) {
|
||||
tabs[i] = gBrowser.duplicateTab(tab, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the given tabs.
|
||||
*
|
||||
@@ -1364,17 +1408,20 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
let shouldActivateSplit =
|
||||
(initialIndex >= 0 || tabs.includes(window.gBrowser.selectedTab)) &&
|
||||
!this._sessionRestoring;
|
||||
|
||||
if (existingSplitTab) {
|
||||
this._moveTabsToContainer(tabs, tabs[tabIndexToUse]);
|
||||
const groupIndex = this._data.findIndex(group =>
|
||||
group.tabs.includes(existingSplitTab)
|
||||
);
|
||||
const group = this._data[groupIndex];
|
||||
const gridTypeChange = gridType && group.gridType !== gridType;
|
||||
const newTabsAdded = tabs.find(t => !group.tabs.includes(t));
|
||||
if (group.tabs.length >= this.MAX_TABS) {
|
||||
gZenUIManager.showToast("zen-split-view-limit-toast");
|
||||
return;
|
||||
}
|
||||
this.#useTabsToSplit(tabs);
|
||||
this.#moveTabsToContainer(tabs, tabs[tabIndexToUse]);
|
||||
const gridTypeChange = gridType && group.gridType !== gridType;
|
||||
const newTabsAdded = tabs.find(t => !group.tabs.includes(t));
|
||||
if (gridTypeChange && !newTabsAdded) {
|
||||
// reset layout
|
||||
group.gridType = gridType;
|
||||
@@ -1406,30 +1453,7 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
return group;
|
||||
}
|
||||
|
||||
// We are here if none of the tabs have been previously split
|
||||
// If there's ANY pinned tab on the list, we clone the pinned tab
|
||||
// state to all the tabs
|
||||
const allArePinned = tabs.every(tab => tab.pinned);
|
||||
const thereIsOnePinned = tabs.some(tab => tab.pinned);
|
||||
const thereIsOneEssential = tabs.some(tab =>
|
||||
tab.hasAttribute("zen-essential")
|
||||
);
|
||||
const thereIsOneLiveFolder = tabs.some(tab =>
|
||||
tab.hasAttribute("zen-live-folder-item-id")
|
||||
);
|
||||
|
||||
if (
|
||||
thereIsOneEssential ||
|
||||
(thereIsOnePinned && !allArePinned) ||
|
||||
thereIsOneLiveFolder
|
||||
) {
|
||||
for (let i = 0; i < tabs.length; i++) {
|
||||
const tab = tabs[i];
|
||||
if (tab.pinned) {
|
||||
tabs[i] = gBrowser.duplicateTab(tab, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.#useTabsToSplit(tabs);
|
||||
|
||||
gridType ??= "grid";
|
||||
|
||||
@@ -2172,7 +2196,7 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
|
||||
splitGroup &&
|
||||
(!draggedTab.group || draggedTab.group !== splitGroup)
|
||||
) {
|
||||
this._moveTabsToContainer([draggedTab], droppedOnTab);
|
||||
this.#moveTabsToContainer([draggedTab], droppedOnTab);
|
||||
gBrowser.moveTabToExistingGroup(draggedTab, splitGroup);
|
||||
if (hoverSide === "left" || hoverSide === "top") {
|
||||
try {
|
||||
|
||||
@@ -104,7 +104,8 @@ tab-group[split-view-group] {
|
||||
}
|
||||
}
|
||||
|
||||
tab-group[split-view-group]:where([hasactivetab]) & {
|
||||
tab-group[split-view-group]:where([hasactivetab]) &,
|
||||
&:has(> tab:is([multiselected])) {
|
||||
background-color: var(--tab-selected-bgcolor);
|
||||
box-shadow: var(--tab-selected-shadow);
|
||||
|
||||
|
||||
@@ -285,8 +285,6 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedTabs = pinnedTabs.filter(tab => tab.selected);
|
||||
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
@@ -366,13 +364,19 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
|
||||
return;
|
||||
}
|
||||
}
|
||||
await gBrowser.explicitUnloadTabs(pinnedTabs);
|
||||
let successful = await gBrowser.explicitUnloadTabs(pinnedTabs);
|
||||
if (!successful) {
|
||||
return;
|
||||
}
|
||||
for (const tab of pinnedTabs) {
|
||||
tab.removeAttribute("discarded");
|
||||
}
|
||||
}
|
||||
if (selectedTabs.length) {
|
||||
this._handleTabSwitch(selectedTabs[0]);
|
||||
} else if (pinnedTabs.some(tab => tab.selected)) {
|
||||
const selectedTabs = pinnedTabs.filter(tab => tab.selected);
|
||||
gBrowser.selectedTab = gBrowser._findTabToBlurTo(
|
||||
selectedTabs[0],
|
||||
selectedTabs
|
||||
);
|
||||
}
|
||||
if (behavior.includes("reset")) {
|
||||
for (const tab of pinnedTabs) {
|
||||
@@ -392,28 +396,6 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
|
||||
}
|
||||
}
|
||||
|
||||
_handleTabSwitch(selectedTab) {
|
||||
if (selectedTab !== gBrowser.selectedTab) {
|
||||
return;
|
||||
}
|
||||
const findNextTab = direction =>
|
||||
gBrowser.tabContainer.findNextTab(selectedTab, {
|
||||
direction,
|
||||
filter: tab => !tab.hidden && !tab.pinned,
|
||||
});
|
||||
|
||||
let nextTab = findNextTab(1) || findNextTab(-1);
|
||||
|
||||
if (!nextTab) {
|
||||
gZenWorkspaces.selectEmptyTab();
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextTab) {
|
||||
gBrowser.selectedTab = nextTab;
|
||||
}
|
||||
}
|
||||
|
||||
#resetTabToStoredState(tab) {
|
||||
const state = this.#getTabState(tab);
|
||||
|
||||
@@ -857,7 +839,9 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
|
||||
const pinUrl = tab._zenPinnedInitialState.entry.url.split("#")[0];
|
||||
const currentUrl = location.split("#")[0];
|
||||
// Add an indicator that the pin has been changed
|
||||
if (pinUrl === currentUrl) {
|
||||
if (
|
||||
Services.io.newURI(currentUrl).spec === Services.io.newURI(pinUrl).spec
|
||||
) {
|
||||
this.resetPinChangedUrl(tab);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -341,7 +341,7 @@
|
||||
:root:not([zen-renaming-tab="true"])
|
||||
#tabbrowser-tabs:not([movingtab])
|
||||
& .tab-content > image:active {
|
||||
scale: 0.98;
|
||||
scale: 0.97;
|
||||
}
|
||||
|
||||
& .tab-icon-image {
|
||||
@@ -353,6 +353,7 @@
|
||||
&:-moz-broken {
|
||||
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3C/svg%3E") !important;
|
||||
background: color-mix(in srgb, var(--zen-primary-color) 80%, light-dark(rgb(0, 0, 0), rgb(255, 255, 255)));
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,13 +475,13 @@
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
|
||||
:root[zen-workspace-id][zen-sidebar-expanded="true"] & {
|
||||
:root[zen-sidebar-expanded="true"] & {
|
||||
margin-left: calc(-1 * var(--zen-toolbox-padding));
|
||||
width: calc(100% + var(--zen-toolbox-padding) * 2);
|
||||
}
|
||||
}
|
||||
|
||||
:root[zen-workspace-id] #pinned-tabs-container {
|
||||
#pinned-tabs-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1088,7 +1089,7 @@
|
||||
|
||||
&:active,
|
||||
&[open] {
|
||||
scale: 0.98;
|
||||
scale: 0.99;
|
||||
}
|
||||
|
||||
&[in-urlbar] {
|
||||
|
||||
@@ -12,10 +12,6 @@ add_task(async function test_Issue_10455() {
|
||||
|
||||
let newWindow = await BrowserTestUtils.openNewBrowserWindow();
|
||||
await newWindow.gZenWorkspaces.promiseInitialized;
|
||||
ok(
|
||||
newWindow.document.documentElement.hasAttribute("zen-workspace-id"),
|
||||
"New window should have a zen-workspace-id attribute"
|
||||
);
|
||||
|
||||
const unloadEvent = BrowserTestUtils.waitForEvent(newWindow, "unload");
|
||||
newWindow.BrowserCommands.closeTabOrWindow();
|
||||
@@ -33,10 +29,6 @@ add_task(async function test_Issue_10455_Dont_Close() {
|
||||
|
||||
let newWindow = await BrowserTestUtils.openNewBrowserWindow();
|
||||
await newWindow.gZenWorkspaces.promiseInitialized;
|
||||
ok(
|
||||
newWindow.document.documentElement.hasAttribute("zen-workspace-id"),
|
||||
"New window should have a zen-workspace-id attribute"
|
||||
);
|
||||
|
||||
newWindow.BrowserCommands.closeTabOrWindow();
|
||||
Assert.strictEqual(
|
||||
|
||||
@@ -12,10 +12,6 @@ add_task(async function test_Private_Mode() {
|
||||
private: true,
|
||||
});
|
||||
await privateWindow.gZenWorkspaces.promiseInitialized;
|
||||
ok(
|
||||
privateWindow.document.documentElement.hasAttribute("zen-workspace-id"),
|
||||
"Private window should have a zen-workspace-id attribute"
|
||||
);
|
||||
|
||||
await BrowserTestUtils.closeWindow(privateWindow);
|
||||
await SpecialPowers.popPrefEnv();
|
||||
|
||||
Reference in New Issue
Block a user