mirror of
https://github.com/zen-browser/desktop.git
synced 2026-03-29 11:51:51 +00:00
fix: Make sure to update cache when swaping docshells, b=bug #11831, c=no-component
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/sessionstore/TabState.sys.mjs b/browser/components/sessionstore/TabState.sys.mjs
|
||||
index 82721356d191055bec0d4b0ca49e481221988801..ffa95005b96ea384433f18dace63faa35d2d21bf 100644
|
||||
index 82721356d191055bec0d4b0ca49e481221988801..238d6ae1a4261e098d1e986e3c3df813d9d625f3 100644
|
||||
--- a/browser/components/sessionstore/TabState.sys.mjs
|
||||
+++ b/browser/components/sessionstore/TabState.sys.mjs
|
||||
@@ -85,7 +85,24 @@ class _TabState {
|
||||
@@ -27,12 +27,3 @@ index 82721356d191055bec0d4b0ca49e481221988801..ffa95005b96ea384433f18dace63faa3
|
||||
|
||||
tabData.userContextId = tab.userContextId || 0;
|
||||
|
||||
@@ -98,7 +115,7 @@ class _TabState {
|
||||
|
||||
// Copy data from the tab state cache only if the tab has fully finished
|
||||
// restoring. We don't want to overwrite data contained in __SS_data.
|
||||
- this.copyFromCache(browser.permanentKey, tabData, options);
|
||||
+ this.copyFromCache(tab.permanentKey, tabData, options);
|
||||
|
||||
// After copyFromCache() was called we check for properties that are kept
|
||||
// in the cache only while the tab is pending or restoring. Once that
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/browser/components/tabbrowser/content/tabgroup.js b/browser/components/tabbrowser/content/tabgroup.js
|
||||
index 9abf115062e7c86196d7cb6b8ac82a9bb63b5a65..150b0266c979bcfec84e0c1975f91bee3c507b39 100644
|
||||
index 9abf115062e7c86196d7cb6b8ac82a9bb63b5a65..9a38d7dc10403c1ee721b6abf33d525a4aa1f821 100644
|
||||
--- a/browser/components/tabbrowser/content/tabgroup.js
|
||||
+++ b/browser/components/tabbrowser/content/tabgroup.js
|
||||
@@ -14,11 +14,11 @@
|
||||
@@ -78,7 +78,20 @@ index 9abf115062e7c86196d7cb6b8ac82a9bb63b5a65..150b0266c979bcfec84e0c1975f91bee
|
||||
|
||||
this.#updateLabelAriaAttributes();
|
||||
|
||||
@@ -143,6 +162,8 @@
|
||||
@@ -132,17 +151,21 @@
|
||||
let tabGroupCreateDetail = this.#wasCreatedByAdoption
|
||||
? { isAdoptingGroup: true }
|
||||
: {};
|
||||
+ if (!this.hasAttribute('drag-image')) {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("TabGroupCreate", {
|
||||
bubbles: true,
|
||||
detail: tabGroupCreateDetail,
|
||||
})
|
||||
);
|
||||
+ }
|
||||
// Reset `wasCreatedByAdoption` to default of false so that we only
|
||||
// claim that a tab group was created by adoption the first time it
|
||||
// mounts after getting created by `Tabbrowser.adoptTabGroup`.
|
||||
this.#wasCreatedByAdoption = false;
|
||||
}
|
||||
@@ -87,7 +100,7 @@ index 9abf115062e7c86196d7cb6b8ac82a9bb63b5a65..150b0266c979bcfec84e0c1975f91bee
|
||||
|
||||
resetDefaultGroupName = () => {
|
||||
this.#defaultGroupName = "";
|
||||
@@ -211,7 +232,10 @@
|
||||
@@ -211,7 +234,10 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -99,7 +112,7 @@ index 9abf115062e7c86196d7cb6b8ac82a9bb63b5a65..150b0266c979bcfec84e0c1975f91bee
|
||||
}
|
||||
|
||||
get color() {
|
||||
@@ -305,6 +329,9 @@
|
||||
@@ -305,6 +331,9 @@
|
||||
}
|
||||
|
||||
set collapsed(val) {
|
||||
@@ -109,7 +122,7 @@ index 9abf115062e7c86196d7cb6b8ac82a9bb63b5a65..150b0266c979bcfec84e0c1975f91bee
|
||||
if (!!val == this.collapsed) {
|
||||
return;
|
||||
}
|
||||
@@ -391,7 +418,6 @@
|
||||
@@ -391,7 +420,6 @@
|
||||
tabGroupName,
|
||||
})
|
||||
.then(result => {
|
||||
@@ -117,7 +130,7 @@ index 9abf115062e7c86196d7cb6b8ac82a9bb63b5a65..150b0266c979bcfec84e0c1975f91bee
|
||||
});
|
||||
}
|
||||
|
||||
@@ -466,13 +492,65 @@
|
||||
@@ -466,13 +494,65 @@
|
||||
* @returns {MozTabbrowserTab[]}
|
||||
*/
|
||||
get tabs() {
|
||||
@@ -188,7 +201,7 @@ index 9abf115062e7c86196d7cb6b8ac82a9bb63b5a65..150b0266c979bcfec84e0c1975f91bee
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -560,7 +638,6 @@
|
||||
@@ -560,7 +640,6 @@
|
||||
);
|
||||
} else {
|
||||
if (tabOrSplitView.pinned) {
|
||||
@@ -196,7 +209,7 @@ index 9abf115062e7c86196d7cb6b8ac82a9bb63b5a65..150b0266c979bcfec84e0c1975f91bee
|
||||
}
|
||||
let tabToMove =
|
||||
this.ownerGlobal === tabOrSplitView.ownerGlobal
|
||||
@@ -625,7 +702,7 @@
|
||||
@@ -625,7 +704,7 @@
|
||||
*/
|
||||
on_click(event) {
|
||||
let isToggleElement =
|
||||
@@ -205,7 +218,7 @@ index 9abf115062e7c86196d7cb6b8ac82a9bb63b5a65..150b0266c979bcfec84e0c1975f91bee
|
||||
event.target === this.#overflowCountLabel;
|
||||
if (isToggleElement && event.button === 0) {
|
||||
event.preventDefault();
|
||||
@@ -696,5 +773,6 @@
|
||||
@@ -696,5 +775,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -105,8 +105,14 @@
|
||||
'#tabbrowser-arrowscrollbox-periphery'
|
||||
);
|
||||
const dragData = draggedTab._dragData;
|
||||
const wrapper = document.createElement('div');
|
||||
const tabRect = window.windowUtils.getBoundsWithoutFlushing(movingTabs[0]);
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.style.width = tabRect.width + 'px';
|
||||
wrapper.style.height = tabRect.height * movingTabs.length + 'px';
|
||||
wrapper.style.overflow = 'clip';
|
||||
wrapper.style.position = 'fixed';
|
||||
wrapper.style.top = '-9999px';
|
||||
periphery.appendChild(wrapper);
|
||||
for (let i = 0; i < movingTabs.length; i++) {
|
||||
const tab = movingTabs[i];
|
||||
const tabClone = tab.cloneNode(true);
|
||||
@@ -125,15 +131,16 @@
|
||||
if (!movingTabs.length > 1) {
|
||||
tabClone.style.transform = `translate(${(tabRect.width - dragData.offsetX) / 2}px, ${(tabRect.height - dragData.offsetY) / 2}px)`;
|
||||
}
|
||||
tabClone.setAttribute('drag-image', 'true');
|
||||
wrapper.appendChild(tabClone);
|
||||
if (isTab(tabClone) && !tabClone.hasAttribute('zen-essential')) {
|
||||
// We need to limit the label content so the drag image doesn't grow too big.
|
||||
const label = tabClone.textLabel;
|
||||
const tabLabelParentWidth = label.parentElement.getBoundingClientRect().width;
|
||||
label.textContent = label.textContent.slice(0, Math.floor(tabLabelParentWidth / 6));
|
||||
}
|
||||
}
|
||||
this.#maybeCreateDragImageDot(movingTabs, wrapper);
|
||||
wrapper.style.width = tabRect.width + 'px';
|
||||
wrapper.style.height = tabRect.height * movingTabs.length + 'px';
|
||||
wrapper.style.overflow = 'clip';
|
||||
wrapper.style.position = 'fixed';
|
||||
wrapper.style.top = '-9999px';
|
||||
periphery.appendChild(wrapper);
|
||||
this._tempDragImageParent = wrapper;
|
||||
return wrapper;
|
||||
}
|
||||
@@ -707,7 +714,9 @@
|
||||
!dropElement ||
|
||||
dropElement.hasAttribute('zen-essential') ||
|
||||
draggedTab.hasAttribute('zen-essential') ||
|
||||
draggedTab.getAttribute('zen-workspace-id') != gZenWorkspaces.activeWorkspace
|
||||
draggedTab.getAttribute('zen-workspace-id') != gZenWorkspaces.activeWorkspace ||
|
||||
!dropElement.visible ||
|
||||
!draggedTab.visible
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@@ -847,7 +856,6 @@
|
||||
const numPinned = gBrowser.pinnedTabCount - numEssentials;
|
||||
const tabToUse = event.target.closest(dropZoneSelector);
|
||||
if (!tabToUse) {
|
||||
this.clearDragOverVisuals();
|
||||
return;
|
||||
}
|
||||
const isPinned = tabToUse.pinned;
|
||||
|
||||
@@ -293,10 +293,8 @@ export class nsZenSessionManager {
|
||||
/**
|
||||
* Collects session data for all tabs in a given window.
|
||||
*
|
||||
* @param sidebarData
|
||||
* The sidebar data object to populate.
|
||||
* @param state
|
||||
* The current session state.
|
||||
* @param sidebarData The sidebar data object to populate.
|
||||
* @param state The current session state.
|
||||
*/
|
||||
#collectTabsData(sidebarData, state) {
|
||||
const tabIdRelationMap = new Map();
|
||||
|
||||
@@ -11,6 +11,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
SessionStore: 'resource:///modules/sessionstore/SessionStore.sys.mjs',
|
||||
TabStateFlusher: 'resource:///modules/sessionstore/TabStateFlusher.sys.mjs',
|
||||
ZenSessionStore: 'resource:///modules/zen/ZenSessionManager.sys.mjs',
|
||||
TabStateCache: 'resource:///modules/sessionstore/TabStateCache.sys.mjs',
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(lazy, 'gWindowSyncEnabled', 'zen.window-sync.enabled');
|
||||
@@ -328,24 +329,6 @@ class nsZenWindowSync {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that all synced tabs with a given ID has the same permanentKey.
|
||||
* @param {Object} aTab - The tab to ensure sync for.
|
||||
*/
|
||||
#makeSureTabSyncsPermanentKey(aTab) {
|
||||
if (!aTab.id) {
|
||||
return;
|
||||
}
|
||||
let permanentKey = aTab.linkedBrowser.permanentKey;
|
||||
this.#runOnAllWindows(null, (win) => {
|
||||
const tab = this.getItemFromWindow(win, aTab.id);
|
||||
if (tab) {
|
||||
tab.linkedBrowser.permanentKey = permanentKey;
|
||||
tab.permanentKey = permanentKey;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a item element from a window by its ID.
|
||||
*
|
||||
@@ -543,6 +526,7 @@ class nsZenWindowSync {
|
||||
* @param {Object} aOtherTab - The tab in the other window.
|
||||
*/
|
||||
async #swapBrowserDocShellsAsync(aOurTab, aOtherTab) {
|
||||
lazy.TabStateFlusher.flush(aOtherTab.linkedBrowser);
|
||||
await this.#styleSwapedBrowsers(aOurTab, aOtherTab, () => {
|
||||
this.#swapBrowserDocSheellsInner(aOurTab, aOtherTab);
|
||||
});
|
||||
@@ -591,14 +575,18 @@ class nsZenWindowSync {
|
||||
*
|
||||
* @param {Object} aOurTab - The tab in the current window.
|
||||
* @param {Object} aOtherTab - The tab in the other window.
|
||||
* @param {boolean} focus - Indicates if the tab should be focused after the swap.
|
||||
* @param {boolean} onClose - Indicates if the swap is done during a tab close operation.
|
||||
* @param {boolean} options.focus - Indicates if the tab should be focused after the swap.
|
||||
* @param {boolean} options.onClose - Indicates if the swap is done during a tab close operation.
|
||||
*/
|
||||
#swapBrowserDocSheellsInner(aOurTab, aOtherTab, focus = true, onClose = false) {
|
||||
#swapBrowserDocSheellsInner(aOurTab, aOtherTab, { focus = true, onClose = false } = {}) {
|
||||
// Can't swap between chrome and content processes.
|
||||
if (aOurTab.linkedBrowser.isRemoteBrowser != aOtherTab.linkedBrowser.isRemoteBrowser) {
|
||||
return false;
|
||||
}
|
||||
// See https://github.com/zen-browser/desktop/issues/11851, swapping the browsers
|
||||
// don't seem to update the state's cache properly, leading to issues when restoring
|
||||
// the session later on.
|
||||
let tabState = this.#getTabState(aOtherTab);
|
||||
// Running `swapBrowsersAndCloseOther` doesn't expect us to use the tab after
|
||||
// the operation, so it doesn't really care about cleaning up the other tab.
|
||||
// We need to make a new tab progress listener for the other tab after the swap.
|
||||
@@ -607,10 +595,6 @@ class nsZenWindowSync {
|
||||
() => {
|
||||
this.log(`Swapping docshells between windows for tab ${aOurTab.id}`);
|
||||
aOurTab.ownerGlobal.gBrowser.swapBrowsersAndCloseOther(aOurTab, aOtherTab, false);
|
||||
// Sometimes, when closing a window for example, when we swap the browsers,
|
||||
// there's a chance that the tab does not have the entries state moved over properly.
|
||||
// To avoid losing history entries, we have to keep the permanentKey in sync.
|
||||
this.#makeSureTabSyncsPermanentKey(aOurTab);
|
||||
// Since we are moving progress listeners around, there's a chance that we
|
||||
// trigger a load while making the switch, and since we remove the previous
|
||||
// tab's listeners, the other browser window will never get the 'finish load' event
|
||||
@@ -626,7 +610,11 @@ class nsZenWindowSync {
|
||||
// We do need to do this though instead of just unloading the browser because
|
||||
// firefox doesn't expect an unloaded + selected tab, so we need to get
|
||||
// around this limitation somehow.
|
||||
if (!onClose && aOtherTab.linkedBrowser?.currentURI.spec !== 'about:blank') {
|
||||
if (
|
||||
!onClose &&
|
||||
(aOtherTab.linkedBrowser?.currentURI.spec !== 'about:blank' ||
|
||||
aOtherTab.hasAttribute('busy'))
|
||||
) {
|
||||
this.log(`Loading about:blank in our tab ${aOtherTab.id} before swap`);
|
||||
aOtherTab.linkedBrowser.loadURI(Services.io.newURI('about:blank'), {
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
@@ -653,7 +641,15 @@ class nsZenWindowSync {
|
||||
// It's also important to note that if we don't flush the state here,
|
||||
// we would start receiving invalid history changes from the the incorrect
|
||||
// browser view that was just swapped out.
|
||||
lazy.TabStateFlusher.flush(aOurTab.linkedBrowser);
|
||||
lazy.TabStateFlusher.flush(aOurTab.linkedBrowser).finally(() => {
|
||||
if (!tabState.entries?.length) {
|
||||
this.log(`Error: No tab state entries found for tab ${aOtherTab.id} during swap`);
|
||||
return;
|
||||
}
|
||||
lazy.TabStateCache.update(aOurTab.linkedBrowser.permanentKey, {
|
||||
entries: tabState.entries,
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -767,9 +763,12 @@ class nsZenWindowSync {
|
||||
for (let tab of activeTabsOnClosedWindow) {
|
||||
const targetTab = this.getItemFromWindow(mostRecentWindow, tab.id);
|
||||
if (targetTab) {
|
||||
targetTab._zenContentsVisible = true;
|
||||
this.log(`Moving active tab ${tab.id} to most recent window on close`);
|
||||
this.#swapBrowserDocSheellsInner(targetTab, tab, targetTab.selected, /* onClose =*/ true);
|
||||
this.#swapBrowserDocSheellsInner(targetTab, tab, {
|
||||
focus: targetTab.selected,
|
||||
onClose: true,
|
||||
});
|
||||
targetTab._zenContentsVisible = true;
|
||||
// We can animate later, whats important is to always stay on the same
|
||||
// process and avoid async operations here to avoid the closed window
|
||||
// being unloaded before the swap is done.
|
||||
@@ -950,7 +949,6 @@ class nsZenWindowSync {
|
||||
SYNC_FLAG_ICON | SYNC_FLAG_LABEL | SYNC_FLAG_MOVE
|
||||
);
|
||||
});
|
||||
this.#makeSureTabSyncsPermanentKey(tab);
|
||||
lazy.TabStateFlusher.flush(tab.linkedBrowser);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user