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

@@ -9,8 +9,9 @@ tab-context-zen-reset-pinned-tab =
.label = Reset Pinned Tab .label = Reset Pinned Tab
.accesskey = R .accesskey = R
tab-context-zen-add-essential = tab-context-zen-add-essential =
.label = Add to Essentials ({ $num } / { $max } slots filled) .label = Add to Essentials
.accesskey = E .accesskey = E
tab-context-zen-add-essential-badge = { $num } / { $max } slots filled
tab-context-zen-remove-essential = tab-context-zen-remove-essential =
.label = Remove from Essentials .label = Remove from Essentials
.accesskey = R .accesskey = R

View File

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

View File

@@ -5,7 +5,7 @@
*/ */
:root:not([inDOMFullscreen='true']):not([chromehidden~='location']):not([chromehidden~='toolbar']) { :root:not([inDOMFullscreen='true']):not([chromehidden~='location']):not([chromehidden~='toolbar']) {
& #tabbrowser-tabbox #tabbrowser-tabpanels .browserSidebarContainer { & #tabbrowser-tabbox #tabbrowser-tabpanels .browserSidebarContainer {
overflow-y: clip; overflow: clip;
:root:not([zen-no-padding='true']) &:not(.zen-glance-overlay) { :root:not([zen-no-padding='true']) &:not(.zen-glance-overlay) {
border-radius: var(--zen-native-inner-radius); border-radius: var(--zen-native-inner-radius);

View File

@@ -374,8 +374,9 @@ body > #confetti {
} }
.zen-site-data-section { .zen-site-data-section {
gap: 6px; gap: 2px;
padding: 8px; padding: 10px;
padding-bottom: 8px;
} }
.zen-site-data-section-header { .zen-site-data-section-header {
@@ -505,7 +506,7 @@ body > #confetti {
#zen-site-data-header { #zen-site-data-header {
gap: 8px; gap: 8px;
align-items: center; align-items: center;
padding: 10px 9px; padding: 10px 8px;
padding-bottom: 0; padding-bottom: 0;
:root[zen-single-toolbar='true']:not([zen-right-side='true']) & { :root[zen-single-toolbar='true']:not([zen-right-side='true']) & {
@@ -550,7 +551,7 @@ body > #confetti {
); );
box-shadow: box-shadow:
0px 2px 4px rgba(0, 0, 0, 0.075), 0px 2px 4px rgba(0, 0, 0, 0.1),
inset 0px 1px 0px light-dark(transparent, rgba(255, 255, 255, 0.15)); inset 0px 1px 0px light-dark(transparent, rgba(255, 255, 255, 0.15));
border-radius: 6px; border-radius: 6px;
--base-border-color: light-dark(rgba(0, 0, 0, 0.175), rgba(255, 255, 255, 0.1)); --base-border-color: light-dark(rgba(0, 0, 0, 0.175), rgba(255, 255, 255, 0.1));

View File

@@ -1106,7 +1106,6 @@
const element = window.MozXULElement.parseXULToFragment(` const element = window.MozXULElement.parseXULToFragment(`
<menuitem id="context_zen-add-essential" <menuitem id="context_zen-add-essential"
data-l10n-id="tab-context-zen-add-essential" data-l10n-id="tab-context-zen-add-essential"
data-l10n-args='{"num": "0", "max": "${this.maxEssentialTabs}"}'
hidden="true" hidden="true"
disabled="true" disabled="true"
command="cmd_contextZenAddToEssentials"/> command="cmd_contextZenAddToEssentials"/>
@@ -1119,21 +1118,24 @@
document.getElementById('context_pinTab')?.before(element); document.getElementById('context_pinTab')?.before(element);
} }
updatePinnedTabContextMenu(contextTab) { async updatePinnedTabContextMenu(contextTab) {
if (!this.enabled) { if (!this.enabled) {
document.getElementById('context_pinTab').hidden = true; document.getElementById('context_pinTab').hidden = true;
return; return;
} }
const isVisible = contextTab.pinned && !contextTab.multiselected; const isVisible = contextTab.pinned && !contextTab.multiselected;
const zenAddEssential = document.getElementById('context_zen-add-essential');
document.getElementById('context_zen-reset-pinned-tab').hidden = document.getElementById('context_zen-reset-pinned-tab').hidden =
!isVisible || !contextTab.getAttribute('zen-pin-id'); !isVisible || !contextTab.getAttribute('zen-pin-id');
document.getElementById('context_zen-replace-pinned-url-with-current').hidden = !isVisible; document.getElementById('context_zen-replace-pinned-url-with-current').hidden = !isVisible;
document.getElementById('context_zen-add-essential').hidden = zenAddEssential.hidden = contextTab.getAttribute('zen-essential') || !!contextTab.group;
contextTab.getAttribute('zen-essential') || !!contextTab.group; zenAddEssential.setAttribute(
document.l10n.setArgs(document.getElementById('context_zen-add-essential'), { 'badge',
num: gBrowser._numZenEssentials, await document.l10n.formatValue('tab-context-zen-add-essential-badge', {
max: this.maxEssentialTabs, num: gBrowser._numZenEssentials,
}); max: this.maxEssentialTabs,
})
);
document document
.getElementById('cmd_contextZenAddToEssentials') .getElementById('cmd_contextZenAddToEssentials')
.setAttribute('disabled', !this.canEssentialBeAdded(contextTab)); .setAttribute('disabled', !this.canEssentialBeAdded(contextTab));