Bug 597980 - Switching into and out of Panorama mode quickly can cause the wrong tab to be selected on return [r=ian, a=dolske]
authorMichael Yoshitaka Erlewine <mitcho@mitcho.com>
Mon, 14 Feb 2011 10:27:09 +0800
changeset 62516 e0ff8fb810b9d7768b83bc1eea9643e604985369
parent 62515 f049f500468de782c8ec9d6987d403013cb6b986
child 62517 cc7de25eaf70c57fa58cb0b2a16cc00d72de134f
push id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
reviewersian, dolske
bugs597980
milestone2.0b12pre
Bug 597980 - Switching into and out of Panorama mode quickly can cause the wrong tab to be selected on return [r=ian, a=dolske]
browser/base/content/tabview/groupitems.js
browser/base/content/tabview/tabitems.js
browser/base/content/test/tabview/Makefile.in
browser/base/content/test/tabview/browser_tabview_bug597980.js
--- a/browser/base/content/tabview/groupitems.js
+++ b/browser/base/content/tabview/groupitems.js
@@ -59,17 +59,16 @@
 //     to <add> along with the elements provided.
 //
 // Possible options:
 //   id - specifies the groupItem's id; otherwise automatically generated
 //   userSize - see <Item.userSize>; default is null
 //   bounds - a <Rect>; otherwise based on the locations of the provided elements
 //   container - a DOM element to use as the container for this groupItem; otherwise will create
 //   title - the title for the groupItem; otherwise blank
