feat: Make 'Add tab to essentials' use a badge, b=no-bug, c=common, tabs

This commit is contained in:
mr. m
2025-11-14 14:16:27 +01:00
parent 5f6cc6490c
commit a0ce296668
5 changed files with 65 additions and 49 deletions

View File

@@ -1,5 +1,5 @@
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad0c761fb5 100644
index c0eafd4faf8d57b8486c5bf8917375850ec8147e..1bf95403333f914f082b38441d31326cbd973686 100644
--- a/browser/components/tabbrowser/content/tabbrowser.js
+++ b/browser/components/tabbrowser/content/tabbrowser.js
@@ -450,15 +450,64 @@
@@ -420,10 +420,10 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
+ gZenWorkspaces._initialTab._shouldRemove = true;
+ }
+ }
}
+ }
+ else {
+ gZenWorkspaces._tabToRemoveForEmpty = this.selectedTab;
+ }
}
+ this._hasAlreadyInitializedZenSessionStore = true;
if (tabs.length > 1 || !tabs[0].selected) {
@@ -490,7 +490,19 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
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);
@@ -4346,6 +4473,7 @@
@@ -4338,7 +4465,11 @@
const tabContainer = pinned
? this.tabContainer.pinnedTabsContainer
: this.tabContainer;
+ if (itemAfter) {
+ itemAfter.before(tab);
+ } else {
tabContainer.insertBefore(tab, itemAfter);
+ }
}
this._updateTabsAfterInsert();
@@ -4346,6 +4477,7 @@
if (pinned) {
this._updateTabBarForPinnedTabs();
}
@@ -498,7 +510,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
TabBarVisibility.update();
}
@@ -4635,6 +4763,9 @@
@@ -4635,6 +4767,9 @@
return;
}
@@ -508,7 +520,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
this.removeTabs(selectedTabs, { isUserTriggered, telemetrySource });
}
@@ -4896,6 +5027,7 @@
@@ -4896,6 +5031,7 @@
telemetrySource,
} = {}
) {
@@ -516,7 +528,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
// When 'closeWindowWithLastTab' pref is enabled, closing all tabs
// can be considered equivalent to closing the window.
if (
@@ -4985,6 +5117,7 @@
@@ -4985,6 +5121,7 @@
if (lastToClose) {
this.removeTab(lastToClose, aParams);
}
@@ -524,7 +536,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
} catch (e) {
console.error(e);
}
@@ -5023,6 +5156,12 @@
@@ -5023,6 +5160,12 @@
aTab._closeTimeNoAnimTimerId = Glean.browserTabclose.timeNoAnim.start();
}
@@ -537,7 +549,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
// Handle requests for synchronously removing an already
// asynchronously closing tab.
if (!animate && aTab.closing) {
@@ -5037,6 +5176,9 @@
@@ -5037,6 +5180,9 @@
// state).
let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width;
let isLastTab = this.#isLastTabInWindow(aTab);
@@ -547,7 +559,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
if (
!this._beginRemoveTab(aTab, {
closeWindowFastpath: true,
@@ -5085,7 +5227,13 @@
@@ -5085,7 +5231,13 @@
// We're not animating, so we can cancel the animation stopwatch.
Glean.browserTabclose.timeAnim.cancel(aTab._closeTimeAnimTimerId);
aTab._closeTimeAnimTimerId = null;
@@ -562,7 +574,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
return;
}
@@ -5219,7 +5367,7 @@
@@ -5219,7 +5371,7 @@
closeWindowWithLastTab != null
? closeWindowWithLastTab
: !window.toolbar.visible ||
@@ -571,7 +583,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
if (closeWindow) {
// We've already called beforeunload on all the relevant tabs if we get here,
@@ -5243,6 +5391,7 @@
@@ -5243,6 +5395,7 @@
newTab = true;
}
@@ -579,7 +591,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
aTab._endRemoveArgs = [closeWindow, newTab];
// swapBrowsersAndCloseOther will take care of closing the window without animation.
@@ -5283,13 +5432,7 @@
@@ -5283,13 +5436,7 @@
aTab._mouseleave();
if (newTab) {
@@ -594,7 +606,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
} else {
TabBarVisibility.update();
}
@@ -5422,6 +5565,7 @@
@@ -5422,6 +5569,7 @@
this.tabs[i]._tPos = i;
}
@@ -602,7 +614,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
if (!this._windowIsClosing) {
// update tab close buttons state
this.tabContainer._updateCloseButtons();
@@ -5643,6 +5787,7 @@
@@ -5643,6 +5791,7 @@
}
let excludeTabs = new Set(aExcludeTabs);
@@ -610,7 +622,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
// If this tab has a successor, it should be selectable, since
// hiding or closing a tab removes that tab as a successor.
@@ -5655,13 +5800,13 @@
@@ -5655,13 +5804,13 @@
!excludeTabs.has(aTab.owner) &&
Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose")
) {
@@ -626,7 +638,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
);
let tab = this.tabContainer.findNextTab(aTab, {
@@ -5677,7 +5822,7 @@
@@ -5677,7 +5826,7 @@
}
if (tab) {
@@ -635,7 +647,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
}
// If no qualifying visible tab was found, see if there is a tab in
@@ -5698,7 +5843,7 @@
@@ -5698,7 +5847,7 @@
});
}
@@ -644,7 +656,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
}
_blurTab(aTab) {
@@ -6104,10 +6249,10 @@
@@ -6104,10 +6253,10 @@
SessionStore.deleteCustomTabValue(aTab, "hiddenBy");
}
@@ -657,7 +669,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
aTab.selected ||
aTab.closing ||
// Tabs that are sharing the screen, microphone or camera cannot be hidden.
@@ -6166,6 +6311,7 @@
@@ -6166,6 +6315,7 @@
* @param {MozTabbrowserTab|MozTabbrowserTabGroup|MozTabbrowserTabGroup.labelElement} aTab
*/
replaceTabWithWindow(aTab, aOptions) {
@@ -665,7 +677,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
if (this.tabs.length == 1) {
return null;
}
@@ -6299,7 +6445,7 @@
@@ -6299,7 +6449,7 @@
* `true` if element is a `<tab-group>`
*/
isTabGroup(element) {
@@ -674,7 +686,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
}
/**
@@ -6375,8 +6521,8 @@
@@ -6375,8 +6525,8 @@
}
// Don't allow mixing pinned and unpinned tabs.
@@ -685,7 +697,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
} else {
tabIndex = Math.max(tabIndex, this.pinnedTabCount);
}
@@ -6402,10 +6548,16 @@
@@ -6402,10 +6552,16 @@
this.#handleTabMove(
element,
() => {
@@ -704,7 +716,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
if (neighbor && this.isTab(element) && tabIndex > element._tPos) {
neighbor.after(element);
} else {
@@ -6463,23 +6615,28 @@
@@ -6463,23 +6619,28 @@
#moveTabNextTo(element, targetElement, moveBefore = false, metricsContext) {
if (this.isTabGroupLabel(targetElement)) {
targetElement = targetElement.group;
@@ -739,7 +751,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
} 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
@@ -6492,14 +6649,34 @@
@@ -6492,14 +6653,34 @@
// 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.
@@ -775,7 +787,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
element.pinned
? this.tabContainer.pinnedTabsContainer
: this.tabContainer;
@@ -6508,7 +6685,7 @@
@@ -6508,7 +6689,7 @@
element,
() => {
if (moveBefore) {
@@ -784,7 +796,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
} else if (targetElement) {
targetElement.after(element);
} else {
@@ -6580,10 +6757,10 @@
@@ -6580,10 +6761,10 @@
* @param {TabMetricsContext} [metricsContext]
*/
moveTabToGroup(aTab, aGroup, metricsContext) {
@@ -797,7 +809,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
return;
}
if (aTab.group && aTab.group.id === aGroup.id) {
@@ -6613,6 +6790,7 @@
@@ -6613,6 +6794,7 @@
let state = {
tabIndex: tab._tPos,
@@ -805,7 +817,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
};
if (tab.visible) {
state.elementIndex = tab.elementIndex;
@@ -6639,7 +6817,7 @@
@@ -6639,7 +6821,7 @@
let changedTabGroup =
previousTabState.tabGroupId != currentTabState.tabGroupId;
@@ -814,7 +826,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
tab.dispatchEvent(
new CustomEvent("TabMove", {
bubbles: true,
@@ -6676,6 +6854,10 @@
@@ -6676,6 +6858,10 @@
moveActionCallback();
@@ -825,7 +837,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
// Clear tabs cache after moving nodes because the order of tabs may have
// changed.
this.tabContainer._invalidateCachedTabs();
@@ -7576,7 +7758,7 @@
@@ -7576,7 +7762,7 @@
// preventDefault(). It will still raise the window if appropriate.
break;
}
@@ -834,7 +846,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
window.focus();
aEvent.preventDefault();
break;
@@ -7593,7 +7775,6 @@
@@ -7593,7 +7779,6 @@
}
case "TabGroupCollapse":
aEvent.target.tabs.forEach(tab => {
@@ -842,7 +854,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
});
break;
case "TabGroupCreateByUser":
@@ -8542,6 +8723,7 @@
@@ -8542,6 +8727,7 @@
aWebProgress.isTopLevel
) {
this.mTab.setAttribute("busy", "true");
@@ -850,7 +862,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
gBrowser._tabAttrModified(this.mTab, ["busy"]);
this.mTab._notselectedsinceload = !this.mTab.selected;
}
@@ -9543,7 +9725,7 @@ var TabContextMenu = {
@@ -9543,7 +9729,7 @@ var TabContextMenu = {
);
contextUnpinSelectedTabs.hidden =
!this.contextTab.pinned || !this.multiselected;
@@ -859,7 +871,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..2ab3908f421d6bc126eb7a0f886646ad
// Build Ask Chat items
TabContextMenu.GenAI.buildTabMenu(
document.getElementById("context_askChat"),
@@ -9863,6 +10045,7 @@ var TabContextMenu = {
@@ -9863,6 +10049,7 @@ var TabContextMenu = {
)
);
} else {