Bug 1126756 - Listen for |message-manager-disconnect| instead of |TabClose| to teardown UITour. r=Unfocused, a=lmandel
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Thu, 19 Feb 2015 23:45:54 -0800
changeset 250111 9ff796be0d67
parent 250110 8ac02f8d22e5
child 250112 de7488acda8a
push id4503
push userryanvm@gmail.com
push date2015-02-27 21:34 +0000
treeherdermozilla-beta@87d76aead804 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersUnfocused, lmandel
bugs1126756
milestone37.0
Bug 1126756 - Listen for |message-manager-disconnect| instead of |TabClose| to teardown UITour. r=Unfocused, a=lmandel
browser/components/uitour/UITour.jsm
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -675,42 +675,32 @@ this.UITour = {
       }
     }
 
     if (!this.tourBrowsersByWindow.has(window)) {
       this.tourBrowsersByWindow.set(window, new Set());
     }
     this.tourBrowsersByWindow.get(window).add(browser);
 
-    // We don't have a tab if we're in a <browser> without a tab.
-    if (tab) {
-      tab.addEventListener("TabClose", this);
-    }
+    Services.obs.addObserver(this, "message-manager-disconnect", false);
 
     window.addEventListener("SSWindowClosing", this);
 
     return true;
   },
 
   handleEvent: function(aEvent) {
     log.debug("handleEvent: type =", aEvent.type, "event =", aEvent);
     switch (aEvent.type) {
       case "pagehide": {
         let window = this.getChromeWindow(aEvent.target);
         this.teardownTourForWindow(window);
         break;
       }
 
-      case "TabClose": {
-        let tab = aEvent.target;
-        let window = tab.ownerDocument.defaultView;
-        this.teardownTourForBrowser(window, tab.linkedBrowser, true);
-        break;
-      }
-
       case "TabSelect": {
         let window = aEvent.target.ownerDocument.defaultView;
 
         // Teardown the browser of the tab we just switched away from.
         if (aEvent.detail && aEvent.detail.previousTab) {
           let previousTab = aEvent.detail.previousTab;
           let openTourWindows = this.tourBrowsersByWindow.get(window);
           if (openTourWindows.has(previousTab.linkedBrowser)) {
@@ -732,16 +722,47 @@ this.UITour = {
           let window = aEvent.target.ownerDocument.defaultView;
           this.handleUrlbarInput(window);
         }
         break;
       }
     }
   },
 
+  observe: function(aSubject, aTopic, aData) {
+    log.debug("observe: aTopic =", aTopic);
+    switch (aTopic) {
+      // The browser message manager is disconnected when the <browser> is
+      // destroyed and we want to teardown at that point.
+      case "message-manager-disconnect": {
+        let winEnum = Services.wm.getEnumerator("navigator:browser");
+        while (winEnum.hasMoreElements()) {
+          let window = winEnum.getNext();
+          if (window.closed)
+            continue;
+
+          let tourBrowsers = this.tourBrowsersByWindow.get(window);
+          if (!tourBrowsers)
+            continue;
+
+          for (let browser of tourBrowsers) {
+            let messageManager = browser.messageManager;
+            if (aSubject != messageManager) {
+              continue;
+            }
+
+            this.teardownTourForBrowser(window, browser, true);
+            return;
+          }
+        }
+        break;
+      }
+    }
+  },
+
   setTelemetryBucket: function(aPageID) {
     let bucket = BUCKET_NAME + BrowserUITelemetry.BUCKET_SEPARATOR + aPageID;
     BrowserUITelemetry.setBucket(bucket);
   },
 
   setExpiringTelemetryBucket: function(aPageID, aType) {
     let bucket = BUCKET_NAME + BrowserUITelemetry.BUCKET_SEPARATOR + aPageID +
                  BrowserUITelemetry.BUCKET_SEPARATOR + aType;
@@ -765,24 +786,18 @@ this.UITour = {
     log.debug("teardownTourForBrowser: aBrowser = ", aBrowser, aTourPageClosing);
 
     if (this.pageIDSourceBrowsers.has(aBrowser)) {
       let pageID = this.pageIDSourceBrowsers.get(aBrowser);
       this.setExpiringTelemetryBucket(pageID, aTourPageClosing ? "closed" : "inactive");
     }
 
     let openTourBrowsers = this.tourBrowsersByWindow.get(aWindow);
-    if (aTourPageClosing) {
-      let tab = aWindow.gBrowser.getTabForBrowser(aBrowser);
-      if (tab) { // Handle standalone <browser>
-        tab.removeEventListener("TabClose", this);
-        if (openTourBrowsers) {
-          openTourBrowsers.delete(aBrowser);
-        }
-      }
+    if (aTourPageClosing && openTourBrowsers) {
+      openTourBrowsers.delete(aBrowser);
     }
 
     this.hideHighlight(aWindow);
     this.hideInfo(aWindow);
     // Ensure the menu panel is hidden before calling recreatePopup so popup events occur.
     this.hideMenu(aWindow, "appMenu");
     this.hideMenu(aWindow, "loop");
 
@@ -813,19 +828,16 @@ this.UITour = {
 
     let openTourBrowsers = this.tourBrowsersByWindow.get(aWindow);
     if (openTourBrowsers) {
       for (let browser of openTourBrowsers) {
         if (this.pageIDSourceBrowsers.has(browser)) {
           let pageID = this.pageIDSourceBrowsers.get(browser);
           this.setExpiringTelemetryBucket(pageID, "closed");
         }
-
-        let tab = aWindow.gBrowser.getTabForBrowser(browser);
-        tab.removeEventListener("TabClose", this);
       }
     }
 
     this.tourBrowsersByWindow.delete(aWindow);
   },
 
   getChromeWindow: function(aContentDocument) {
     return aContentDocument.defaultView