Backed out changeset 5a4d0f82563f (bug 1110602) for about:accounts test failures.
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Wed, 21 Jan 2015 11:56:14 -0800
changeset 253770 9ea84a34c51842017bbf6e68dfccbcf3dcd50a9a
parent 253769 39c78d4281d5793ed51941c6a6d652d6b1fac3ac
child 253771 3ca92178aac791e5823f9a6ed57a864733b23c27
push id721
push userjlund@mozilla.com
push dateTue, 21 Apr 2015 23:03:33 +0000
treeherdermozilla-release@d27c9211ebb3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1110602
milestone38.0a1
backs out5a4d0f82563fe23099e4494dd03cc1670c718d55
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
Backed out changeset 5a4d0f82563f (bug 1110602) for about:accounts test failures.
browser/components/uitour/UITour.jsm
browser/components/uitour/test/browser_UITour_detach_tab.js
browser/components/uitour/test/browser_UITour_observe.js
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -54,19 +54,20 @@ XPCOMUtils.defineLazyGetter(this, "log",
     prefix: "UITour",
   };
   return new ConsoleAPI(consoleOptions);
 });
 
 this.UITour = {
   url: null,
   seenPageIDs: null,
-  pageIDSourceBrowsers: new WeakMap(),
-  /* Map from browser chrome windows to a Set of <browser>s in which a tour is open (both visible and hidden) */
-  tourBrowsersByWindow: new WeakMap(),
+  pageIDSourceTabs: new WeakMap(),
+  pageIDSourceWindows: new WeakMap(),
+  /* Map from browser windows to a set of tabs in which a tour is open */
+  originTabs: new WeakMap(),
   urlbarCapture: new WeakMap(),
   appMenuOpenForAnnotation: new Set(),
   availableTargetsCache: new WeakMap(),
 
   _detachingTab: false,
   _annotationPanelMutationObservers: new WeakMap(),
   _queuedEvents: [],
   _pendingDoc: null,
@@ -379,17 +380,22 @@ this.UITour = {
         // pageID, as it could make parsing the telemetry bucket name difficult.
         if (typeof data.pageID != "string" ||
             data.pageID.contains(BrowserUITelemetry.BUCKET_SEPARATOR)) {
           log.warn("registerPageID: Invalid page ID specified");
           break;
         }
 
         this.addSeenPageID(data.pageID);
-        this.pageIDSourceBrowsers.set(browser, data.pageID);
+
+        // Store tabs and windows separately so we don't need to loop over all
+        // tabs when a window is closed.
+        this.pageIDSourceTabs.set(tab, data.pageID);
+        this.pageIDSourceWindows.set(window, data.pageID);
+
         this.setTelemetryBucket(data.pageID);
 
         break;
       }
 
       case "showHighlight": {
         let targetPromise = this.getTarget(window, data.target);
         targetPromise.then(target => {
@@ -627,91 +633,104 @@ this.UITour = {
 
       case "ping": {
         if (typeof data.callbackID == "string")
           this.sendPageCallback(messageManager, data.callbackID);
         break;
       }
     }
 
-    if (!this.tourBrowsersByWindow.has(window)) {
-      this.tourBrowsersByWindow.set(window, new Set());
-    }
-    this.tourBrowsersByWindow.get(window).add(browser);
+    if (!window.gMultiProcessBrowser) { // Non-e10s. See bug 1089000.
+      if (!this.originTabs.has(window)) {
+        this.originTabs.set(window, new Set());
+      }
 
-    // We don't have a tab if it's being detached or we're in a <browser> without a tab.
-    if (tab) {
+      this.originTabs.get(window).add(tab);
       tab.addEventListener("TabClose", this);
-      if (!window.gMultiProcessBrowser) {
-        tab.addEventListener("TabBecomingWindow", this);
-      }
+      tab.addEventListener("TabBecomingWindow", this);
+      window.addEventListener("SSWindowClosing", this);
     }
 
-    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);
+        this.teardownTour(window);
         break;
       }
 
       case "TabBecomingWindow":
         this._detachingTab = true;
         // Fall through
       case "TabClose": {
         let tab = aEvent.target;
+        if (this.pageIDSourceTabs.has(tab)) {
+          let pageID = this.pageIDSourceTabs.get(tab);
+
+          // Delete this from the window cache, so if the window is closed we
+          // don't expire this page ID twice.
+          let window = tab.ownerDocument.defaultView;
+          if (this.pageIDSourceWindows.get(window) == pageID)
+            this.pageIDSourceWindows.delete(window);
+
+          this.setExpiringTelemetryBucket(pageID, "closed");
+        }
+
         let window = tab.ownerDocument.defaultView;
-        this.teardownTourForBrowser(window, tab.linkedBrowser, true);
+        this.teardownTour(window);
         break;
       }
 
       case "TabSelect": {
-        let window = aEvent.target.ownerDocument.defaultView;
-
         if (aEvent.detail && aEvent.detail.previousTab) {
           let previousTab = aEvent.detail.previousTab;
-          let openTourWindows = this.tourBrowsersByWindow.get(window);
-          if (openTourWindows.has(previousTab.linkedBrowser)) {
-            this.teardownTourForBrowser(window, previousTab.linkedBrowser, false);
+
+          if (this.pageIDSourceTabs.has(previousTab)) {
+            let pageID = this.pageIDSourceTabs.get(previousTab);
+            this.setExpiringTelemetryBucket(pageID, "inactive");
           }
         }
 
+        let window = aEvent.target.ownerDocument.defaultView;
         let pendingDoc;
         if (this._detachingTab && this._pendingDoc && (pendingDoc = this._pendingDoc.get())) {
           let selectedTab = window.gBrowser.selectedTab;
           if (selectedTab.linkedBrowser.contentDocument == pendingDoc) {
-            if (!this.tourBrowsersByWindow.get(window)) {
-              this.tourBrowsersByWindow.set(window, new Set());
+            if (!this.originTabs.get(window)) {
+              this.originTabs.set(window, new Set());
             }
-            this.tourBrowsersByWindow.get(window).add(selectedTab.linkedBrowser);
+            this.originTabs.get(window).add(selectedTab);
             this.pendingDoc = null;
             this._detachingTab = false;
             while (this._queuedEvents.length) {
               try {
                 this.onPageEvent(this._queuedEvents.shift());
               } catch (ex) {
                 log.error(ex);
               }
             }
             break;
           }
         }
 
+        this.teardownTour(window);
         break;
       }
 
       case "SSWindowClosing": {
         let window = aEvent.target;
-        this.teardownTourForWindow(window);
+        if (this.pageIDSourceWindows.has(window)) {
+          let pageID = this.pageIDSourceWindows.get(window);
+          this.setExpiringTelemetryBucket(pageID, "closed");
+        }
+
+        this.teardownTour(window, true);
         break;
       }
 
       case "input": {
         if (aEvent.target.id == "urlbar") {
           let window = aEvent.target.ownerDocument.defaultView;
           this.handleUrlbarInput(window);
         }
@@ -736,84 +755,48 @@ this.UITour = {
   // This is registered with UITelemetry by BrowserUITelemetry, so that UITour
   // can remain lazy-loaded on-demand.
   getTelemetry: function() {
     return {
       seenPageIDs: [...this.seenPageIDs.keys()],
     };
   },
 
-  /**
-   * Tear down a tour from a tab e.g. upon switching/closing tabs.
-   */
-  teardownTourForBrowser: function(aWindow, aBrowser, aTourPageClosing = false) {
-    log.debug("teardownTourForBrowser: aBrowser = ", aBrowser, aTourPageClosing);
+  teardownTour: function(aWindow, aWindowClosing = false) {
+    log.debug("teardownTour: aWindowClosing = " + aWindowClosing);
+    aWindow.gBrowser.tabContainer.removeEventListener("TabSelect", this);
+    aWindow.removeEventListener("SSWindowClosing", this);
 
-    if (this.pageIDSourceBrowsers.has(aBrowser)) {
-      let pageID = this.pageIDSourceBrowsers.get(aBrowser);
-      this.setExpiringTelemetryBucket(pageID, aTourPageClosing ? "closed" : "inactive");
+    let originTabs = this.originTabs.get(aWindow);
+    if (originTabs) {
+      for (let tab of originTabs) {
+        tab.removeEventListener("TabClose", this);
+        tab.removeEventListener("TabBecomingWindow", this);
+      }
+    }
+    this.originTabs.delete(aWindow);
+
+    if (!aWindowClosing) {
+      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");
     }
 
-    let openTourBrowsers = this.tourBrowsersByWindow.get(aWindow);
-    if (aTourPageClosing) {
-      let tab = aWindow.gBrowser.getTabForBrowser(aBrowser);
-      if (tab) { // Handle standalone <browser>
-        tab.removeEventListener("TabClose", this);
-        tab.removeEventListener("TabBecomingWindow", this);
-        if (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");
-
-    // Clean up panel listeners after calling hideMenu above.
+    // Clean up panel listeners after we may have called hideMenu above.
     aWindow.PanelUI.panel.removeEventListener("popuphiding", this.hideAppMenuAnnotations);
     aWindow.PanelUI.panel.removeEventListener("ViewShowing", this.hideAppMenuAnnotations);
     aWindow.PanelUI.panel.removeEventListener("popuphidden", this.onPanelHidden);
     let loopPanel = aWindow.document.getElementById("loop-notification-panel");
     loopPanel.removeEventListener("popuphidden", this.onPanelHidden);
     loopPanel.removeEventListener("popuphiding", this.hideLoopPanelAnnotations);
 
     this.endUrlbarCapture(aWindow);
     this.resetTheme();
-
-    // If there are no more tour tabs left in the window, teardown the tour for the whole window.
-    if (!openTourBrowsers || openTourBrowsers.size == 0) {
-      this.teardownTourForWindow(aWindow);
-    }
-  },
-
-  /**
-   * Tear down all tours for a ChromeWindow.
-   */
-  teardownTourForWindow: function(aWindow) {
-    log.debug("teardownTourForWindow");
-    aWindow.gBrowser.tabContainer.removeEventListener("TabSelect", this);
-    aWindow.removeEventListener("SSWindowClosing", this);
-
-    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
                            .window
                            .QueryInterface(Ci.nsIInterfaceRequestor)
                            .getInterface(Ci.nsIWebNavigation)
                            .QueryInterface(Ci.nsIDocShellTreeItem)
@@ -1244,17 +1227,16 @@ this.UITour = {
     this._setAppMenuStateForAnnotation(aWindow, "info", false);
 
     let tooltipButtons = document.getElementById("UITourTooltipButtons");
     while (tooltipButtons.firstChild)
       tooltipButtons.firstChild.remove();
   },
 
   showMenu: function(aWindow, aMenuName, aOpenCallback = null) {
-    log.debug("showMenu:", aMenuName);
     function openMenuButton(aMenuBtn) {
       if (!aMenuBtn || !aMenuBtn.boxObject || aMenuBtn.open) {
         if (aOpenCallback)
           aOpenCallback();
         return;
       }
       if (aOpenCallback)
         aMenuBtn.addEventListener("popupshown", onPopupShown);
@@ -1309,17 +1291,16 @@ this.UITour = {
     } else if (aMenuName == "searchEngines") {
       this.getTarget(aWindow, "searchProvider").then(target => {
         openMenuButton(target.node);
       }).catch(log.error);
     }
   },
 
   hideMenu: function(aWindow, aMenuName) {
-    log.debug("hideMenu:", aMenuName);
     function closeMenuButton(aMenuBtn) {
       if (aMenuBtn && aMenuBtn.boxObject)
         aMenuBtn.boxObject.openMenu(false);
     }
 
     if (aMenuName == "appMenu") {
       aWindow.PanelUI.hide();
     } else if (aMenuName == "bookmarks") {
@@ -1639,26 +1620,22 @@ this.UITour = {
 
   notify(eventName, params) {
     let winEnum = Services.wm.getEnumerator("navigator:browser");
     while (winEnum.hasMoreElements()) {
       let window = winEnum.getNext();
       if (window.closed)
         continue;
 
-      let openTourBrowsers = this.tourBrowsersByWindow.get(window);
-      if (!openTourBrowsers)
+      let originTabs = this.originTabs.get(window);
+      if (!originTabs)
         continue;
 
-      for (let browser of openTourBrowsers) {
-        let messageManager = browser.messageManager;
-        if (!messageManager) {
-          log.error("notify: Trying to notify a browser without a messageManager", browser);
-          continue;
-        }
+      for (let tab of originTabs) {
+        let messageManager = tab.linkedBrowser.messageManager;
         let detail = {
           event: eventName,
           params: params,
         };
         messageManager.sendAsyncMessage("UITour:SendPageNotification", detail);
       }
     }
   },
--- a/browser/components/uitour/test/browser_UITour_detach_tab.js
+++ b/browser/components/uitour/test/browser_UITour_detach_tab.js
@@ -63,18 +63,18 @@ let tests = [
     gContentWindow = yield browserStartupDeferred.promise;
 
     // This highlight should be shown thanks to the visibilitychange listener.
     let newWindowHighlight = gContentWindow.document.getElementById("UITourHighlight");
     yield elementVisiblePromise(newWindowHighlight);
 
     let selectedTab = gContentWindow.gBrowser.selectedTab;
     is(selectedTab.linkedBrowser && selectedTab.linkedBrowser.contentDocument, gContentDoc, "Document should be selected in new window");
-    ok(UITour.tourBrowsersByWindow && UITour.tourBrowsersByWindow.has(gContentWindow), "Window should be known");
-    ok(UITour.tourBrowsersByWindow.get(gContentWindow).has(selectedTab.linkedBrowser), "Selected browser should be known");
+    ok(UITour.originTabs && UITour.originTabs.has(gContentWindow), "Window should be known");
+    ok(UITour.originTabs.get(gContentWindow).has(selectedTab), "Tab should be known");
 
     let shownPromise = promisePanelShown(gContentWindow);
     gContentAPI.showMenu("appMenu");
     yield shownPromise;
 
     isnot(gContentWindow.PanelUI.panel.state, "closed", "Panel should be open");
     ok(gContentWindow.PanelUI.contents.children.length > 0, "Panel contents should have children");
     gContentAPI.hideHighlight();
--- a/browser/components/uitour/test/browser_UITour_observe.js
+++ b/browser/components/uitour/test/browser_UITour_observe.js
@@ -43,45 +43,9 @@ let tests = [
       gContentAPI.observe(null);
       done();
     }
 
     gContentAPI.observe(listener, () => {
       UITour.notify("test-event-3", {key: "something"});
     });
   },
-  function test_background_tab(done) {
-    function listener(event, params) {
-      is(event, "test-event-background-1", "Correct event name");
-      is(params, null, "No param object");
-      gContentAPI.observe(null);
-      gBrowser.removeCurrentTab();
-      done();
-    }
-
-    gContentAPI.observe(listener, () => {
-      gBrowser.selectedTab = gBrowser.addTab("about:blank");
-      isnot(gBrowser.selectedTab, gTestTab, "Make sure the selected tab changed");
-
-      UITour.notify("test-event-background-1");
-    });
-  },
-  // Make sure the tab isn't torn down when switching back to the tour one.
-  function test_background_then_foreground_tab(done) {
-    let blankTab = null;
-    function listener(event, params) {
-      is(event, "test-event-4", "Correct event name");
-      is(params, null, "No param object");
-      gContentAPI.observe(null);
-      gBrowser.removeTab(blankTab);
-      done();
-    }
-
-    gContentAPI.observe(listener, () => {
-      blankTab = gBrowser.selectedTab = gBrowser.addTab("about:blank");
-      isnot(gBrowser.selectedTab, gTestTab, "Make sure the selected tab changed");
-      gBrowser.selectedTab = gTestTab;
-      is(gBrowser.selectedTab, gTestTab, "Switch back to the test tab");
-
-      UITour.notify("test-event-4");
-    });
-  },
-];
+];
\ No newline at end of file