-//   dontPush - true if this groupItem shouldn't push away on creation; default is false
 //   dontPush - true if this groupItem shouldn't push away or snap on creation; default is false
 //   immediately - true if we want all placement immediately, not with animation
 function GroupItem(listOfEls, options) {
   if (!options)
     options = {};
 
   this._inited = false;
   this._uninited = false;
@@ -685,17 +684,16 @@ GroupItem.prototype = Utils.extend(new I
     UI.setActiveTab(closestTabItem);
 
     // set the active group or orphan tabitem.
     if (closestTabItem) {
       if (closestTabItem.parent) {
         GroupItems.setActiveGroupItem(closestTabItem.parent);
       } else {
         GroupItems.setActiveOrphanTab(closestTabItem);
-        GroupItems.setActiveGroupItem(null);
       }
     } else {
       GroupItems.setActiveGroupItem(null);
       GroupItems.setActiveOrphanTab(null);
     }
   },
 
   // ----------
@@ -1420,17 +1418,16 @@ GroupItem.prototype = Utils.extend(new I
       return {
         shouldZoom: true,
         callback: function() {
           self.collapse();
         }
       };
     }
 
-    GroupItems.setActiveGroupItem(self);
     return { shouldZoom: true };
   },
 
   expand: function GroupItem_expand() {
     var self = this;
     // ___ we're stacked, and command is held down so expand
     GroupItems.setActiveGroupItem(self);
     let activeTab = this.topChild || this.getChildren()[0];
@@ -2272,16 +2269,18 @@ let GroupItems = {
   // ----------
   // Function: setActiveOrphanTab
   // In cases where an orphan tab (not in a groupItem) is active by itself,
   // this function is called and the "active orphan tab" is set.
   //
   // Paramaters:
   //  groupItem - the active <TabItem> or <null>
   setActiveOrphanTab: function GroupItems_setActiveOrphanTab(tabItem) {
+    if (tabItem !== null)
+      this.setActiveGroupItem(null);
     this._activeOrphanTab = tabItem;
   },
 
   // ----------
   // Function: _updateTabBar
   // Hides and shows tabs in the tab bar based on the active groupItem or
   // currently active orphan tabItem
   _updateTabBar: function GroupItems__updateTabBar() {
@@ -2300,21 +2299,21 @@ let GroupItems = {
 
   // ----------
   // Function: updateActiveGroupItemAndTabBar
   // Sets active TabItem and GroupItem, and updates tab bar appropriately.
   updateActiveGroupItemAndTabBar: function GroupItems_updateActiveGroupItemAndTabBar(tabItem) {
     Utils.assertThrow(tabItem && tabItem.isATabItem, "tabItem must be a TabItem");
 
     let groupItem = tabItem.parent;
-    this.setActiveGroupItem(groupItem);
 
-    if (groupItem)
+    if (groupItem) {
+      this.setActiveGroupItem(groupItem);
       groupItem.setActiveTab(tabItem);
-    else
+    } else
       this.setActiveOrphanTab(tabItem);
 
     this._updateTabBar();
   },
 
   // ----------
   // Function: getOrphanedTabs
   // Returns an array of all tabs that aren't in a groupItem.
--- a/browser/base/content/tabview/tabitems.js
+++ b/browser/base/content/tabview/tabitems.js
@@ -612,18 +612,23 @@ TabItem.prototype = Utils.extend(new Ite
   zoomIn: function TabItem_zoomIn(isNewBlankTab) {
     // don't allow zoom in if its group is hidden
     if (this.parent && this.parent.hidden)
       return;
 
     var self = this;
     var $tabEl = this.$container, $canvas = this.$canvas;
     var childHitResult = { shouldZoom: true };
-    if (this.parent)
+    UI.setActiveTab(this);
+    if (this.parent) {
       childHitResult = this.parent.childHit(this);
+      GroupItems.setActiveGroupItem(this.parent);
+    } else {
+      GroupItems.setActiveOrphanTab(this);
+    }
 
     this.shouldHideCachedData = true;
     TabItems._update(this.tab);
 
     if (childHitResult.shouldZoom) {
       // Zoom in!
       var tab = this.tab;
 
--- a/browser/base/content/test/tabview/Makefile.in
+++ b/browser/base/content/test/tabview/Makefile.in
@@ -66,16 +66,17 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug595804.js \
                  browser_tabview_bug595930.js \
                  browser_tabview_bug595943.js \
                  browser_tabview_bug595965.js \
                  browser_tabview_bug596781.js \
                  browser_tabview_bug597248.js \
                  browser_tabview_bug597360.js \
                  browser_tabview_bug597399.js \
+                 browser_tabview_bug597980.js \
                  browser_tabview_bug598600.js \
                  browser_tabview_bug599626.js \
                  browser_tabview_bug600645.js \
                  browser_tabview_bug600812.js \
                  browser_tabview_bug604098.js \
                  browser_tabview_bug606657.js \
                  browser_tabview_bug606905.js \
                  browser_tabview_bug608037.js \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabview/browser_tabview_bug597980.js
@@ -0,0 +1,59 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+  waitForExplicitFinish();
+
+  newWindowWithTabView(onTabViewShown);
+}
+
+function onTabViewShown(win) {
+  let contentWindow = win.document.getElementById("tab-view").contentWindow;
+  is(contentWindow.GroupItems.groupItems.length, 1, "Has only one group");
+
+  let originalTab = win.gBrowser.selectedTab;
+  let originalGroup = contentWindow.GroupItems.groupItems[0];
+  let newTab = win.gBrowser.loadOneTab("about:blank", {inBackground: true});
+  
+  is(originalGroup.getChildren().length, 2, "The original group now has two tabs");
+  
+  // create group two with the new tab
+  let box = new contentWindow.Rect(300,300,150,150);
+  let newGroup = new contentWindow.GroupItem([], {bounds: box, immediately: true});
+  newGroup.add(newTab._tabViewTabItem, {immediately: true});
+
+  // ensure active group item and tab
+  contentWindow.GroupItems.setActiveGroupItem(originalGroup);
+  is(contentWindow.GroupItems.getActiveGroupItem(), originalGroup,
+     "The original group is active");
+  is(contentWindow.UI.getActiveTab(), originalTab._tabViewTabItem,
+     "The original tab is active");
+  
+  function checkActive(callback, time) {
+    is(contentWindow.GroupItems.getActiveGroupItem(), newGroup,
+       "The new group is active");
+    is(contentWindow.UI.getActiveTab(), newTab._tabViewTabItem,
+       "The new tab is active");
+    if (time)
+      setTimeout(callback, time);
+    else
+      callback();
+  }
+
+  // click on the new tab, and check that the new tab and group are active
+  // at two times: 10 ms after (still during the animation) and
+  // 500 ms after (after the animation, hopefully). Either way, the new
+  // tab and group should be active.
+  EventUtils.sendMouseEvent({ type: "mousedown" },
+                            newTab._tabViewTabItem.container, contentWindow);
+  EventUtils.sendMouseEvent({ type: "mouseup" },
+                            newTab._tabViewTabItem.container, contentWindow);
+  setTimeout(function() {
+    checkActive(function() {
+      checkActive(function() {
+        win.close();
+        finish();
+      });
+    }, 490);
+  }, 10)
+}