Bug 1383073 - Move speculativeConnectOnTabHover to tabbrowser.xml so we don't have to worry about clearing mouseover listeners from tabs. r?dao.
MozReview-Commit-ID: 6Q0EvtJGEIg
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -7650,16 +7650,19 @@
}
}
tabContainer._hoveredTab = this;
if (this.linkedPanel && !this.selected) {
this.linkedBrowser.unselectedTabHover(true);
this.startUnselectedTabHoverTimer();
}
+
+ // Prepare connection to host beforehand.
+ SessionStore.speculativeConnectOnTabHover(this);
]]></body>
</method>
<method name="_mouseleave">
<body><![CDATA[
let tabContainer = this.parentNode;
if (tabContainer._beforeHoveredTab) {
tabContainer._beforeHoveredTab.removeAttribute("beforehovered");
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -351,16 +351,20 @@ this.SessionStore = {
persistTabAttribute: function ss_persistTabAttribute(aName) {
SessionStoreInternal.persistTabAttribute(aName);
},
restoreLastSession: function ss_restoreLastSession() {
SessionStoreInternal.restoreLastSession();
},
+ speculativeConnectOnTabHover(tab) {
+ SessionStoreInternal.speculativeConnectOnTabHover(tab);
+ },
+
getCurrentState(aUpdateAll) {
return SessionStoreInternal.getCurrentState(aUpdateAll);
},
reviveCrashedTab(aTab) {
return SessionStoreInternal.reviveCrashedTab(aTab);
},
@@ -715,16 +719,18 @@ var SessionStoreInternal = {
});
this._max_tabs_undo = this._prefBranch.getIntPref("sessionstore.max_tabs_undo");
this._prefBranch.addObserver("sessionstore.max_tabs_undo", this, true);
this._max_windows_undo = this._prefBranch.getIntPref("sessionstore.max_windows_undo");
this._prefBranch.addObserver("sessionstore.max_windows_undo", this, true);
+ this._restore_on_demand = this._prefBranch.getBoolPref("sessionstore.restore_on_demand");
+ this._prefBranch.addObserver("sessionstore.restore_on_demand", this, true);
gResistFingerprintingEnabled = Services.prefs.getBoolPref("privacy.resistFingerprinting");
Services.prefs.addObserver("privacy.resistFingerprinting", this);
},
/**
* Called on application shutdown, after notifications:
* quit-application-granted, quit-application
@@ -1828,16 +1834,19 @@ var SessionStoreInternal = {
break;
case "sessionstore.max_windows_undo":
this._max_windows_undo = this._prefBranch.getIntPref("sessionstore.max_windows_undo");
this._capClosedWindows();
break;
case "privacy.resistFingerprinting":
gResistFingerprintingEnabled = Services.prefs.getBoolPref("privacy.resistFingerprinting");
break;
+ case "sessionstore.restore_on_demand":
+ this._restore_on_demand = this._prefBranch.getBoolPref("sessionstore.restore_on_demand");
+ break;
}
},
/**
* save state when new tab is added
* @param aWindow
* Window reference
*/
@@ -3274,18 +3283,17 @@ var SessionStoreInternal = {
if (overwriteTabs) {
for (let i = tabbrowser.browsers.length - 1; i >= 0; i--) {
if (!tabbrowser.tabs[i].selected) {
tabbrowser.removeTab(tabbrowser.tabs[i]);
}
}
}
- let restoreOnDemand = this._prefBranch.getBoolPref("sessionstore.restore_on_demand");
- let restoreTabsLazily = this._prefBranch.getBoolPref("sessionstore.restore_tabs_lazily") && restoreOnDemand;
+ let restoreTabsLazily = this._prefBranch.getBoolPref("sessionstore.restore_tabs_lazily") && this._restore_on_demand;
for (var t = 0; t < newTabCount; t++) {
let tabData = winData.tabs[t];
let userContextId = tabData.userContextId;
let select = t == selectTab - 1;
let tab;
@@ -3328,23 +3336,16 @@ var SessionStoreInternal = {
userContextId,
skipBackgroundNotify: true });
if (select) {
let leftoverTab = tabbrowser.selectedTab;
tabbrowser.selectedTab = tab;
tabbrowser.removeTab(leftoverTab);
}
-
- // Prepare connection to the host when users hover mouse over this
- // tab. If we're not restoring on demand, we'll prepare connection
- // when we're restoring next tab.
- if (!tabData.pinned && restoreOnDemand) {
- this.speculativeConnectOnTabHover(tab, url);
- }
}
tabs.push(tab);
if (tabData.hidden) {
tabbrowser.hideTab(tab);
}
@@ -3438,31 +3439,35 @@ var SessionStoreInternal = {
sc.speculativeConnect(uri, null, null);
return true;
}
return false;
},
/**
* Make a connection to a host when users hover mouse on a tab.
+ * This will also set a flag in the tab to prevent us from speculatively
+ * connecting a second time.
*
* @param tab
- * A tab to set up a hover listener.
- * @param url
- * URL of a host.
+ * a tab to speculatively connect on mouse hover.
*/
- speculativeConnectOnTabHover(tab, url) {
- tab.addEventListener("mouseover", () => {
+ speculativeConnectOnTabHover(tab) {
+ if (this._restore_on_demand && !tab.__SS_connectionPrepared && tab.hasAttribute("pending")) {
+ let url = this.getLazyTabValue(tab, "url");
let prepared = this.prepareConnectionToHost(url);
// This is used to test if a connection has been made beforehand.
if (gDebuggingEnabled) {
tab.__test_connection_prepared = prepared;
tab.__test_connection_url = url;
}
- }, {once: true});
+ // A flag indicate that we've prepared a connection for this tab and
+ // if is called again, we shouldn't prepare another connection.
+ tab.__SS_connectionPrepared = true;
+ }
},
/**
* Restore multiple windows using the provided state.
* @param aWindow
* Window reference to the first window to use for restoration.
* Additionally required windows will be opened.
* @param aState
--- a/browser/components/sessionstore/test/browser_speculative_connect.js
+++ b/browser/components/sessionstore/test/browser_speculative_connect.js
@@ -32,30 +32,33 @@ add_task(async function speculative_conn
await BrowserTestUtils.waitForEvent(newWin, "load");
await BrowserTestUtils.waitForEvent(newWin.gBrowser.tabContainer, "SSTabRestored");
let tabs = newWin.gBrowser.tabs;
is(tabs.length, TEST_URLS.length + 1, "Restored right number of tabs");
let e = new MouseEvent("mouseover");
- // First tab should be ignore, since it's the default blank tab when we open a new window.
+ // First tab should be ignored, since it's the default blank tab when we open a new window.
// Trigger a mouse enter on second tab.
tabs[1].dispatchEvent(e);
is(tabs[1].__test_connection_prepared, false, "Second tab doesn't have a connection prepared");
is(tabs[1].__test_connection_url, TEST_URLS[0], "Second tab has correct url");
+ is(tabs[1].__SS_connectionPrepared, true, "Second tab should have __SS_connectionPrepared flag after hovered");
// Trigger a mouse enter on third tab.
tabs[2].dispatchEvent(e);
is(tabs[2].__test_connection_prepared, true, "Third tab has a connection prepared");
is(tabs[2].__test_connection_url, TEST_URLS[1], "Third tab has correct url");
+ is(tabs[2].__SS_connectionPrepared, true, "Third tab should have __SS_connectionPrepared flag after hovered");
// Last tab is the previously selected tab.
tabs[3].dispatchEvent(e);
+ is(tabs[3].__SS_connectionPrepared, undefined, "Previous selected tab shouldn't have __SS_connectionPrepared flag");
is(tabs[3].__test_connection_prepared, undefined, "Previous selected tab should not have a connection prepared");
is(tabs[3].__test_connection_url, undefined, "Previous selected tab should not have a connection prepared");
await BrowserTestUtils.closeWindow(newWin);
});
add_task(async function speculative_connect_restore_automatically() {
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", false);
@@ -73,17 +76,17 @@ add_task(async function speculative_conn
let newWin = undoCloseWindow(0);
// Make sure we wait until this window is restored.
await BrowserTestUtils.waitForEvent(newWin, "load");
await BrowserTestUtils.waitForEvent(newWin.gBrowser.tabContainer, "SSTabRestored");
let tabs = newWin.gBrowser.tabs;
is(tabs.length, TEST_URLS.length + 1, "Restored right number of tabs");
- // First tab is ignore, since it's the default tab open when we open new window
+ // First tab is ignored, since it's the default tab open when we open new window
// Second tab.
is(tabs[1].__test_connection_prepared, false, "Second tab doesn't have a connection prepared");
is(tabs[1].__test_connection_url, TEST_URLS[0], "Second tab has correct host url");
// Third tab.
is(tabs[2].__test_connection_prepared, true, "Third tab has a connection prepared");
is(tabs[2].__test_connection_url, TEST_URLS[1], "Third tab has correct host url");