Bug 1139588 - Fix waitForDocLoadComplete() to hold onto the weak progress listener to ensure it isn't GC'ed before we saw the document load. r=Gijs, a=test-only
authorTim Taubert <ttaubert@mozilla.com>
Thu, 05 Mar 2015 23:01:58 +0100
changeset 249168 c7c384d18548c231191e37243de7e8217b910e5d
parent 249167 932b7f9d5457217b57a8220aa7812b78a233fb39
child 249169 3cc718d438b5c5fb1af7bad22ec0e04aa3af6398
push id970
push userjryans@gmail.com
push dateTue, 10 Mar 2015 15:54:18 +0000
reviewersGijs, test-only
bugs1139588
milestone37.0
Bug 1139588 - Fix waitForDocLoadComplete() to hold onto the weak progress listener to ensure it isn't GC'ed before we saw the document load. r=Gijs, a=test-only
browser/base/content/test/general/head.js
--- a/browser/base/content/test/general/head.js
+++ b/browser/base/content/test/general/head.js
@@ -458,39 +458,46 @@ function waitForDocLoadAndStopIt(aExpect
 }
 
 /**
  * Waits for the next load to complete in the current browser.
  *
  * @return promise
  */
 function waitForDocLoadComplete(aBrowser=gBrowser) {
-  let deferred = Promise.defer();
-  let progressListener = {
-    onStateChange: function (webProgress, req, flags, status) {
-      let docStop = Ci.nsIWebProgressListener.STATE_IS_NETWORK |
-                    Ci.nsIWebProgressListener.STATE_STOP;
-      info("Saw state " + flags.toString(16) + " and status " + status.toString(16));
+  return new Promise(resolve => {
+    let listener = {
+      onStateChange: function (webProgress, req, flags, status) {
+        let docStop = Ci.nsIWebProgressListener.STATE_IS_NETWORK |
+                      Ci.nsIWebProgressListener.STATE_STOP;
+        info("Saw state " + flags.toString(16) + " and status " + status.toString(16));
 
-      // When a load needs to be retargetted to a new process it is cancelled
-      // with NS_BINDING_ABORTED so ignore that case
-      if ((flags & docStop) == docStop && status != Cr.NS_BINDING_ABORTED) {
-        aBrowser.removeProgressListener(progressListener);
-        info("Browser loaded " + aBrowser.contentWindow.location);
-        deferred.resolve();
-      }
-    },
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
-                                           Ci.nsISupportsWeakReference])
-  };
-  aBrowser.addProgressListener(progressListener);
-  info("Waiting for browser load");
-  return deferred.promise;
+        // When a load needs to be retargetted to a new process it is cancelled
+        // with NS_BINDING_ABORTED so ignore that case
+        if ((flags & docStop) == docStop && status != Cr.NS_BINDING_ABORTED) {
+          aBrowser.removeProgressListener(this);
+          waitForDocLoadComplete.listeners.delete(this);
+          info("Browser loaded " + aBrowser.contentWindow.location);
+          resolve();
+        }
+      },
+      QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
+                                             Ci.nsISupportsWeakReference])
+    };
+    aBrowser.addProgressListener(listener);
+    waitForDocLoadComplete.listeners.add(listener);
+    info("Waiting for browser load");
+  });
 }
 
+// Keep a set of progress listeners for waitForDocLoadComplete() to make sure
+// they're not GC'ed before we saw the page load.
+waitForDocLoadComplete.listeners = new Set();
+registerCleanupFunction(() => waitForDocLoadComplete.listeners.clear());
+
 let FullZoomHelper = {
 
   selectTabAndWaitForLocationChange: function selectTabAndWaitForLocationChange(tab) {
     if (!tab)
       throw new Error("tab must be given.");
     if (gBrowser.selectedTab == tab)
       return Promise.resolve();
     gBrowser.selectedTab = tab;