Bug 622872 - Broken experience with the following STR (leads to frozen UI) r=ian a=blocking
☠☠ backed out by 1f6f73ea3bbc ☠ ☠
authorRaymond Lee <raymond@raysquare.com>
Fri, 21 Jan 2011 10:39:51 +0800
changeset 61089 599e9b6cd5e5cf56d3b1858b2cb2cbbcc85c090e
parent 61088 f9e25d57bb252f1099ed8d3de25520ed0d39e32c
child 61090 a01589063ec0571339b76e9f7eb137d14997fd0c
child 61094 1f6f73ea3bbc86aa3162bed6d04770905e1b3b98
push id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
reviewersian, blocking
bugs622872
milestone2.0b10pre
Bug 622872 - Broken experience with the following STR (leads to frozen UI) r=ian a=blocking
browser/base/content/tabview/tabitems.js
browser/base/content/test/tabview/Makefile.in
browser/base/content/test/tabview/browser_tabview_bug622872.js
--- a/browser/base/content/tabview/tabitems.js
+++ b/browser/base/content/tabview/tabitems.js
@@ -1010,16 +1010,19 @@ let TabItems = {
   // Function: unlink
   // Takes in a xul:tab and destroys the TabItem associated with it. 
   unlink: function TabItems_unlink(tab) {
     try {
       Utils.assertThrow(tab, "tab");
       Utils.assertThrow(tab._tabViewTabItem, "should already be linked");
       // note that it's ok to unlink an app tab; see .handleTabUnpin
 
+      if (tab._tabViewTabItem == GroupItems.getActiveOrphanTab())
+        GroupItems.setActiveOrphanTab(null);
+
       this.unregister(tab._tabViewTabItem);
       tab._tabViewTabItem._sendToSubscribers("close");
       iQ(tab._tabViewTabItem.container).remove();
       tab._tabViewTabItem.removeTrenches();
       Items.unsquish(null, tab._tabViewTabItem);
 
       tab._tabViewTabItem = null;
       Storage.saveTab(tab, null);
--- a/browser/base/content/test/tabview/Makefile.in
+++ b/browser/base/content/test/tabview/Makefile.in
@@ -78,16 +78,17 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug608037.js \
                  browser_tabview_bug608184.js \
                  browser_tabview_bug608158.js \
                  browser_tabview_bug610242.js \
                  browser_tabview_bug616967.js \
                  browser_tabview_bug618828.js \
                  browser_tabview_bug619937.js \
                  browser_tabview_bug622835.js \
+                 browser_tabview_bug622872.js \
                  browser_tabview_bug624265.js \
                  browser_tabview_bug624953.js \
                  browser_tabview_dragdrop.js \
                  browser_tabview_exit_button.js \
                  browser_tabview_expander.js \
                  browser_tabview_group.js \
                  browser_tabview_launch.js \
                  browser_tabview_multiwindow_search.js \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabview/browser_tabview_bug622872.js
@@ -0,0 +1,153 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bug 622872 test.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Michael Yoshitaka Erlewine <mitcho@mitcho.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+function test() {
+  waitForExplicitFinish();
+  newWindowWithTabView(part1);
+}
+
+// PART 1:
+// 1. Create a new tab (called newTab)
+// 2. Orphan it. Activate this orphan tab.
+// 3. Zoom into it.
+function part1(win) {
+  ok(win.TabView.isVisible(), "Tab View is visible");
+
+  let contentWindow = win.document.getElementById("tab-view").contentWindow;
+  is(win.gBrowser.tabs.length, 1, "In the beginning, there was one tab.");
+  let [originalTab] = win.gBrowser.visibleTabs;
+  let originalGroup = contentWindow.GroupItems.getActiveGroupItem();
+  ok(originalGroup.getChildren().some(function(child) {
+    return child == originalTab._tabViewTabItem;
+  }),"The current active group is the one with the original tab in it.");
+  info('originalTab:' + originalTab);
+
+  // Create a new tab and orphan it
+  let newTab = win.gBrowser.loadOneTab("about:mozilla", {inBackground: true});
+  info('newTab:' + newTab);
+  let newTabItem = newTab._tabViewTabItem;
+  ok(originalGroup.getChildren().some(function(child) child == newTabItem),"The new tab was made in the current group");
+  contentWindow.GroupItems.getActiveGroupItem().remove(newTabItem);
+  ok(!originalGroup.getChildren().some(function(child) child == newTabItem),"The new tab was orphaned");
+  newTabItem.pushAway();
+  // activate this tab item
+  contentWindow.UI.setActiveTab(newTabItem);
+  
+  // PART 2: close this orphan tab (newTab)
+  let part2 = function part2() {
+    // At this point we may still be changing tabs... see bug 626003 for info
+    executeSoon(function part2executeSoon() {
+      win.removeEventListener("tabviewhidden", part2, false);
+      is(win.gBrowser.selectedTab, newTab, "We zoomed into that new tab.");
+      ok(!win.TabView.isVisible(), "Tab View is hidden, because we're looking at the new tab");
+  
+      win.addEventListener("tabviewshown", part3, false);
+      win.gBrowser.removeTab(newTab, {animate: false});
+      win.TabView.toggle();
+    });
+  }
+  
+  let secondNewTab;
+  // PART 3: now back in Panorama, open a new tab via the "new tab" menu item (or equivalent)
+  // We call this secondNewTab.
+  let part3 = function part3() {
+    // At this point we may still be closing a tab... see bug 626003 for info
+    executeSoon(function part3executeSoon() {
+      win.removeEventListener("tabviewshown", part3, false);
+      ok(win.TabView.isVisible(), "Tab View is visible");
+      is(win.gBrowser.tabs.length, 1, "Only one tab again.");
+      is(win.gBrowser.tabs[0], originalTab, "That one tab is the original tab.");
+
+      let groupItems = contentWindow.GroupItems.groupItems;
+      is(groupItems.length, 1, "Only one group");
+
+      ok(!contentWindow.GroupItems.getActiveOrphanTab(), "There is no active orphan tab.");
+      
+      win.addEventListener("tabviewhidden", part4, false);
+      win.document.getElementById("cmd_newNavigatorTab").doCommand();
+    });
+  }
+  
+  // PART 4: verify it opened in the original group, and go back into Panorama
+  let part4 = function part4() {
+    // At this point we may still be creating that new tab... you get the idea.
+    executeSoon(function part4executeSoon() {
+      win.removeEventListener("tabviewhidden", part4, false);
+      is(win.gBrowser.tabs.length, 2, "There are two tabs total now.");
+      is(win.gBrowser.visibleTabs.length, 2, "We're looking at both of them.");
+
+      let foundOriginalTab = false;
+      // we can't use forEach because win.gBrowser.tabs is only array-like.
+      for (let i = 0; i < win.gBrowser.tabs.length; i++) {
+        let tab = win.gBrowser.tabs[i];
+        if (tab === originalTab)
+          foundOriginalTab = true;
+        else
+          secondNewTab = tab;
+      }
+      ok(foundOriginalTab, "One of those tabs is the original tab.");
+      ok(secondNewTab, "We found another tab... this is secondNewTab");
+
+      is(win.gBrowser.selectedTab, secondNewTab, "This second new tab is what we're looking at.");
+      
+      win.addEventListener("tabviewshown", part5, false);
+      win.TabView.toggle();
+    });
+  }
+  
+  // PART 5: make sure we only have one group with both tabs now, and finish.
+  let part5 = function part5() {
+    win.removeEventListener("tabviewshown", part5, false);
+
+    is(win.gBrowser.tabs.length, 2, "There are of course still two tabs.");
+
+    let groupItems = contentWindow.GroupItems.groupItems;
+    is(groupItems.length, 1, "There is one group now");
+    is(groupItems[0], originalGroup, "It's the original group.");
+    is(originalGroup.getChildren().length, 2, "It has two children.");
+
+    // finish!
+    win.close();
+    finish();
+  }
+  
+  // Okay, all set up now. Let's get this party started!
+  afterAllTabItemsUpdated(function() {
+    win.addEventListener("tabviewhidden", part2, false);
+    win.TabView.toggle();
+  }, win);
+}