Bug 1383073 - Move speculativeConnectOnTabHover to tabbrowser.xml so we don't have to worry about clearing mouseover listeners from tabs. r=dao.
authorBeekill95 <nnn_bikiu0707@yahoo.com>
Fri, 28 Jul 2017 15:03:30 +0700
changeset 373134 cc352ddd68683ed0c59641cf82958c23d42adedf
parent 373133 79cd0acfa99364d2bedd862959523d5869f8b8e9
child 373135 46153627ee5fa17c8cc67a76a9a468b36cfd1b52
push id32291
push userryanvm@gmail.com
push dateMon, 07 Aug 2017 01:16:58 +0000
treeherdermozilla-central@813810854eea [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdao
bugs1383073
milestone57.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
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
browser/base/content/tabbrowser.xml
browser/components/sessionstore/SessionStore.jsm
browser/components/sessionstore/test/browser_speculative_connect.js
--- 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");