mirror of
https://github.com/zen-browser/desktop.git
synced 2026-08-25 16:01:34 +00:00
Merge branch 'window-sync' of https://github.com/zen-browser/desktop into window-sync
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
diff --git a/browser/components/tabbrowser/content/tabbrowser.js b/browser/components/tabbrowser/content/tabbrowser.js
|
||||
index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4cd44d980e 100644
|
||||
index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4cd44d980e 100644
|
||||
--- a/browser/components/tabbrowser/content/tabbrowser.js
|
||||
+++ b/browser/components/tabbrowser/content/tabbrowser.js
|
||||
@@ -432,15 +432,64 @@
|
||||
@@ -479,6 +480,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
|
||||
TabBarVisibility.update();
|
||||
}
|
||||
@@ -4896,6 +5024,7 @@
|
||||
@@ -4896,6 +5024,7 @@
|
||||
telemetrySource,
|
||||
} = {}
|
||||
@@ -487,6 +489,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
// When 'closeWindowWithLastTab' pref is enabled, closing all tabs
|
||||
// can be considered equivalent to closing the window.
|
||||
if (
|
||||
@@ -4985,6 +5114,7 @@
|
||||
@@ -4985,6 +5114,7 @@
|
||||
if (lastToClose) {
|
||||
this.removeTab(lastToClose, aParams);
|
||||
@@ -495,6 +498,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
@@ -5023,6 +5153,12 @@
|
||||
@@ -5023,6 +5153,12 @@
|
||||
aTab._closeTimeNoAnimTimerId = Glean.browserTabclose.timeNoAnim.start();
|
||||
}
|
||||
@@ -508,6 +512,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
// Handle requests for synchronously removing an already
|
||||
// asynchronously closing tab.
|
||||
if (!animate && aTab.closing) {
|
||||
@@ -5037,6 +5173,9 @@
|
||||
@@ -5037,6 +5173,9 @@
|
||||
// state).
|
||||
let tabWidth = window.windowUtils.getBoundsWithoutFlushing(aTab).width;
|
||||
@@ -518,6 +523,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
if (
|
||||
!this._beginRemoveTab(aTab, {
|
||||
closeWindowFastpath: true,
|
||||
@@ -5085,7 +5224,13 @@
|
||||
@@ -5085,7 +5224,13 @@
|
||||
// We're not animating, so we can cancel the animation stopwatch.
|
||||
Glean.browserTabclose.timeAnim.cancel(aTab._closeTimeAnimTimerId);
|
||||
@@ -533,6 +539,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5219,7 +5364,7 @@
|
||||
@@ -5219,7 +5364,7 @@
|
||||
closeWindowWithLastTab != null
|
||||
? closeWindowWithLastTab
|
||||
@@ -542,6 +549,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
|
||||
if (closeWindow) {
|
||||
// We've already called beforeunload on all the relevant tabs if we get here,
|
||||
@@ -5243,6 +5388,7 @@
|
||||
@@ -5243,6 +5388,7 @@
|
||||
|
||||
newTab = true;
|
||||
@@ -550,6 +558,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
aTab._endRemoveArgs = [closeWindow, newTab];
|
||||
|
||||
// swapBrowsersAndCloseOther will take care of closing the window without animation.
|
||||
@@ -5283,13 +5429,7 @@
|
||||
@@ -5283,13 +5429,7 @@
|
||||
aTab._mouseleave();
|
||||
|
||||
@@ -565,6 +574,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
} else {
|
||||
TabBarVisibility.update();
|
||||
}
|
||||
@@ -5422,6 +5562,7 @@
|
||||
@@ -5422,6 +5562,7 @@
|
||||
this.tabs[i]._tPos = i;
|
||||
}
|
||||
@@ -573,6 +583,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
if (!this._windowIsClosing) {
|
||||
// update tab close buttons state
|
||||
this.tabContainer._updateCloseButtons();
|
||||
@@ -5643,6 +5784,7 @@
|
||||
@@ -5643,6 +5784,7 @@
|
||||
}
|
||||
|
||||
@@ -581,6 +592,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
|
||||
// If this tab has a successor, it should be selectable, since
|
||||
// hiding or closing a tab removes that tab as a successor.
|
||||
@@ -5655,13 +5797,13 @@
|
||||
@@ -5655,13 +5797,13 @@
|
||||
!excludeTabs.has(aTab.owner) &&
|
||||
Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose")
|
||||
@@ -597,6 +609,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
);
|
||||
|
||||
let tab = this.tabContainer.findNextTab(aTab, {
|
||||
@@ -5677,7 +5819,7 @@
|
||||
@@ -5677,7 +5819,7 @@
|
||||
}
|
||||
|
||||
@@ -606,6 +619,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
}
|
||||
|
||||
// If no qualifying visible tab was found, see if there is a tab in
|
||||
@@ -5698,7 +5840,7 @@
|
||||
@@ -5698,7 +5840,7 @@
|
||||
});
|
||||
}
|
||||
@@ -615,6 +629,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
}
|
||||
|
||||
_blurTab(aTab) {
|
||||
@@ -6104,10 +6246,10 @@
|
||||
@@ -6104,10 +6246,10 @@
|
||||
SessionStore.deleteCustomTabValue(aTab, "hiddenBy");
|
||||
}
|
||||
@@ -628,6 +643,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
aTab.selected ||
|
||||
aTab.closing ||
|
||||
// Tabs that are sharing the screen, microphone or camera cannot be hidden.
|
||||
@@ -6166,6 +6308,7 @@
|
||||
@@ -6166,6 +6308,7 @@
|
||||
* @param {MozTabbrowserTab|MozTabbrowserTabGroup|MozTabbrowserTabGroup.labelElement} aTab
|
||||
*/
|
||||
@@ -636,6 +652,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
if (this.tabs.length == 1) {
|
||||
return null;
|
||||
}
|
||||
@@ -6299,7 +6442,7 @@
|
||||
@@ -6299,7 +6442,7 @@
|
||||
* `true` if element is a `<tab-group>`
|
||||
*/
|
||||
@@ -645,6 +662,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6375,8 +6518,8 @@
|
||||
@@ -6375,8 +6518,8 @@
|
||||
}
|
||||
|
||||
@@ -656,6 +674,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
} else {
|
||||
tabIndex = Math.max(tabIndex, this.pinnedTabCount);
|
||||
}
|
||||
@@ -6402,10 +6545,16 @@
|
||||
@@ -6402,10 +6545,16 @@
|
||||
this.#handleTabMove(
|
||||
element,
|
||||
@@ -675,6 +694,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
if (neighbor && this.isTab(element) && tabIndex > element._tPos) {
|
||||
neighbor.after(element);
|
||||
} else {
|
||||
@@ -6463,23 +6612,28 @@
|
||||
@@ -6463,23 +6612,28 @@
|
||||
#moveTabNextTo(element, targetElement, moveBefore = false, metricsContext) {
|
||||
if (this.isTabGroupLabel(targetElement)) {
|
||||
@@ -710,6 +730,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
} 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 +6646,34 @@
|
||||
@@ -6492,14 +6646,34 @@
|
||||
// move the tab group right before the first unpinned tab.
|
||||
// 4. Moving a tab group and the first unpinned tab is grouped:
|
||||
@@ -746,6 +767,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
element.pinned
|
||||
? this.tabContainer.pinnedTabsContainer
|
||||
: this.tabContainer;
|
||||
@@ -6508,7 +6682,7 @@
|
||||
@@ -6508,7 +6682,7 @@
|
||||
element,
|
||||
() => {
|
||||
@@ -755,6 +777,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
} else if (targetElement) {
|
||||
targetElement.after(element);
|
||||
} else {
|
||||
@@ -6580,10 +6754,10 @@
|
||||
@@ -6580,10 +6754,10 @@
|
||||
* @param {TabMetricsContext} [metricsContext]
|
||||
*/
|
||||
@@ -768,6 +791,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
return;
|
||||
}
|
||||
if (aTab.group && aTab.group.id === aGroup.id) {
|
||||
@@ -6613,6 +6787,7 @@
|
||||
@@ -6613,6 +6787,7 @@
|
||||
|
||||
let state = {
|
||||
@@ -776,6 +800,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
};
|
||||
if (tab.visible) {
|
||||
state.elementIndex = tab.elementIndex;
|
||||
@@ -6639,7 +6814,7 @@
|
||||
@@ -6639,7 +6814,7 @@
|
||||
let changedTabGroup =
|
||||
previousTabState.tabGroupId != currentTabState.tabGroupId;
|
||||
@@ -785,6 +810,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
tab.dispatchEvent(
|
||||
new CustomEvent("TabMove", {
|
||||
bubbles: true,
|
||||
@@ -6676,6 +6851,10 @@
|
||||
@@ -6676,6 +6851,10 @@
|
||||
|
||||
moveActionCallback();
|
||||
@@ -796,6 +822,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
// Clear tabs cache after moving nodes because the order of tabs may have
|
||||
// changed.
|
||||
this.tabContainer._invalidateCachedTabs();
|
||||
@@ -7576,7 +7755,7 @@
|
||||
@@ -7576,7 +7755,7 @@
|
||||
// preventDefault(). It will still raise the window if appropriate.
|
||||
break;
|
||||
@@ -805,6 +832,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
window.focus();
|
||||
aEvent.preventDefault();
|
||||
break;
|
||||
@@ -7593,7 +7772,6 @@
|
||||
@@ -7593,7 +7772,6 @@
|
||||
}
|
||||
case "TabGroupCollapse":
|
||||
@@ -813,6 +841,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
});
|
||||
break;
|
||||
case "TabGroupCreateByUser":
|
||||
@@ -8542,6 +8720,7 @@
|
||||
@@ -8542,6 +8720,7 @@
|
||||
aWebProgress.isTopLevel
|
||||
) {
|
||||
@@ -821,6 +850,7 @@ index c0eafd4faf8d57b8486c5bf8917375850ec8147e..30c8fd7e978eb3036f35b17ae3f6ea4c
|
||||
gBrowser._tabAttrModified(this.mTab, ["busy"]);
|
||||
this.mTab._notselectedsinceload = !this.mTab.selected;
|
||||
}
|
||||
@@ -9543,7 +9722,7 @@ var TabContextMenu = {
|
||||
@@ -9543,7 +9722,7 @@ var TabContextMenu = {
|
||||
);
|
||||
contextUnpinSelectedTabs.hidden =
|
||||
|
||||
@@ -87,8 +87,11 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
|
||||
}
|
||||
|
||||
onTabIconChanged(tab, url = null) {
|
||||
tab.dispatchEvent(new CustomEvent('ZenTabIconChanged', { bubbles: true, detail: { tab } }));
|
||||
tab.dispatchEvent(new CustomEvent('ZenTabIconChanged', { bubbles: true, detail: { tab } }));
|
||||
const iconUrl = url ?? tab.iconImage.src;
|
||||
if (tab.hasAttribute('zen-essential')) {
|
||||
tab.style.setProperty('--zen-essential-tab-icon', `url(${iconUrl})`);
|
||||
if (tab.hasAttribute('zen-essential')) {
|
||||
tab.style.setProperty('--zen-essential-tab-icon', `url(${iconUrl})`);
|
||||
}
|
||||
@@ -156,6 +159,17 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
|
||||
}
|
||||
}
|
||||
|
||||
async _onTabClick(e) {
|
||||
const tab = e.target?.closest('tab');
|
||||
if (e.button === 1 && tab) {
|
||||
await this.onCloseTabShortcut(e, tab, {
|
||||
closeIfPending: Services.prefs.getBoolPref(
|
||||
'zen.pinned-tab-manager.wheel-close-if-pending'
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async resetPinnedTab(tab) {
|
||||
if (!tab) {
|
||||
tab = TabContextMenu.contextTab;
|
||||
@@ -181,6 +195,9 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
|
||||
_initClosePinnedTabShortcut() {
|
||||
let cmdClose = document.getElementById('cmd_close');
|
||||
|
||||
_initClosePinnedTabShortcut() {
|
||||
let cmdClose = document.getElementById('cmd_close');
|
||||
|
||||
if (cmdClose) {
|
||||
cmdClose.addEventListener('command', this.onCloseTabShortcut.bind(this));
|
||||
}
|
||||
@@ -212,6 +229,32 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
|
||||
),
|
||||
];
|
||||
|
||||
async onCloseTabShortcut(
|
||||
event,
|
||||
selectedTab = gBrowser.selectedTab,
|
||||
{
|
||||
behavior = lazy.zenPinnedTabCloseShortcutBehavior,
|
||||
noClose = false,
|
||||
closeIfPending = false,
|
||||
alwaysUnload = false,
|
||||
folderToUnload = null,
|
||||
} = {}
|
||||
) {
|
||||
try {
|
||||
const tabs = Array.isArray(selectedTab) ? selectedTab : [selectedTab];
|
||||
const pinnedTabs = [
|
||||
...new Set(
|
||||
tabs
|
||||
.flatMap((tab) => {
|
||||
if (tab.group?.hasAttribute('split-view-group')) {
|
||||
return tab.group.tabs;
|
||||
}
|
||||
return tab;
|
||||
})
|
||||
.filter((tab) => tab?.pinned)
|
||||
),
|
||||
];
|
||||
|
||||
if (!pinnedTabs.length) {
|
||||
return;
|
||||
}
|
||||
@@ -944,16 +987,16 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
|
||||
}
|
||||
}
|
||||
|
||||
async onTabLabelChanged(tab) {
|
||||
tab.dispatchEvent(new CustomEvent('ZenTabLabelChanged', { detail: { tab } }));
|
||||
if (!this._pinsCache) {
|
||||
return;
|
||||
}
|
||||
// If our current pin in the cache point to about:blank, we need to update the entry
|
||||
const pin = this._pinsCache.find((pin) => pin.uuid === tab.getAttribute('zen-pin-id'));
|
||||
if (!pin) {
|
||||
return;
|
||||
}
|
||||
async onTabLabelChanged(tab) {
|
||||
tab.dispatchEvent(new CustomEvent('ZenTabLabelChanged', { detail: { tab } }));
|
||||
if (!this._pinsCache) {
|
||||
return;
|
||||
}
|
||||
// If our current pin in the cache point to about:blank, we need to update the entry
|
||||
const pin = this._pinsCache.find((pin) => pin.uuid === tab.getAttribute('zen-pin-id'));
|
||||
if (!pin) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pin.url === 'about:blank' && tab.linkedBrowser.currentURI.spec !== 'about:blank') {
|
||||
await this.replacePinnedUrlWithCurrent(tab);
|
||||
|
||||
Reference in New Issue
Block a user