forked from ZenBrowserMirrors/zen-desktop
feat: Improved tab transitions and fixed a couple of issues with glance, b=(no-bug), c=tabs, common, glance, split-view, workspaces
This commit is contained in:
parent
dda1dab6f3
commit
09ca430b88
14 changed files with 374 additions and 176 deletions
|
@ -9,6 +9,7 @@
|
|||
content/browser/ZenCustomizableUI.sys.mjs (../../zen/common/ZenCustomizableUI.sys.mjs)
|
||||
content/browser/zen-components/ZenUIMigration.mjs (../../zen/common/ZenUIMigration.mjs)
|
||||
content/browser/zen-components/ZenCommonUtils.mjs (../../zen/common/ZenCommonUtils.mjs)
|
||||
content/browser/zen-components/ZenSessionStore.mjs (../../zen/common/ZenSessionStore.mjs)
|
||||
|
||||
content/browser/zen-styles/zen-theme.css (../../zen/common/styles/zen-theme.css)
|
||||
content/browser/zen-styles/zen-buttons.css (../../zen/common/styles/zen-buttons.css)
|
||||
|
|
|
@ -9,3 +9,5 @@
|
|||
<script type="text/javascript" src="chrome://browser/content/zen-components/ZenWorkspaces.mjs"></script>
|
||||
<script type="text/javascript" src="chrome://browser/content/zen-components/ZenWorkspacesSync.mjs"></script>
|
||||
<script type="text/javascript" src="chrome://browser/content/zen-components/ZenActorsManager.mjs"></script>
|
||||
<script type="text/javascript" src="chrome://browser/content/zen-components/ZenSessionStore.mjs"></script>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs
|
||||
index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d81447514e2c 100644
|
||||
index 8c6047e1ada5a22e57e1e665965237c9e22641d7..8d0585e738a5a758ebbddfa0787c71d634dadd4d 100644
|
||||
--- a/browser/components/sessionstore/SessionStore.sys.mjs
|
||||
+++ b/browser/components/sessionstore/SessionStore.sys.mjs
|
||||
@@ -2088,7 +2088,6 @@ var SessionStoreInternal = {
|
||||
|
@ -31,17 +31,19 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814
|
|||
return;
|
||||
}
|
||||
|
||||
@@ -3925,6 +3922,9 @@ var SessionStoreInternal = {
|
||||
@@ -3925,6 +3922,11 @@ var SessionStoreInternal = {
|
||||
Math.min(tabState.index, tabState.entries.length)
|
||||
);
|
||||
tabState.pinned = false;
|
||||
+ tabState.zenEssential = false;
|
||||
+ tabState.zenPinnedId = null;
|
||||
+ tabState.zenIsGlance = false;
|
||||
+ tabState.zenGlanceId = null;
|
||||
+ tabState.zenHasStaticLabel = false;
|
||||
|
||||
if (inBackground === false) {
|
||||
aWindow.gBrowser.selectedTab = newTab;
|
||||
@@ -5239,7 +5239,7 @@ var SessionStoreInternal = {
|
||||
@@ -5239,7 +5241,7 @@ var SessionStoreInternal = {
|
||||
}
|
||||
|
||||
let workspaceID = aWindow.getWorkspaceID();
|
||||
|
@ -50,7 +52,7 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814
|
|||
winData.workspaceID = workspaceID;
|
||||
}
|
||||
},
|
||||
@@ -5430,14 +5430,15 @@ var SessionStoreInternal = {
|
||||
@@ -5430,14 +5432,15 @@ var SessionStoreInternal = {
|
||||
}
|
||||
|
||||
let tabbrowser = aWindow.gBrowser;
|
||||
|
@ -68,7 +70,7 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814
|
|||
continue;
|
||||
}
|
||||
let tabData = lazy.TabState.collect(tab, TAB_CUSTOM_VALUES.get(tab));
|
||||
@@ -5456,8 +5457,8 @@ var SessionStoreInternal = {
|
||||
@@ -5456,8 +5459,8 @@ var SessionStoreInternal = {
|
||||
// We don't store the Firefox View tab in Session Store, so if it was the last selected "tab" when
|
||||
// a window is closed, point to the first item in the tab strip instead (it will never be the Firefox View tab,
|
||||
// since it's only inserted into the tab strip after it's selected).
|
||||
|
@ -79,7 +81,7 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814
|
|||
winData.title = tabbrowser.tabs[0].label;
|
||||
}
|
||||
winData.selected = selectedIndex;
|
||||
@@ -5569,8 +5570,8 @@ var SessionStoreInternal = {
|
||||
@@ -5569,8 +5572,8 @@ var SessionStoreInternal = {
|
||||
// selectTab represents.
|
||||
let selectTab = 0;
|
||||
if (overwriteTabs) {
|
||||
|
@ -90,7 +92,7 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814
|
|||
selectTab = Math.min(selectTab, winData.tabs.length);
|
||||
}
|
||||
|
||||
@@ -5613,6 +5614,7 @@ var SessionStoreInternal = {
|
||||
@@ -5613,6 +5616,7 @@ var SessionStoreInternal = {
|
||||
winData.tabs,
|
||||
winData.groups ?? []
|
||||
);
|
||||
|
@ -98,12 +100,13 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814
|
|||
this._log.debug(
|
||||
`restoreWindow, createTabsForSessionRestore returned ${tabs.length} tabs`
|
||||
);
|
||||
@@ -6162,8 +6164,23 @@ var SessionStoreInternal = {
|
||||
@@ -6162,6 +6166,22 @@ var SessionStoreInternal = {
|
||||
|
||||
// Most of tabData has been restored, now continue with restoring
|
||||
// attributes that may trigger external events.
|
||||
+ if (tabData.zenEssential) {
|
||||
+ tab.setAttribute("zen-essential", "true");
|
||||
+ tabData.pinned = true; // Essential tabs are always pinned.
|
||||
+ }
|
||||
+ if (tabData.zenIsEmpty) {
|
||||
+ tab.setAttribute("zen-empty-tab", "true");
|
||||
|
@ -118,8 +121,5 @@ index 8c6047e1ada5a22e57e1e665965237c9e22641d7..ccd2779d66eda9d034ca51cc3200d814
|
|||
+ tab.setAttribute("zenDefaultUserContextId", true);
|
||||
+ }
|
||||
|
||||
- if (tabData.pinned) {
|
||||
+ if (tabData.pinned || tabData.zenEssential) {
|
||||
if (tabData.pinned) {
|
||||
tabbrowser.pinTab(tab);
|
||||
} else {
|
||||
tabbrowser.unpinTab(tab);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
diff --git a/browser/components/sessionstore/TabState.sys.mjs b/browser/components/sessionstore/TabState.sys.mjs
|
||||
index 8f7ed557e6aa61e7e16ed4a8d785ad5fe651b3d8..254849e13f7566029dc780c45e376e0f0d427cb5 100644
|
||||
index 8f7ed557e6aa61e7e16ed4a8d785ad5fe651b3d8..76f4cf5aef30cb580ef0295fe6928b5a6a362f4b 100644
|
||||
--- a/browser/components/sessionstore/TabState.sys.mjs
|
||||
+++ b/browser/components/sessionstore/TabState.sys.mjs
|
||||
@@ -84,6 +84,16 @@ class _TabState {
|
||||
@@ -84,6 +84,18 @@ class _TabState {
|
||||
tabData.groupId = tab.group.id;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@ index 8f7ed557e6aa61e7e16ed4a8d785ad5fe651b3d8..254849e13f7566029dc780c45e376e0f
|
|||
+ tabData.zenPinnedIcon = tab.getAttribute("zen-pinned-icon");
|
||||
+ tabData.zenIsEmpty = tab.hasAttribute("zen-empty-tab");
|
||||
+ tabData.zenHasStaticLabel = tab.hasAttribute("zen-has-static-label");
|
||||
+ tabData.zenGlanceId = tab.getAttribute("glance-id");
|
||||
+ tabData.zenIsGlance = tab.hasAttribute("zen-glance-tab");
|
||||
+
|
||||
tabData.searchMode = tab.ownerGlobal.gURLBar.getSearchMode(browser, true);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
|
||||
index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b032cf200f1 100644
|
||||
index d5aa64842a35c6697263c63fd3a0571b64b01344..14f5bc046f2e54109bd3fd0402a8f8b598a513c2 100644
|
||||
--- a/browser/components/tabbrowser/content/tabbrowser.js
|
||||
+++ b/browser/components/tabbrowser/content/tabbrowser.js
|
||||
@@ -413,11 +413,41 @@
|
||||
|
@ -292,37 +292,17 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
|
||||
let url = "about:blank";
|
||||
if (tabData.entries?.length) {
|
||||
@@ -3598,7 +3675,29 @@
|
||||
@@ -3598,7 +3675,8 @@
|
||||
skipLoad: true,
|
||||
preferredRemoteType,
|
||||
});
|
||||
-
|
||||
+ tab._originalUrl = url;
|
||||
|
||||
+ if (tabData.zenWorkspace) {
|
||||
+ tab.setAttribute("zen-workspace-id", tabData.zenWorkspace);
|
||||
+ }
|
||||
+ if (tabData.zenPinnedId) {
|
||||
+ tab.setAttribute("zen-pin-id", tabData.zenPinnedId);
|
||||
+ }
|
||||
+ if (tabData.zenIsEmpty) {
|
||||
+ tab.setAttribute("zen-empty-tab", "true");
|
||||
+ }
|
||||
+ if (tabData.zenHasStaticLabel) {
|
||||
+ tab.setAttribute("zen-has-static-label", "true");
|
||||
+ }
|
||||
+ if (tabData.zenEssential) {
|
||||
+ tab.setAttribute("zen-essential", "true");
|
||||
+ }
|
||||
+ if (tabData.zenDefaultUserContextId) {
|
||||
+ tab.setAttribute("zenDefaultUserContextId", "true");
|
||||
+ }
|
||||
+ if (tabData.zenPinnedEntry) {
|
||||
+ tab.setAttribute("zen-pinned-entry", tabData.zenPinnedEntry);
|
||||
+ }
|
||||
+ gZenSessionStore.restoreInitialTabData(tab, tabData);
|
||||
if (select) {
|
||||
tabToSelect = tab;
|
||||
}
|
||||
@@ -3622,7 +3721,8 @@
|
||||
@@ -3622,7 +3700,8 @@
|
||||
// needs calling:
|
||||
shouldUpdateForPinnedTabs = true;
|
||||
}
|
||||
|
@ -332,7 +312,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
let { groupId } = tabData;
|
||||
const tabGroup = tabGroupWorkingData.get(groupId);
|
||||
// if a tab refers to a tab group we don't know, skip any group
|
||||
@@ -3636,7 +3736,10 @@
|
||||
@@ -3636,7 +3715,10 @@
|
||||
tabGroup.stateData.id,
|
||||
tabGroup.stateData.color,
|
||||
tabGroup.stateData.collapsed,
|
||||
|
@ -344,7 +324,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
);
|
||||
tabsFragment.appendChild(tabGroup.node);
|
||||
}
|
||||
@@ -3684,8 +3787,16 @@
|
||||
@@ -3684,8 +3766,16 @@
|
||||
// to remove the old selected tab.
|
||||
if (tabToSelect) {
|
||||
let leftoverTab = this.selectedTab;
|
||||
|
@ -363,7 +343,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
}
|
||||
|
||||
if (tabs.length > 1 || !tabs[0].selected) {
|
||||
@@ -3881,7 +3992,7 @@
|
||||
@@ -3881,7 +3971,7 @@
|
||||
// Ensure we have an index if one was not provided.
|
||||
if (typeof elementIndex != "number" && typeof tabIndex != "number") {
|
||||
// Move the new tab after another tab if needed, to the end otherwise.
|
||||
|
@ -372,7 +352,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
if (
|
||||
!bulkOrderedOpen &&
|
||||
((openerTab &&
|
||||
@@ -3904,7 +4015,7 @@
|
||||
@@ -3904,7 +3994,7 @@
|
||||
) {
|
||||
elementIndex = Infinity;
|
||||
} else if (previousTab.visible) {
|
||||
|
@ -381,7 +361,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
} else if (previousTab == FirefoxViewHandler.tab) {
|
||||
elementIndex = 0;
|
||||
}
|
||||
@@ -3932,10 +4043,10 @@
|
||||
@@ -3932,14 +4022,14 @@
|
||||
}
|
||||
// Ensure index is within bounds.
|
||||
if (tab.pinned) {
|
||||
|
@ -395,7 +375,12 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
index = Math.min(index, allItems.length);
|
||||
}
|
||||
/** @type {MozTabbrowserTab|undefined} */
|
||||
@@ -3947,7 +4058,7 @@
|
||||
- let itemAfter = allItems.at(index);
|
||||
+ let itemAfter = gZenGlanceManager.getTabOrGlanceParent(allItems.at(index));
|
||||
|
||||
// Prevent a flash of unstyled content by setting up the tab content
|
||||
// and inherited attributes before appending it (see Bug 1592054):
|
||||
@@ -3947,7 +4037,7 @@
|
||||
|
||||
this.tabContainer._invalidateCachedTabs();
|
||||
|
||||
|
@ -404,7 +389,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
if (this.isTab(itemAfter) && itemAfter.group == tabGroup) {
|
||||
// Place at the front of, or between tabs in, the same tab group
|
||||
this.tabContainer.insertBefore(tab, itemAfter);
|
||||
@@ -4268,6 +4379,9 @@
|
||||
@@ -4268,6 +4358,9 @@
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -414,7 +399,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
this.removeTabs(selectedTabs, { telemetrySource });
|
||||
}
|
||||
|
||||
@@ -4520,6 +4634,7 @@
|
||||
@@ -4520,6 +4613,7 @@
|
||||
telemetrySource,
|
||||
} = {}
|
||||
) {
|
||||
|
@ -422,7 +407,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
// When 'closeWindowWithLastTab' pref is enabled, closing all tabs
|
||||
// can be considered equivalent to closing the window.
|
||||
if (
|
||||
@@ -4604,6 +4719,7 @@
|
||||
@@ -4604,6 +4698,7 @@
|
||||
if (lastToClose) {
|
||||
this.removeTab(lastToClose, aParams);
|
||||
}
|
||||
|
@ -430,7 +415,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
@@ -4641,6 +4757,12 @@
|
||||
@@ -4641,6 +4736,12 @@
|
||||
aTab._closeTimeNoAnimTimerId = Glean.browserTabclose.timeNoAnim.start();
|
||||
}
|
||||
|
||||
|
@ -443,7 +428,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
// Handle requests for synchronously removing an already
|
||||
// asynchronously closing tab.
|
||||
if (!animate && aTab.closing) {
|
||||
@@ -4655,7 +4777,9 @@
|
||||
@@ -4655,7 +4756,9 @@
|
||||
// frame created for it (for example, by updating the visually selected
|
||||
// state).
|
||||
let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width;
|
||||
|
@ -454,7 +439,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
if (
|
||||
!this._beginRemoveTab(aTab, {
|
||||
closeWindowFastpath: true,
|
||||
@@ -4821,7 +4945,7 @@
|
||||
@@ -4821,7 +4924,7 @@
|
||||
closeWindowWithLastTab != null
|
||||
? closeWindowWithLastTab
|
||||
: !window.toolbar.visible ||
|
||||
|
@ -463,7 +448,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
|
||||
if (closeWindow) {
|
||||
// We've already called beforeunload on all the relevant tabs if we get here,
|
||||
@@ -4845,6 +4969,7 @@
|
||||
@@ -4845,6 +4948,7 @@
|
||||
|
||||
newTab = true;
|
||||
}
|
||||
|
@ -471,7 +456,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
aTab._endRemoveArgs = [closeWindow, newTab];
|
||||
|
||||
// swapBrowsersAndCloseOther will take care of closing the window without animation.
|
||||
@@ -4885,9 +5010,7 @@
|
||||
@@ -4885,9 +4989,7 @@
|
||||
aTab._mouseleave();
|
||||
|
||||
if (newTab) {
|
||||
|
@ -482,7 +467,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
} else {
|
||||
TabBarVisibility.update();
|
||||
}
|
||||
@@ -5016,6 +5139,8 @@
|
||||
@@ -5016,6 +5118,8 @@
|
||||
this.tabs[i]._tPos = i;
|
||||
}
|
||||
|
||||
|
@ -491,7 +476,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
if (!this._windowIsClosing) {
|
||||
if (wasPinned) {
|
||||
this.tabContainer._positionPinnedTabs();
|
||||
@@ -5230,6 +5355,7 @@
|
||||
@@ -5230,6 +5334,7 @@
|
||||
}
|
||||
|
||||
let excludeTabs = new Set(aExcludeTabs);
|
||||
|
@ -499,7 +484,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
|
||||
// If this tab has a successor, it should be selectable, since
|
||||
// hiding or closing a tab removes that tab as a successor.
|
||||
@@ -5242,13 +5368,13 @@
|
||||
@@ -5242,13 +5347,13 @@
|
||||
!excludeTabs.has(aTab.owner) &&
|
||||
Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose")
|
||||
) {
|
||||
|
@ -515,7 +500,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
);
|
||||
|
||||
let tab = this.tabContainer.findNextTab(aTab, {
|
||||
@@ -5264,7 +5390,7 @@
|
||||
@@ -5264,7 +5369,7 @@
|
||||
}
|
||||
|
||||
if (tab) {
|
||||
|
@ -524,7 +509,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
}
|
||||
|
||||
// If no qualifying visible tab was found, see if there is a tab in
|
||||
@@ -5285,7 +5411,7 @@
|
||||
@@ -5285,7 +5390,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -533,7 +518,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
}
|
||||
|
||||
_blurTab(aTab) {
|
||||
@@ -5686,10 +5812,10 @@
|
||||
@@ -5686,10 +5791,10 @@
|
||||
SessionStore.deleteCustomTabValue(aTab, "hiddenBy");
|
||||
}
|
||||
|
||||
|
@ -546,7 +531,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
aTab.selected ||
|
||||
aTab.closing ||
|
||||
// Tabs that are sharing the screen, microphone or camera cannot be hidden.
|
||||
@@ -5986,7 +6112,7 @@
|
||||
@@ -5986,7 +6091,7 @@
|
||||
|
||||
// Don't allow mixing pinned and unpinned tabs.
|
||||
if (this.isTab(element) && element.pinned) {
|
||||
|
@ -555,7 +540,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
} else {
|
||||
tabIndex = Math.max(tabIndex, this.pinnedTabCount);
|
||||
}
|
||||
@@ -6012,10 +6138,16 @@
|
||||
@@ -6012,10 +6117,16 @@
|
||||
this.#handleTabMove(
|
||||
element,
|
||||
() => {
|
||||
|
@ -574,7 +559,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
if (neighbor && this.isTab(element) && tabIndex > element._tPos) {
|
||||
neighbor.after(element);
|
||||
} else {
|
||||
@@ -6084,17 +6216,26 @@
|
||||
@@ -6084,17 +6195,29 @@
|
||||
targetElement = targetElement.group;
|
||||
}
|
||||
}
|
||||
|
@ -583,8 +568,12 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
+ element = element.group;
|
||||
+ }
|
||||
// Don't allow mixing pinned and unpinned tabs.
|
||||
if (element.pinned && !targetElement?.pinned) {
|
||||
- if (element.pinned && !targetElement?.pinned) {
|
||||
- targetElement = this.tabs[this.pinnedTabCount - 1];
|
||||
+ if (element.hasAttribute('zen-essential') && !targetElement?.hasAttribute('zen-essential')) {
|
||||
+ targetElement = this.tabs.filter(tab => !tab.hasAttribute('zen-glance-tab'))[this._numZenEssentials - 1];
|
||||
+ moveBefore = false;
|
||||
+ } else if (element.pinned && !targetElement?.pinned) {
|
||||
+ targetElement = this.tabs.filter(tab => !tab.hasAttribute('zen-glance-tab'))[this.pinnedTabCount - 1];
|
||||
moveBefore = false;
|
||||
} else if (!element.pinned && targetElement && targetElement.pinned) {
|
||||
|
@ -604,7 +593,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
if (element.pinned && this.tabContainer.verticalMode) {
|
||||
return this.tabContainer.verticalPinnedTabsContainer;
|
||||
}
|
||||
@@ -6154,7 +6295,7 @@
|
||||
@@ -6154,7 +6277,7 @@
|
||||
if (!this.isTab(aTab)) {
|
||||
throw new Error("Can only move a tab into a tab group");
|
||||
}
|
||||
|
@ -613,7 +602,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
return;
|
||||
}
|
||||
if (aTab.group && aTab.group.id === aGroup.id) {
|
||||
@@ -6248,6 +6389,10 @@
|
||||
@@ -6248,6 +6371,10 @@
|
||||
|
||||
moveActionCallback();
|
||||
|
||||
|
@ -624,7 +613,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
// Clear tabs cache after moving nodes because the order of tabs may have
|
||||
// changed.
|
||||
this.tabContainer._invalidateCachedTabs();
|
||||
@@ -7145,7 +7290,7 @@
|
||||
@@ -7145,7 +7272,7 @@
|
||||
// preventDefault(). It will still raise the window if appropriate.
|
||||
break;
|
||||
}
|
||||
|
@ -633,7 +622,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
window.focus();
|
||||
aEvent.preventDefault();
|
||||
break;
|
||||
@@ -8044,6 +8189,7 @@
|
||||
@@ -8044,6 +8171,7 @@
|
||||
aWebProgress.isTopLevel
|
||||
) {
|
||||
this.mTab.setAttribute("busy", "true");
|
||||
|
@ -641,7 +630,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
gBrowser._tabAttrModified(this.mTab, ["busy"]);
|
||||
this.mTab._notselectedsinceload = !this.mTab.selected;
|
||||
}
|
||||
@@ -9009,7 +9155,7 @@ var TabContextMenu = {
|
||||
@@ -9009,7 +9137,7 @@ var TabContextMenu = {
|
||||
);
|
||||
contextUnpinSelectedTabs.hidden =
|
||||
!this.contextTab.pinned || !this.multiselected;
|
||||
|
@ -650,7 +639,7 @@ index d5aa64842a35c6697263c63fd3a0571b64b01344..6943dc7f1d3d95ab1da315cbdbda0b03
|
|||
// Move Tab items
|
||||
let contextMoveTabOptions = document.getElementById(
|
||||
"context_moveTabOptions"
|
||||
@@ -9278,6 +9424,7 @@ var TabContextMenu = {
|
||||
@@ -9278,6 +9406,7 @@ var TabContextMenu = {
|
||||
telemetrySource: gBrowser.TabMetrics.METRIC_SOURCE.TAB_STRIP,
|
||||
});
|
||||
} else {
|
||||
|
|
13
src/browser/components/tabbrowser/content/tabgroup-js.patch
Normal file
13
src/browser/components/tabbrowser/content/tabgroup-js.patch
Normal file
|
@ -0,0 +1,13 @@
|
|||
diff --git a/browser/components/tabbrowser/content/tabgroup.js b/browser/components/tabbrowser/content/tabgroup.js
|
||||
index 6dc774ea335b0c5dba7dcf76cdb23728faae1343..b0b9ef236c2e8517db4bcf3270596456bbefe11d 100644
|
||||
--- a/browser/components/tabbrowser/content/tabgroup.js
|
||||
+++ b/browser/components/tabbrowser/content/tabgroup.js
|
||||
@@ -301,7 +301,7 @@
|
||||
*/
|
||||
addTabs(tabs, metricsContext) {
|
||||
for (let tab of tabs) {
|
||||
- if (tab.pinned) {
|
||||
+ if (tab.pinned !== this.pinned) {
|
||||
tab.ownerGlobal.gBrowser.unpinTab(tab);
|
||||
}
|
||||
let tabToMove =
|
|
@ -1,5 +1,5 @@
|
|||
diff --git a/browser/components/tabbrowser/content/tabs.js b/browser/components/tabbrowser/content/tabs.js
|
||||
index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea9596403cef 100644
|
||||
index 84d633471c89230b981d8a07babef4e0c76c0338..7cef57d99eca61f49968a128378d71c44f52556e 100644
|
||||
--- a/browser/components/tabbrowser/content/tabs.js
|
||||
+++ b/browser/components/tabbrowser/content/tabs.js
|
||||
@@ -83,7 +83,7 @@
|
||||
|
@ -46,6 +46,15 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
expandGroupOnDrop = true;
|
||||
}
|
||||
}
|
||||
@@ -868,7 +869,7 @@
|
||||
? event.screenY - window.screenY - tabOffset
|
||||
: event.screenY - window.screenY,
|
||||
scrollPos:
|
||||
- this.verticalMode && tab.pinned
|
||||
+ this.verticalMode && tab.pinned && false
|
||||
? this.verticalPinnedTabsContainer.scrollPosition
|
||||
: this.arrowScrollbox.scrollPosition,
|
||||
screenX: event.screenX,
|
||||
@@ -921,6 +922,10 @@
|
||||
}
|
||||
|
||||
|
@ -76,31 +85,32 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
if (draggedTab && dropEffect == "copy") {
|
||||
let duplicatedDraggedTab;
|
||||
let duplicatedTabs = [];
|
||||
@@ -1116,10 +1133,11 @@
|
||||
@@ -1116,7 +1133,7 @@
|
||||
}
|
||||
} else {
|
||||
let isPinned = draggedTab.pinned;
|
||||
- let numPinned = gBrowser.pinnedTabCount;
|
||||
+ let numPinned = gBrowser._numVisiblePinTabsWithoutCollapsed;
|
||||
+ let essential = draggedTab.hasAttribute("zen-essential");
|
||||
let tabs = this.ariaFocusableItems.slice(
|
||||
- isPinned ? 0 : numPinned,
|
||||
- isPinned ? numPinned : undefined
|
||||
+ isPinned ? (essential ? 0 : gBrowser._numZenEssentials) : numPinned,
|
||||
+ isPinned ? (essential ? gBrowser._numZenEssentials : numPinned) : undefined
|
||||
);
|
||||
let size = this.verticalMode ? "height" : "width";
|
||||
let screenAxis = this.verticalMode ? "screenY" : "screenX";
|
||||
@@ -1211,7 +1229,7 @@
|
||||
item.removeAttribute("tabdrop-samewindow");
|
||||
resolve();
|
||||
};
|
||||
- if (gReduceMotion) {
|
||||
+ if (true || gReduceMotion) {
|
||||
postTransitionCleanup();
|
||||
} else {
|
||||
let onTransitionEnd = transitionendEvent => {
|
||||
@@ -1337,6 +1355,7 @@
|
||||
isPinned ? 0 : numPinned,
|
||||
isPinned ? numPinned : undefined
|
||||
@@ -1135,8 +1152,14 @@
|
||||
(lastMovingTabScreen + tabSize);
|
||||
|
||||
if (this.verticalMode) {
|
||||
+ if (oldTranslateY > 0 && translateOffsetY > tabHeight / 2) {
|
||||
+ newTranslateY += tabHeight;
|
||||
+ }
|
||||
+ if (oldTranslateY < 0 && -translateOffsetY > tabHeight / 2) {
|
||||
+ newTranslateY -= tabHeight;
|
||||
+ }
|
||||
newTranslateY = Math.min(
|
||||
- Math.max(oldTranslateY, firstBound),
|
||||
+ Math.max(newTranslateY, firstBound),
|
||||
lastBound
|
||||
);
|
||||
} else {
|
||||
@@ -1337,6 +1360,7 @@
|
||||
|
||||
let nextItem = this.ariaFocusableItems[newIndex];
|
||||
let tabGroup = isTab(nextItem) && nextItem.group;
|
||||
|
@ -108,7 +118,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
gBrowser.loadTabs(urls, {
|
||||
inBackground,
|
||||
replace,
|
||||
@@ -1369,6 +1388,17 @@
|
||||
@@ -1369,6 +1393,17 @@
|
||||
|
||||
this.finishMoveTogetherSelectedTabs(draggedTab);
|
||||
this.finishAnimateTabMove();
|
||||
|
@ -126,7 +136,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
this.#expandGroupOnDrop(draggedTab);
|
||||
|
||||
if (
|
||||
@@ -1597,7 +1627,7 @@
|
||||
@@ -1597,7 +1632,7 @@
|
||||
}
|
||||
|
||||
get newTabButton() {
|
||||
|
@ -135,7 +145,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
}
|
||||
|
||||
get verticalMode() {
|
||||
@@ -1621,29 +1651,54 @@
|
||||
@@ -1621,29 +1656,54 @@
|
||||
if (this.#allTabs) {
|
||||
return this.#allTabs;
|
||||
}
|
||||
|
@ -198,7 +208,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
}
|
||||
|
||||
/**
|
||||
@@ -1698,23 +1753,18 @@
|
||||
@@ -1698,23 +1758,18 @@
|
||||
}
|
||||
|
||||
let elementIndex = 0;
|
||||
|
@ -226,7 +236,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
let visibleTabsInGroup = child.tabs.filter(tab => tab.visible);
|
||||
visibleTabsInGroup.forEach(tab => {
|
||||
tab.elementIndex = elementIndex++;
|
||||
@@ -1724,10 +1774,7 @@
|
||||
@@ -1724,10 +1779,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,7 +248,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
|
||||
return this.#focusableItems;
|
||||
}
|
||||
@@ -1735,6 +1782,7 @@
|
||||
@@ -1735,6 +1787,7 @@
|
||||
_invalidateCachedTabs() {
|
||||
this.#allTabs = null;
|
||||
this._invalidateCachedVisibleTabs();
|
||||
|
@ -246,7 +256,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
}
|
||||
|
||||
_invalidateCachedVisibleTabs() {
|
||||
@@ -1749,8 +1797,8 @@
|
||||
@@ -1749,8 +1802,8 @@
|
||||
#isContainerVerticalPinnedGrid(tab) {
|
||||
return (
|
||||
this.verticalMode &&
|
||||
|
@ -257,7 +267,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
!this.expandOnHover
|
||||
);
|
||||
}
|
||||
@@ -1766,7 +1814,7 @@
|
||||
@@ -1766,7 +1819,7 @@
|
||||
|
||||
if (node == null) {
|
||||
// We have a container for non-tab elements at the end of the scrollbox.
|
||||
|
@ -266,7 +276,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
}
|
||||
|
||||
node.before(tab);
|
||||
@@ -1861,7 +1909,7 @@
|
||||
@@ -1861,7 +1914,7 @@
|
||||
// There are separate "new tab" buttons for horizontal tabs toolbar, vertical tabs and
|
||||
// for when the tab strip is overflowed (which is shared by vertical and horizontal tabs);
|
||||
// Attach the long click popup to all of them.
|
||||
|
@ -275,7 +285,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
const newTab2 = this.newTabButton;
|
||||
const newTabVertical = document.getElementById(
|
||||
"vertical-tabs-newtab-button"
|
||||
@@ -1956,10 +2004,12 @@
|
||||
@@ -1956,10 +2009,12 @@
|
||||
|
||||
_handleTabSelect(aInstant) {
|
||||
let selectedTab = this.selectedItem;
|
||||
|
@ -288,7 +298,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
selectedTab._notselectedsinceload = false;
|
||||
}
|
||||
|
||||
@@ -2132,6 +2182,7 @@
|
||||
@@ -2132,6 +2187,7 @@
|
||||
}
|
||||
|
||||
_positionPinnedTabs() {
|
||||
|
@ -296,7 +306,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
let tabs = this.visibleTabs;
|
||||
let numPinned = gBrowser.pinnedTabCount;
|
||||
let absPositionHorizontalTabs =
|
||||
@@ -2206,7 +2257,7 @@
|
||||
@@ -2206,7 +2262,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -305,16 +315,25 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
|
||||
let directionX = screenX > dragData.animLastScreenX;
|
||||
let directionY = screenY > dragData.animLastScreenY;
|
||||
@@ -2214,7 +2265,7 @@
|
||||
dragData.animLastScreenX = screenX;
|
||||
@@ -2215,6 +2271,8 @@
|
||||
|
||||
let { width: tabWidth, height: tabHeight } =
|
||||
- draggedTab.getBoundingClientRect();
|
||||
+ (draggedTab.group?.hasAttribute("split-view-group") ? draggedTab.group : draggedTab).getBoundingClientRect();
|
||||
draggedTab.getBoundingClientRect();
|
||||
+ tabWidth += 4; // Add 4px to account for the gap
|
||||
+ tabHeight += 4;
|
||||
let shiftSizeX = tabWidth * movingTabs.length;
|
||||
let shiftSizeY = tabHeight;
|
||||
dragData.tabWidth = tabWidth;
|
||||
@@ -2389,12 +2440,16 @@
|
||||
@@ -2244,7 +2302,7 @@
|
||||
let translateX = screenX - dragData.screenX;
|
||||
let translateY = screenY - dragData.screenY;
|
||||
translateY +=
|
||||
- this.verticalPinnedTabsContainer.scrollPosition - dragData.scrollPos;
|
||||
+ dragData.scrollPos;
|
||||
let firstBoundX = firstTabInRow.screenX - firstMovingTabScreenX;
|
||||
let firstBoundY = firstTabInRow.screenY - firstMovingTabScreenY;
|
||||
let lastBoundX =
|
||||
@@ -2389,12 +2447,16 @@
|
||||
|
||||
this.#clearDragOverCreateGroupTimer();
|
||||
|
||||
|
@ -335,7 +354,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
|
||||
if (this.#rtlMode) {
|
||||
tabs.reverse();
|
||||
@@ -2408,7 +2463,7 @@
|
||||
@@ -2408,7 +2470,7 @@
|
||||
let size = this.verticalMode ? "height" : "width";
|
||||
let translateAxis = this.verticalMode ? "translateY" : "translateX";
|
||||
let scrollDirection = this.verticalMode ? "scrollTop" : "scrollLeft";
|
||||
|
@ -344,7 +363,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
let translateX = event.screenX - dragData.screenX;
|
||||
let translateY = event.screenY - dragData.screenY;
|
||||
|
||||
@@ -2422,12 +2477,21 @@
|
||||
@@ -2422,12 +2484,21 @@
|
||||
let lastTab = tabs.at(-1);
|
||||
let lastMovingTab = movingTabs.at(-1);
|
||||
let firstMovingTab = movingTabs[0];
|
||||
|
@ -367,7 +386,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
translate +=
|
||||
this.arrowScrollbox.scrollbox[scrollDirection] - dragData.scrollPos;
|
||||
} else if (isPinned && this.verticalMode) {
|
||||
@@ -2446,6 +2510,9 @@
|
||||
@@ -2446,6 +2517,9 @@
|
||||
// Shift the `.tab-group-label-container` to shift the label element.
|
||||
item = item.parentElement;
|
||||
}
|
||||
|
@ -377,7 +396,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
item.style.transform = `${translateAxis}(${translate}px)`;
|
||||
}
|
||||
|
||||
@@ -2583,6 +2650,9 @@
|
||||
@@ -2583,6 +2657,9 @@
|
||||
break;
|
||||
}
|
||||
let element = tabs[mid];
|
||||
|
@ -387,7 +406,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
let elementForSize = isTabGroupLabel(element)
|
||||
? element.parentElement
|
||||
: element;
|
||||
@@ -2605,6 +2675,10 @@
|
||||
@@ -2605,6 +2682,10 @@
|
||||
if (!dropElement) {
|
||||
dropElement = this.ariaFocusableItems[oldDropElementIndex];
|
||||
}
|
||||
|
@ -398,7 +417,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
let newDropElementIndex = dropElement
|
||||
? dropElement.elementIndex
|
||||
: oldDropElementIndex;
|
||||
@@ -2613,7 +2687,7 @@
|
||||
@@ -2613,7 +2694,7 @@
|
||||
let shouldCreateGroupOnDrop;
|
||||
let dropBefore;
|
||||
if (dropElement) {
|
||||
|
@ -407,7 +426,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
? dropElement.parentElement
|
||||
: dropElement;
|
||||
|
||||
@@ -2675,12 +2749,12 @@
|
||||
@@ -2675,12 +2756,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -422,7 +441,16 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
dropElement != draggedTab &&
|
||||
isTab(dropElement) &&
|
||||
!dropElement?.group &&
|
||||
@@ -2750,7 +2824,7 @@
|
||||
@@ -2720,7 +2801,7 @@
|
||||
// Dropping right before the tab group.
|
||||
dropElement = dropElementGroup;
|
||||
colorCode = undefined;
|
||||
- } else if (dropElementGroup.collapsed) {
|
||||
+ } else if (dropElement?.group?.hasAttribute("split-view-group")) {
|
||||
// Dropping right after the collapsed tab group.
|
||||
dropElement = dropElementGroup;
|
||||
colorCode = undefined;
|
||||
@@ -2750,7 +2831,7 @@
|
||||
// Shift background tabs to leave a gap where the dragged tab
|
||||
// would currently be dropped.
|
||||
for (let item of tabs) {
|
||||
|
@ -431,7 +459,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
continue;
|
||||
}
|
||||
|
||||
@@ -2759,6 +2833,9 @@
|
||||
@@ -2759,6 +2840,9 @@
|
||||
if (isTabGroupLabel(item)) {
|
||||
// Shift the `.tab-group-label-container` to shift the label element.
|
||||
item = item.parentElement;
|
||||
|
@ -441,7 +469,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
}
|
||||
item.style.transform = transform;
|
||||
}
|
||||
@@ -2811,8 +2888,9 @@
|
||||
@@ -2811,8 +2895,9 @@
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -453,7 +481,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
return;
|
||||
}
|
||||
|
||||
@@ -2824,6 +2902,12 @@
|
||||
@@ -2824,6 +2909,12 @@
|
||||
item = item.parentElement;
|
||||
}
|
||||
item.style.transform = "";
|
||||
|
@ -466,7 +494,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
item.removeAttribute("dragover-createGroup");
|
||||
}
|
||||
this.removeAttribute("movingtab-createGroup");
|
||||
@@ -2870,7 +2954,7 @@
|
||||
@@ -2870,7 +2961,7 @@
|
||||
let postTransitionCleanup = () => {
|
||||
movingTab._moveTogetherSelectedTabsData.animate = false;
|
||||
};
|
||||
|
@ -475,7 +503,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
postTransitionCleanup();
|
||||
} else {
|
||||
let onTransitionEnd = transitionendEvent => {
|
||||
@@ -3043,7 +3127,7 @@
|
||||
@@ -3043,7 +3134,7 @@
|
||||
}
|
||||
|
||||
_notifyBackgroundTab(aTab) {
|
||||
|
@ -484,7 +512,7 @@ index 84d633471c89230b981d8a07babef4e0c76c0338..1a9c56846ff27d68c16b939fb759ea95
|
|||
return;
|
||||
}
|
||||
|
||||
@@ -3169,6 +3253,9 @@
|
||||
@@ -3169,6 +3260,9 @@
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
diff --git a/toolkit/themes/shared/menu.css b/toolkit/themes/shared/menu.css
|
||||
index ecf66f30b2dd18765af467913bb0bc66a8d36a41..6b58db0c1590b0151a3e169b75d4d2ee19db912c 100644
|
||||
index ecf66f30b2dd18765af467913bb0bc66a8d36a41..8ecb03f8f09100dc76e8e4dabd13c366717268b4 100644
|
||||
--- a/toolkit/themes/shared/menu.css
|
||||
+++ b/toolkit/themes/shared/menu.css
|
||||
@@ -345,7 +345,7 @@ menuitem[highlightable] > .menu-text {
|
||||
@@ -345,7 +345,6 @@ menuitem[highlightable] > .menu-text {
|
||||
/* On macOS and Windows, empty icons shouldn't take up any space */
|
||||
menuitem:not(.menuitem-iconic, [image]) > &,
|
||||
menu:not(.menu-iconic) > & {
|
||||
- display: none;
|
||||
+
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
99
src/zen/common/ZenSessionStore.mjs
Normal file
99
src/zen/common/ZenSessionStore.mjs
Normal file
|
@ -0,0 +1,99 @@
|
|||
{
|
||||
class ZenSessionStore extends ZenPreloadedFeature {
|
||||
init() {
|
||||
this.#waitAndCleanup();
|
||||
}
|
||||
|
||||
#glanceTabs = {};
|
||||
promiseInitialized = new Promise((resolve) => {
|
||||
this._resolveInitialized = resolve;
|
||||
});
|
||||
|
||||
restoreInitialTabData(tab, tabData) {
|
||||
if (tabData.zenWorkspace) {
|
||||
tab.setAttribute('zen-workspace-id', tabData.zenWorkspace);
|
||||
}
|
||||
if (tabData.zenPinnedId) {
|
||||
tab.setAttribute('zen-pin-id', tabData.zenPinnedId);
|
||||
}
|
||||
if (tabData.zenIsEmpty) {
|
||||
tab.setAttribute('zen-empty-tab', 'true');
|
||||
}
|
||||
if (tabData.zenHasStaticLabel) {
|
||||
tab.setAttribute('zen-has-static-label', 'true');
|
||||
}
|
||||
if (tabData.zenEssential) {
|
||||
tab.setAttribute('zen-essential', 'true');
|
||||
}
|
||||
if (tabData.zenDefaultUserContextId) {
|
||||
tab.setAttribute('zenDefaultUserContextId', 'true');
|
||||
}
|
||||
if (tabData.zenPinnedEntry) {
|
||||
tab.setAttribute('zen-pinned-entry', tabData.zenPinnedEntry);
|
||||
}
|
||||
if (tabData.zenGlanceId) {
|
||||
// We just found the background used for glance. Find
|
||||
// the current
|
||||
if (tabData.zenIsGlance) {
|
||||
if (this.#glanceTabs[tabData.zenGlanceId]) {
|
||||
this.#glanceTabs[tabData.zenGlanceId].tab = tab;
|
||||
} else {
|
||||
this.#glanceTabs[tabData.zenGlanceId] = {
|
||||
tab: tab,
|
||||
background: null,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (this.#glanceTabs[tabData.zenGlanceId]) {
|
||||
this.#glanceTabs[tabData.zenGlanceId].background = tab;
|
||||
} else {
|
||||
this.#glanceTabs[tabData.zenGlanceId] = {
|
||||
tab: null,
|
||||
background: tab,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async #resolveGlanceTabs() {
|
||||
for (const [id, data] of Object.entries(this.#glanceTabs)) {
|
||||
const { tab, background } = data;
|
||||
// TODO(Restore glance tab): Finish this implementation
|
||||
continue;
|
||||
|
||||
if (!tab || !background) {
|
||||
tab?.removeAttribute('glance-id');
|
||||
background?.removeAttribute('glance-id');
|
||||
continue;
|
||||
}
|
||||
console.log(tab, background);
|
||||
const browserRect = gBrowser.tabbox.getBoundingClientRect();
|
||||
await gZenGlanceManager.openGlance(
|
||||
{
|
||||
url: undefined,
|
||||
x: browserRect.width / 2,
|
||||
y: browserRect.height / 2,
|
||||
width: 0,
|
||||
height: 0,
|
||||
},
|
||||
tab,
|
||||
background
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async #waitAndCleanup() {
|
||||
await SessionStore.promiseInitialized;
|
||||
await this.#resolveGlanceTabs();
|
||||
this.#cleanup();
|
||||
}
|
||||
|
||||
#cleanup() {
|
||||
this._resolveInitialized();
|
||||
delete window.gZenSessionStore;
|
||||
}
|
||||
}
|
||||
|
||||
window.gZenSessionStore = new ZenSessionStore();
|
||||
}
|
|
@ -989,43 +989,54 @@ var gZenVerticalTabsManager = {
|
|||
async renameTabKeydown(event) {
|
||||
event.stopPropagation();
|
||||
if (event.key === 'Enter') {
|
||||
let label = this._tabEdited.querySelector('.tab-label-container-editing');
|
||||
let input = this._tabEdited.querySelector('#tab-label-input');
|
||||
const isTab = !!event.target.closest('.tabbrowser-tab');
|
||||
let label = isTab
|
||||
? this._tabEdited.querySelector('.tab-label-container-editing')
|
||||
: this._tabEdited;
|
||||
let input = document.getElementById('tab-label-input');
|
||||
let newName = input.value.trim();
|
||||
|
||||
// Check if name is blank, reset if so
|
||||
// Always remove, so we can always rename and if it's empty,
|
||||
// it will reset to the original name anyway
|
||||
this._tabEdited.removeAttribute('zen-has-static-label');
|
||||
if (newName) {
|
||||
gBrowser._setTabLabel(this._tabEdited, newName);
|
||||
this._tabEdited.setAttribute('zen-has-static-label', 'true');
|
||||
gZenUIManager.showToast('zen-tabs-renamed');
|
||||
document.documentElement.removeAttribute('zen-renaming-tab');
|
||||
input.remove();
|
||||
if (!isTab) {
|
||||
await this._tabEdited.onRenameFinished(newName);
|
||||
} else {
|
||||
gBrowser.setTabTitle(this._tabEdited);
|
||||
}
|
||||
if (this._tabEdited.getAttribute('zen-pin-id')) {
|
||||
// Update pin title in storage
|
||||
await gZenPinnedTabManager.updatePinTitle(
|
||||
// Check if name is blank, reset if so
|
||||
// Always remove, so we can always rename and if it's empty,
|
||||
// it will reset to the original name anyway
|
||||
this._tabEdited.removeAttribute('zen-has-static-label');
|
||||
if (newName) {
|
||||
gBrowser._setTabLabel(this._tabEdited, newName);
|
||||
this._tabEdited.setAttribute('zen-has-static-label', 'true');
|
||||
gZenUIManager.showToast('zen-tabs-renamed');
|
||||
} else {
|
||||
gBrowser.setTabTitle(this._tabEdited);
|
||||
}
|
||||
if (this._tabEdited.getAttribute('zen-pin-id')) {
|
||||
// Update pin title in storage
|
||||
await gZenPinnedTabManager.updatePinTitle(
|
||||
this._tabEdited,
|
||||
this._tabEdited.label,
|
||||
!!newName
|
||||
);
|
||||
}
|
||||
|
||||
// Maybe add some confetti here?!?
|
||||
gZenUIManager.motion.animate(
|
||||
this._tabEdited,
|
||||
this._tabEdited.label,
|
||||
!!newName
|
||||
{
|
||||
scale: [1, 0.98, 1],
|
||||
},
|
||||
{
|
||||
duration: 0.25,
|
||||
}
|
||||
);
|
||||
}
|
||||
document.documentElement.removeAttribute('zen-renaming-tab');
|
||||
|
||||
// Maybe add some confetti here?!?
|
||||
gZenUIManager.motion.animate(
|
||||
this._tabEdited,
|
||||
{
|
||||
scale: [1, 0.98, 1],
|
||||
},
|
||||
{
|
||||
duration: 0.25,
|
||||
}
|
||||
);
|
||||
|
||||
this._tabEdited.querySelector('.tab-editor-container').remove();
|
||||
const editorContainer = this._tabEdited.querySelector('.tab-editor-container');
|
||||
if (editorContainer) {
|
||||
editorContainer.remove();
|
||||
}
|
||||
label.classList.remove('tab-label-container-editing');
|
||||
|
||||
this._tabEdited = null;
|
||||
|
@ -1035,34 +1046,45 @@ var gZenVerticalTabsManager = {
|
|||
},
|
||||
|
||||
renameTabStart(event) {
|
||||
const isTab = !!event.target.closest('.tabbrowser-tab');
|
||||
if (
|
||||
this._tabEdited ||
|
||||
!Services.prefs.getBoolPref('zen.tabs.rename-tabs') ||
|
||||
Services.prefs.getBoolPref('browser.tabs.closeTabByDblclick') ||
|
||||
((!Services.prefs.getBoolPref('zen.tabs.rename-tabs') ||
|
||||
Services.prefs.getBoolPref('browser.tabs.closeTabByDblclick')) &&
|
||||
isTab) ||
|
||||
!gZenVerticalTabsManager._prefsSidebarExpanded
|
||||
)
|
||||
return;
|
||||
this._tabEdited = event.target.closest('.tabbrowser-tab');
|
||||
this._tabEdited =
|
||||
event.target.closest('.tabbrowser-tab') ||
|
||||
event.target.closest('.zen-current-workspace-indicator-name') ||
|
||||
gZenWorkspaces.activeWorkspaceIndicator.querySelector(
|
||||
'.zen-current-workspace-indicator-name'
|
||||
);
|
||||
if (
|
||||
!this._tabEdited ||
|
||||
!this._tabEdited.pinned ||
|
||||
this._tabEdited.hasAttribute('zen-essential')
|
||||
((!this._tabEdited.pinned || this._tabEdited.hasAttribute('zen-essential')) && isTab)
|
||||
) {
|
||||
this._tabEdited = null;
|
||||
return;
|
||||
}
|
||||
event.stopPropagation();
|
||||
document.documentElement.setAttribute('zen-renaming-tab', 'true');
|
||||
const label = this._tabEdited.querySelector('.tab-label-container');
|
||||
const label = isTab ? this._tabEdited.querySelector('.tab-label-container') : this._tabEdited;
|
||||
label.classList.add('tab-label-container-editing');
|
||||
|
||||
const container = window.MozXULElement.parseXULToFragment(`
|
||||
<vbox class="tab-label-container tab-editor-container" flex="1" align="start" pack="center"></vbox>
|
||||
`);
|
||||
label.after(container);
|
||||
const containerHtml = this._tabEdited.querySelector('.tab-editor-container');
|
||||
if (isTab) {
|
||||
const container = window.MozXULElement.parseXULToFragment(`
|
||||
<vbox class="tab-label-container tab-editor-container" flex="1" align="start" pack="center"></vbox>
|
||||
`);
|
||||
label.after(container);
|
||||
}
|
||||
const containerHtml = isTab
|
||||
? this._tabEdited.querySelector('.tab-editor-container')
|
||||
: this._tabEdited.parentNode;
|
||||
const input = document.createElement('input');
|
||||
input.id = 'tab-label-input';
|
||||
input.value = this._tabEdited.label;
|
||||
input.value = isTab ? this._tabEdited.label : this._tabEdited.textContent;
|
||||
input.addEventListener('keydown', this.renameTabKeydown.bind(this));
|
||||
|
||||
containerHtml.appendChild(input);
|
||||
|
@ -1077,8 +1099,16 @@ var gZenVerticalTabsManager = {
|
|||
return;
|
||||
}
|
||||
document.documentElement.removeAttribute('zen-renaming-tab');
|
||||
this._tabEdited.querySelector('.tab-editor-container').remove();
|
||||
const label = this._tabEdited.querySelector('.tab-label-container-editing');
|
||||
const editorContainer = this._tabEdited.querySelector('.tab-editor-container');
|
||||
let input = document.getElementById('tab-label-input');
|
||||
input.remove();
|
||||
if (editorContainer) {
|
||||
editorContainer.remove();
|
||||
}
|
||||
const isTab = !!this._tabEdited.closest('.tabbrowser-tab');
|
||||
const label = isTab
|
||||
? this._tabEdited.querySelector('.tab-label-container-editing')
|
||||
: this._tabEdited;
|
||||
label.classList.remove('tab-label-container-editing');
|
||||
|
||||
this._tabEdited = null;
|
||||
|
|
|
@ -705,8 +705,8 @@
|
|||
}
|
||||
|
||||
getTabOrGlanceParent(tab) {
|
||||
if (tab?.hasAttribute('glance-id')) {
|
||||
const parentTab = this.#glances.get(tab.getAttribute('glance-id')).parentTab;
|
||||
if (tab?.hasAttribute('glance-id') && this.#glances) {
|
||||
const parentTab = this.#glances.get(tab.getAttribute('glance-id'))?.parentTab;
|
||||
if (parentTab) {
|
||||
return parentTab;
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
|||
);
|
||||
|
||||
window.addEventListener('TabClose', this.handleTabClose.bind(this));
|
||||
window.addEventListener('TabBrowserDiscarded', this.handleTabBrowserDiscarded.bind(this));
|
||||
window.addEventListener('TabSelect', this.onTabSelect.bind(this));
|
||||
this.initializeContextMenu();
|
||||
this.insertIntoContextMenu();
|
||||
|
@ -150,6 +151,17 @@ class ZenViewSplitter extends ZenDOMOperatedFeature {
|
|||
this.removeTabFromGroup(tab, groupIndex, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Event} event - The event that triggered the tab browser discard.
|
||||
* @description Handles the tab browser discard event.
|
||||
*/
|
||||
async handleTabBrowserDiscarded(event) {
|
||||
const tab = event.target;
|
||||
if (tab.group?.hasAttribute('split-view-group')) {
|
||||
gBrowser.explicitUnloadTabs(tab.group.tabs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Event} event - The event that triggered the tab select.
|
||||
* @description Handles the tab select event.
|
||||
|
|
|
@ -356,6 +356,7 @@
|
|||
margin-block: 0 !important;
|
||||
margin-inline: 0 !important;
|
||||
box-shadow: none !important;
|
||||
border-radius: calc(var(--border-radius-medium) - 2px);
|
||||
}
|
||||
/* Adjust padding for content */
|
||||
& .tab-content {
|
||||
|
@ -374,6 +375,27 @@
|
|||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
& .tab-audio-button {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
&[soundplaying]:not([muted]) .tab-icon-stack::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 110%;
|
||||
height: 110%;
|
||||
background-repeat: no-repeat;
|
||||
opacity: 1;
|
||||
background: url('chrome://browser/content/zen-images/note-indicator.svg') no-repeat;
|
||||
top: -70%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.8s ease;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- Essentials Glance Tab Specifics (Floating) --- */
|
||||
|
@ -1239,7 +1261,7 @@
|
|||
|
||||
padding-bottom: var(--zen-toolbox-padding);
|
||||
overflow: hidden;
|
||||
gap: calc(var(--zen-toolbox-padding) - 2px);
|
||||
gap: 4px;
|
||||
transition:
|
||||
max-height 0.3s ease-out,
|
||||
grid-template-columns 0.3s ease-out;
|
||||
|
|
|
@ -42,11 +42,6 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
this._resolveInitialized = resolve;
|
||||
});
|
||||
|
||||
workspaceIndicatorXUL = `
|
||||
<hbox class="zen-current-workspace-indicator-icon"></hbox>
|
||||
<hbox class="zen-current-workspace-indicator-name"></hbox>
|
||||
`;
|
||||
|
||||
async waitForPromises() {
|
||||
if (this.privateWindowOrDisabled) {
|
||||
return;
|
||||
|
@ -858,6 +853,9 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
console.error('gZenWorkspaces: Error initializing theme picker', e);
|
||||
}
|
||||
this.onWindowResize();
|
||||
if (window.gZenSessionStore) {
|
||||
await gZenSessionStore.promiseInitialized;
|
||||
}
|
||||
await this._selectStartPage();
|
||||
this._fixTabPositions();
|
||||
this._resolveInitialized();
|
||||
|
@ -915,7 +913,7 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
) {
|
||||
this.log(`Found tab to select: ${this._tabToSelect}, ${tabs.length}`);
|
||||
setTimeout(() => {
|
||||
gBrowser.selectedTab = tabs[this._tabToSelect];
|
||||
gBrowser.selectedTab = gZenGlanceManager.getTabOrGlanceParent(tabs[this._tabToSelect]);
|
||||
this._removedByStartupPage = true;
|
||||
gBrowser.removeTab(this._tabToRemoveForEmpty, {
|
||||
skipSessionStore: true,
|
||||
|
@ -2941,6 +2939,9 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
|
|||
}
|
||||
|
||||
_initializeWorkspaceTabContextMenus() {
|
||||
if (this.privateWindowOrDisabled) {
|
||||
return;
|
||||
}
|
||||
const menu = document.createXULElement('menu');
|
||||
menu.setAttribute('id', 'context-zen-change-workspace-tab');
|
||||
menu.setAttribute('data-l10n-id', 'context-zen-change-workspace-tab');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue