author | Beekill95 <nnn_bikiu0707@yahoo.com> |
Fri, 28 Jul 2017 15:03:30 +0700 | |
changeset 373134 | cc352ddd68683ed0c59641cf82958c23d42adedf |
parent 373133 | 79cd0acfa99364d2bedd862959523d5869f8b8e9 |
child 373135 | 46153627ee5fa17c8cc67a76a9a468b36cfd1b52 |
push id | 32291 |
push user | ryanvm@gmail.com |
push date | Mon, 07 Aug 2017 01:16:58 +0000 |
treeherder | mozilla-central@813810854eea [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | dao |
bugs | 1383073 |
milestone | 57.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -7542,16 +7542,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");