mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1345090 - Modify SessionStore to restore tabs with lazy browsers. r=mikedeboer,dao
MozReview-Commit-ID: 5J5UqlWMxKX
This commit is contained in:
parent
34ae9eb687
commit
a7fa6eb9b7
@ -1613,6 +1613,9 @@ pref("browser.formautofill.experimental", false);
|
||||
pref("browser.formautofill.enabled", false);
|
||||
pref("browser.formautofill.loglevel", "Warn");
|
||||
|
||||
// Whether or not to restore a session with lazy-browser tabs.
|
||||
pref("browser.sessionstore.restore_tabs_lazily", true);
|
||||
|
||||
// Enable safebrowsing v4 tables (suffixed by "-proto") update.
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("urlclassifier.malwareTable", "goog-malware-shavar,goog-unwanted-shavar,goog-malware-proto,goog-unwanted-proto,test-malware-simple,test-unwanted-simple");
|
||||
|
@ -2034,7 +2034,8 @@
|
||||
"addProgressListener", "removeProgressListener", "audioPlaybackStarted",
|
||||
"audioPlaybackStopped", "adjustPriority", "pauseMedia", "stopMedia",
|
||||
"blockMedia", "resumeMedia", "mute", "unmute", "blockedPopups", "lastURI",
|
||||
"purgeSessionHistory", "stopScroll", "startScroll"
|
||||
"purgeSessionHistory", "stopScroll", "startScroll",
|
||||
"userTypedValue", "userTypedClear"
|
||||
]</field>
|
||||
|
||||
<method name="_createLazyBrowser">
|
||||
@ -2052,11 +2053,51 @@
|
||||
switch (name) {
|
||||
case "permitUnload":
|
||||
getter = () => {
|
||||
return function() {
|
||||
return () => {
|
||||
return { permitUnload: true, timedOut: false };
|
||||
};
|
||||
};
|
||||
break;
|
||||
case "reload":
|
||||
case "reloadWithFlags":
|
||||
getter = () => {
|
||||
return (params) => {
|
||||
// Wait for load handler to be instantiated before
|
||||
// initializing the reload.
|
||||
aTab.addEventListener("SSTabRestoring", () => {
|
||||
browser[name](params);
|
||||
}, { once: true });
|
||||
gBrowser._insertBrowser(aTab);
|
||||
};
|
||||
};
|
||||
break;
|
||||
case "isRemoteBrowser":
|
||||
getter = () => {
|
||||
return browser.getAttribute("remote") == "true";
|
||||
};
|
||||
break;
|
||||
case "audioMuted":
|
||||
getter = () => {
|
||||
return false;
|
||||
};
|
||||
break;
|
||||
case "currentURI":
|
||||
getter = () => {
|
||||
let url = SessionStore.getLazyTabValue(aTab, "url");
|
||||
return Services.io.newURI(url);
|
||||
};
|
||||
break;
|
||||
case "contentTitle":
|
||||
getter = () => {
|
||||
return SessionStore.getLazyTabValue(aTab, "title");
|
||||
};
|
||||
break;
|
||||
case "userTypedValue":
|
||||
case "userTypedClear":
|
||||
getter = () => {
|
||||
return SessionStore.getLazyTabValue(aTab, name);
|
||||
};
|
||||
break;
|
||||
default:
|
||||
getter = () => {
|
||||
this._insertBrowser(aTab);
|
||||
@ -2084,9 +2125,8 @@
|
||||
<![CDATA[
|
||||
"use strict";
|
||||
|
||||
// If browser is already inserted, or aTab doesn't have a
|
||||
// browser, don't do anything.
|
||||
if (aTab.linkedPanel || !aTab.linkedBrowser) {
|
||||
// If browser is already inserted don't do anything.
|
||||
if (aTab.linkedPanel) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4876,7 +4916,8 @@
|
||||
tab.linkedBrowser &&
|
||||
tab.linkedBrowser.isRemoteBrowser) {
|
||||
label += " - e10s";
|
||||
if (Services.appinfo.maxWebProcessCount > 1) {
|
||||
if (tab.linkedBrowser.frameLoader &&
|
||||
Services.appinfo.maxWebProcessCount > 1) {
|
||||
label += " (" + tab.linkedBrowser.frameLoader.tabParent.osPid + ")";
|
||||
}
|
||||
}
|
||||
@ -7245,6 +7286,11 @@
|
||||
<parameter name="aMuteReason"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
// Do not attempt to toggle mute state if browser is lazy.
|
||||
if (!this.linkedPanel) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tabContainer = this.parentNode;
|
||||
let browser = this.linkedBrowser;
|
||||
let modifiedAttrs = [];
|
||||
|
@ -334,6 +334,10 @@ this.SessionStore = {
|
||||
SessionStoreInternal.deleteTabValue(aTab, aKey);
|
||||
},
|
||||
|
||||
getLazyTabValue(aTab, aKey) {
|
||||
return SessionStoreInternal.getLazyTabValue(aTab, aKey);
|
||||
},
|
||||
|
||||
getGlobalValue: function ss_getGlobalValue(aKey) {
|
||||
return SessionStoreInternal.getGlobalValue(aKey);
|
||||
},
|
||||
@ -1871,6 +1875,15 @@ var SessionStoreInternal = {
|
||||
if (browser.frameLoader) {
|
||||
this._lastKnownFrameLoader.set(browser.permanentKey, browser.frameLoader);
|
||||
}
|
||||
|
||||
// Only restore if browser has been lazy.
|
||||
if (aTab.__SS_lazyData && !browser.__SS_restoreState && TabStateCache.get(browser)) {
|
||||
let tabState = TabState.clone(aTab);
|
||||
this.restoreTab(aTab, tabState);
|
||||
}
|
||||
|
||||
// The browser has been inserted now, so lazy data is no longer relevant.
|
||||
delete aTab.__SS_lazyData;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -2545,6 +2558,19 @@ var SessionStoreInternal = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves data specific to lazy-browser tabs. If tab is not lazy,
|
||||
* will return undefined.
|
||||
*
|
||||
* @param aTab (xul:tab)
|
||||
* The tabbrowser-tab the data is for.
|
||||
* @param aKey (string)
|
||||
* The key which maps to the desired data.
|
||||
*/
|
||||
getLazyTabValue(aTab, aKey) {
|
||||
return (aTab.__SS_lazyData || {})[aKey];
|
||||
},
|
||||
|
||||
getGlobalValue: function ssi_getGlobalValue(aKey) {
|
||||
return this._globalState.get(aKey);
|
||||
},
|
||||
@ -3272,6 +3298,9 @@ var SessionStoreInternal = {
|
||||
|
||||
let numVisibleTabs = 0;
|
||||
|
||||
let createLazyBrowser = this._prefBranch.getBoolPref("sessionstore.restore_tabs_lazily") &&
|
||||
this._prefBranch.getBoolPref("sessionstore.restore_on_demand");
|
||||
|
||||
for (var t = 0; t < newTabCount; t++) {
|
||||
// When trying to restore into existing tab, we also take the userContextId
|
||||
// into account if present.
|
||||
@ -3280,7 +3309,8 @@ var SessionStoreInternal = {
|
||||
(tabbrowser.tabs[t].getAttribute("usercontextid") == (userContextId || ""));
|
||||
let tab = reuseExisting ? this._maybeUpdateBrowserRemoteness(tabbrowser.tabs[t])
|
||||
: tabbrowser.addTab("about:blank",
|
||||
{ skipAnimation: true,
|
||||
{ createLazyBrowser,
|
||||
skipAnimation: true,
|
||||
userContextId,
|
||||
skipBackgroundNotify: true });
|
||||
|
||||
@ -3595,9 +3625,7 @@ var SessionStoreInternal = {
|
||||
tabbrowser.selectedBrowser == browser ||
|
||||
loadArguments;
|
||||
|
||||
if (!willRestoreImmediately && !forceOnDemand) {
|
||||
TabRestoreQueue.add(tab);
|
||||
}
|
||||
let isBrowserInserted = browser.isConnected;
|
||||
|
||||
// Increase the busy state counter before modifying the tab.
|
||||
this._setWindowStateBusy(window);
|
||||
@ -3665,14 +3693,6 @@ var SessionStoreInternal = {
|
||||
// Save the index in case we updated it above.
|
||||
tabData.index = activeIndex + 1;
|
||||
|
||||
// Start a new epoch to discard all frame script messages relating to a
|
||||
// previous epoch. All async messages that are still on their way to chrome
|
||||
// will be ignored and don't override any tab data set when restoring.
|
||||
let epoch = this.startNextEpoch(browser);
|
||||
|
||||
// keep the data around to prevent dataloss in case
|
||||
// a tab gets closed before it's been properly restored
|
||||
browser.__SS_restoreState = TAB_STATE_NEEDS_RESTORE;
|
||||
browser.setAttribute("pending", "true");
|
||||
tab.setAttribute("pending", "true");
|
||||
|
||||
@ -3700,26 +3720,57 @@ var SessionStoreInternal = {
|
||||
userTypedClear: tabData.userTypedClear || 0
|
||||
});
|
||||
|
||||
this._sendRestoreHistory(browser, {tabData, epoch, loadArguments});
|
||||
|
||||
// Update tab label and icon to show something
|
||||
// while we wait for the messages to be processed.
|
||||
this.updateTabLabelAndIcon(tab, tabData);
|
||||
|
||||
// Restore tab attributes.
|
||||
if ("attributes" in tabData) {
|
||||
TabAttributes.set(tab, tabData.attributes);
|
||||
}
|
||||
|
||||
// This could cause us to ignore MAX_CONCURRENT_TAB_RESTORES a bit, but
|
||||
// it ensures each window will have its selected tab loaded.
|
||||
if (willRestoreImmediately) {
|
||||
this.restoreTabContent(tab, loadArguments, reloadInFreshProcess,
|
||||
restoreContentReason);
|
||||
} else if (!forceOnDemand) {
|
||||
this.restoreNextTab();
|
||||
if (isBrowserInserted) {
|
||||
// Start a new epoch to discard all frame script messages relating to a
|
||||
// previous epoch. All async messages that are still on their way to chrome
|
||||
// will be ignored and don't override any tab data set when restoring.
|
||||
let epoch = this.startNextEpoch(browser);
|
||||
|
||||
// Ensure that the tab will get properly restored in the event the tab
|
||||
// crashes while restoring. But don't set this on lazy browsers as
|
||||
// restoreTab will get called again when the browser is instantiated.
|
||||
browser.__SS_restoreState = TAB_STATE_NEEDS_RESTORE;
|
||||
|
||||
this._sendRestoreHistory(browser, {tabData, epoch, loadArguments});
|
||||
|
||||
// This could cause us to ignore MAX_CONCURRENT_TAB_RESTORES a bit, but
|
||||
// it ensures each window will have its selected tab loaded.
|
||||
if (willRestoreImmediately) {
|
||||
this.restoreTabContent(tab, loadArguments, reloadInFreshProcess,
|
||||
restoreContentReason);
|
||||
} else if (!forceOnDemand) {
|
||||
TabRestoreQueue.add(tab);
|
||||
this.restoreNextTab();
|
||||
}
|
||||
} else {
|
||||
// __SS_lazyData holds data for lazy-browser tabs to proxy for
|
||||
// data unobtainable from the unbound browser. This only applies to lazy
|
||||
// browsers and will be removed once the browser is inserted in the document.
|
||||
// This must preceed `updateTabLabelAndIcon` call for required data to be present.
|
||||
let url = "about:blank";
|
||||
let title = "";
|
||||
|
||||
if (activeIndex in tabData.entries) {
|
||||
url = tabData.entries[activeIndex].url;
|
||||
title = tabData.entries[activeIndex].title || url;
|
||||
}
|
||||
tab.__SS_lazyData = {
|
||||
url,
|
||||
title,
|
||||
userTypedValue: tabData.userTypedValue || "",
|
||||
userTypedClear: tabData.userTypedClear || 0
|
||||
};
|
||||
}
|
||||
|
||||
// Update tab label and icon to show something
|
||||
// while we wait for the messages to be processed.
|
||||
this.updateTabLabelAndIcon(tab, tabData);
|
||||
|
||||
// Decrease the busy state counter after we're done.
|
||||
this._setWindowStateReady(window);
|
||||
},
|
||||
|
@ -32,11 +32,27 @@ function test() {
|
||||
"We still know that no load is ongoing");
|
||||
is(gURLBar.value, "example.com",
|
||||
"Address bar's value correctly restored");
|
||||
// Change tabs to make sure address bar value gets updated
|
||||
gBrowser.selectedTab = gBrowser.tabContainer.getItemAtIndex(0);
|
||||
is(gURLBar.value, "about:mozilla",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
|
||||
// Change tabs to make sure address bar value gets updated. If tab is
|
||||
// lazy, wait for SSTabRestored to ensure address bar has time to update.
|
||||
let tabToSelect = gBrowser.tabContainer.getItemAtIndex(0);
|
||||
if (tabToSelect.linkedBrowser.isConnected) {
|
||||
gBrowser.selectedTab = tabToSelect;
|
||||
is(gURLBar.value, "about:mozilla",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
} else {
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored",
|
||||
function SSTabRestored(event) {
|
||||
if (event.target == tabToSelect) {
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", SSTabRestored, true);
|
||||
is(gURLBar.value, "about:mozilla",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
}
|
||||
}, true);
|
||||
gBrowser.selectedTab = tabToSelect;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -60,15 +76,34 @@ function test() {
|
||||
"No history entries still sets currentURI to about:blank");
|
||||
is(browser.userTypedValue, "example.org",
|
||||
"userTypedValue was correctly restored");
|
||||
ok(!browser.didStartLoadSinceLastUserTyping(),
|
||||
"We still know that no load is ongoing");
|
||||
// didStartLoadSinceLastUserTyping does not exist on lazy tabs.
|
||||
if (browser.didStartLoadSinceLastUserTyping) {
|
||||
ok(!browser.didStartLoadSinceLastUserTyping(),
|
||||
"We still know that no load is ongoing");
|
||||
}
|
||||
is(gURLBar.value, "about:mozilla",
|
||||
"Address bar's value correctly restored");
|
||||
// Change tabs to make sure address bar value gets updated
|
||||
gBrowser.selectedTab = gBrowser.tabContainer.getItemAtIndex(1);
|
||||
is(gURLBar.value, "example.org",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
|
||||
// Change tabs to make sure address bar value gets updated. If tab is
|
||||
// lazy, wait for SSTabRestored to ensure address bar has time to update.
|
||||
let tabToSelect = gBrowser.tabContainer.getItemAtIndex(1);
|
||||
if (tabToSelect.linkedBrowser.isConnected) {
|
||||
gBrowser.selectedTab = tabToSelect;
|
||||
is(gURLBar.value, "example.org",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
} else {
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored",
|
||||
function SSTabRestored(event) {
|
||||
if (event.target == tabToSelect) {
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", SSTabRestored, true);
|
||||
is(gURLBar.value, "example.org",
|
||||
"Address bar's value correctly updated");
|
||||
runNextTest();
|
||||
}
|
||||
}, true);
|
||||
gBrowser.selectedTab = tabToSelect;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,9 @@
|
||||
var stateBackup = ss.getBrowserState();
|
||||
|
||||
function cleanup() {
|
||||
// Reset the pref
|
||||
try {
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
|
||||
} catch (e) {}
|
||||
// Reset the prefs
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_tabs_lazily");
|
||||
ss.setBrowserState(stateBackup);
|
||||
executeSoon(finish);
|
||||
}
|
||||
@ -20,6 +19,8 @@ function test() {
|
||||
// Set the pref to true so we know exactly how many tabs should be restoring at
|
||||
// any given time. This guarantees that a finishing load won't start another.
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
||||
// Don't restore tabs lazily.
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_tabs_lazily", false);
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org/#1", triggeringPrincipal_base64 }] },
|
||||
|
@ -9,6 +9,8 @@ add_task(function* () {
|
||||
// Set the pref to true so we know exactly how many tabs should be restoring at
|
||||
// any given time. This guarantees that a finishing load won't start another.
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
||||
// Don't restore tabs lazily.
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_tabs_lazily", false);
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org#1", triggeringPrincipal_base64 }], extData: { "uniq": r() } },
|
||||
@ -92,5 +94,7 @@ add_task(function* () {
|
||||
yield progressCallback();
|
||||
|
||||
// Cleanup.
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_tabs_lazily");
|
||||
yield promiseBrowserState(stateBackup);
|
||||
});
|
||||
|
@ -97,22 +97,26 @@ function test_setTabState() {
|
||||
ss.setTabValue(tab, "baz", "qux");
|
||||
}
|
||||
|
||||
function onSSTabRestored(aEvent) {
|
||||
is(busyEventCount, 1);
|
||||
is(readyEventCount, 1);
|
||||
is(ss.getTabValue(tab, "baz"), "qux");
|
||||
is(tab.linkedBrowser.currentURI.spec, "http://example.org/");
|
||||
function onSSTabRestoring(aEvent) {
|
||||
if (aEvent.target == tab) {
|
||||
is(busyEventCount, 1);
|
||||
is(readyEventCount, 1);
|
||||
is(ss.getTabValue(tab, "baz"), "qux");
|
||||
is(tab.linkedBrowser.currentURI.spec, "http://example.org/");
|
||||
|
||||
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy);
|
||||
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored);
|
||||
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy);
|
||||
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestoring", onSSTabRestoring);
|
||||
|
||||
runNextTest();
|
||||
runNextTest();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy);
|
||||
window.addEventListener("SSWindowStateReady", onSSWindowStateReady);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestoring", onSSTabRestoring);
|
||||
// Browser must be inserted in order to restore.
|
||||
gBrowser._insertBrowser(tab);
|
||||
ss.setTabState(tab, newTabState);
|
||||
}
|
||||
|
||||
@ -137,23 +141,26 @@ function test_duplicateTab() {
|
||||
ss.setTabValue(newTab, "baz", "qux");
|
||||
}
|
||||
|
||||
function onSSTabRestored(aEvent) {
|
||||
is(busyEventCount, 1);
|
||||
is(readyEventCount, 1);
|
||||
is(ss.getTabValue(newTab, "baz"), "qux");
|
||||
is(newTab.linkedBrowser.currentURI.spec, "about:rights");
|
||||
function onSSTabRestoring(aEvent) {
|
||||
if (aEvent.target == newTab) {
|
||||
is(busyEventCount, 1);
|
||||
is(readyEventCount, 1);
|
||||
is(ss.getTabValue(newTab, "baz"), "qux");
|
||||
is(newTab.linkedBrowser.currentURI.spec, "about:rights");
|
||||
|
||||
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy);
|
||||
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored);
|
||||
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy);
|
||||
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady);
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestoring", onSSTabRestoring);
|
||||
|
||||
runNextTest();
|
||||
runNextTest();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("SSWindowStateBusy", onSSWindowStateBusy);
|
||||
window.addEventListener("SSWindowStateReady", onSSWindowStateReady);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored);
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestoring", onSSTabRestoring);
|
||||
|
||||
gBrowser._insertBrowser(tab);
|
||||
newTab = ss.duplicateTab(window, tab);
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,6 @@ add_task(function* test_scroll_background_tabs() {
|
||||
|
||||
// The second tab should be the one we loaded URL at still
|
||||
tab = newWin.gBrowser.tabs[1];
|
||||
yield promiseTabRestoring(tab);
|
||||
|
||||
ok(tab.hasAttribute("pending"), "Tab should be pending");
|
||||
browser = tab.linkedBrowser;
|
||||
|
@ -47,7 +47,6 @@ add_task(function* test_scroll_background_about_reader_tabs() {
|
||||
|
||||
// The second tab should be the one we loaded URL at still
|
||||
tab = newWin.gBrowser.tabs[1];
|
||||
yield promiseTabRestoring(tab);
|
||||
|
||||
ok(tab.hasAttribute("pending"), "Tab should be pending");
|
||||
browser = tab.linkedBrowser;
|
||||
|
@ -94,18 +94,24 @@ function waitForBrowserState(aState, aSetStateCallback) {
|
||||
let windowObserving = false;
|
||||
let restoreHiddenTabs = Services.prefs.getBoolPref(
|
||||
"browser.sessionstore.restore_hidden_tabs");
|
||||
let restoreTabsLazily = Services.prefs.getBoolPref(
|
||||
"browser.sessionstore.restore_tabs_lazily");
|
||||
|
||||
aState.windows.forEach(function(winState) {
|
||||
winState.tabs.forEach(function(tabState) {
|
||||
if (restoreHiddenTabs || !tabState.hidden)
|
||||
if (!restoreTabsLazily && (restoreHiddenTabs || !tabState.hidden))
|
||||
expectedTabsRestored++;
|
||||
});
|
||||
});
|
||||
|
||||
// There must be only hidden tabs and restoreHiddenTabs = false. We still
|
||||
// If there are only hidden tabs and restoreHiddenTabs = false, we still
|
||||
// expect one of them to be restored because it gets shown automatically.
|
||||
if (!expectedTabsRestored)
|
||||
// Otherwise if lazy tab restore there will only be one tab restored per window.
|
||||
if (!expectedTabsRestored) {
|
||||
expectedTabsRestored = 1;
|
||||
} else if (restoreTabsLazily) {
|
||||
expectedTabsRestored = aState.windows.length;
|
||||
}
|
||||
|
||||
function onSSTabRestored(aEvent) {
|
||||
if (++tabsRestored == expectedTabsRestored) {
|
||||
@ -376,11 +382,11 @@ var gProgressListener = {
|
||||
for (let win of BrowserWindowIterator()) {
|
||||
for (let i = 0; i < win.gBrowser.tabs.length; i++) {
|
||||
let browser = win.gBrowser.tabs[i].linkedBrowser;
|
||||
if (!browser.__SS_restoreState)
|
||||
if (browser.isConnected && !browser.__SS_restoreState)
|
||||
wasRestored++;
|
||||
else if (browser.__SS_restoreState == TAB_STATE_RESTORING)
|
||||
isRestoring++;
|
||||
else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
|
||||
else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE || !browser.isConnected)
|
||||
needsRestore++;
|
||||
}
|
||||
}
|
||||
|
@ -92,12 +92,22 @@ var BrowserHelper = {
|
||||
},
|
||||
|
||||
increasePriority: function NP_BH_increasePriority(aBrowser) {
|
||||
// Ignore if browser is lazy. Once the browser is instantiated, this will
|
||||
// get taken care of by TabBrowserInserted and TabSelect handlers.
|
||||
if (!aBrowser.isConnected) {
|
||||
return;
|
||||
}
|
||||
aBrowser.adjustPriority(PRIORITY_DELTA);
|
||||
_priorityBackup.set(aBrowser.permanentKey,
|
||||
_priorityBackup.get(aBrowser.permanentKey) + PRIORITY_DELTA);
|
||||
},
|
||||
|
||||
decreasePriority: function NP_BH_decreasePriority(aBrowser) {
|
||||
// Ignore if browser is lazy. Once the browser is instantiated, this will
|
||||
// get taken care of by TabBrowserInserted and TabSelect handlers.
|
||||
if (!aBrowser.isConnected) {
|
||||
return;
|
||||
}
|
||||
aBrowser.adjustPriority(PRIORITY_DELTA * -1);
|
||||
_priorityBackup.set(aBrowser.permanentKey,
|
||||
_priorityBackup.get(aBrowser.permanentKey) - PRIORITY_DELTA);
|
||||
|
@ -355,7 +355,8 @@ BrowserTabList.prototype.getTab = function ({ outerWindowID, tabId }) {
|
||||
} else if (typeof tabId == "number") {
|
||||
// Tabs OOP
|
||||
for (let browser of this._getBrowsers()) {
|
||||
if (browser.frameLoader.tabParent &&
|
||||
if (browser.frameLoader &&
|
||||
browser.frameLoader.tabParent &&
|
||||
browser.frameLoader.tabParent.tabId === tabId) {
|
||||
return this._getActorForBrowser(browser);
|
||||
}
|
||||
|
@ -564,6 +564,11 @@ this.BrowserTestUtils = {
|
||||
if (winType == "navigator:browser") {
|
||||
let finalMsgsPromise = new Promise((resolve) => {
|
||||
let browserSet = new Set(win.gBrowser.browsers);
|
||||
// Ensure all browsers have been inserted or we won't get
|
||||
// messages back from them.
|
||||
browserSet.forEach((browser) => {
|
||||
win.gBrowser._insertBrowser(win.gBrowser.getTabForBrowser(browser));
|
||||
})
|
||||
let mm = win.getGroupMessageManager("browsers");
|
||||
|
||||
mm.addMessageListener("SessionStore:update", function onMessage(msg) {
|
||||
|
@ -35,10 +35,11 @@ this.PrivateBrowsingUtils = {
|
||||
|
||||
isBrowserPrivate(aBrowser) {
|
||||
let chromeWin = aBrowser.ownerGlobal;
|
||||
if (chromeWin.gMultiProcessBrowser) {
|
||||
if (chromeWin.gMultiProcessBrowser || !aBrowser.isConnected) {
|
||||
// In e10s we have to look at the chrome window's private
|
||||
// browsing status since the only alternative is to check the
|
||||
// content window, which is in another process.
|
||||
// content window, which is in another process. If the browser
|
||||
// is lazy then the content window doesn't exist.
|
||||
return this.isWindowPrivate(chromeWin);
|
||||
}
|
||||
return this.privacyContextFromWindow(aBrowser.contentWindow).usePrivateBrowsing;
|
||||
|
Loading…
Reference in New Issue
Block a user