merge backout
authorDão Gottwald <dao@mozilla.com>
Mon, 15 Aug 2011 19:49:22 +0200
changeset 75381 987d310dfcec75acfb9c58dc0223b783ac1d97bb
parent 75379 a721c6686657930a4109e96691e116ccdcc59e05 (current diff)
parent 75380 7a08fd89d10aefbe28fc9a03c643b06650f1b412 (diff)
child 75383 bdbc65fca5ff366c35841120c53128bde7a6a205
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
milestone8.0a1
merge backout
browser/base/content/tabview/content.js
browser/base/content/tabview/groupitems.js
browser/base/content/test/tabview/browser_tabview_bug626455.js
deleted file mode 100644
--- a/browser/base/content/tabview/content.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/* ***** 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 content.js.
- *
- * The Initial Developer of the Original Code is the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Tim Taubert <ttaubert@mozilla.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 ***** */
-
-addEventListener("DOMWillOpenModalDialog", function (event) {
-  // (event.isTrusted == true) when the event is generated by a user action
-  // and does not originate from a script.
-  if (event.isTrusted) {
-    // we're intentionally sending a synchronous message to handle this event
-    // as quick as possible, switch the selected tab and hide the tabview
-    // before the modal dialog is shown
-    sendSyncMessage("Panorama:DOMWillOpenModalDialog");
-  }
-}, true);
--- a/browser/base/content/tabview/groupitems.js
+++ b/browser/base/content/tabview/groupitems.js
@@ -739,55 +739,40 @@ GroupItem.prototype = Utils.extend(new I
       return true;
     }
     return false;
   },
 
   // ----------
   // Function: _unhide
   // Shows the hidden group.
-  //
-  // Parameters:
-  //   options - various options (see below)
-  //
-  // Possible options:
-  //   immediately - true when no animations should be used
-  _unhide: function GroupItem__unhide(options) {
+  _unhide: function GroupItem__unhide() {
+    let self = this;
+
     this._cancelFadeAwayUndoButtonTimer();
     this.hidden = false;
     this.$undoContainer.remove();
     this.$undoContainer = null;
     this.droppable(true);
     this.setTrenches(this.bounds);
 
-    let self = this;
-
-    let finalize = function () {
-      self._children.forEach(function(child) {
-        iQ(child.container).show();
-      });
-
-      UI.setActive(self);
-      self._sendToSubscribers("groupShown", { groupItemId: self.id });
-    };
-
-    let $container = iQ(this.container).show();
+    iQ(this.container).show().animate({
+      "-moz-transform": "scale(1)",
+      "opacity": 1
+    }, {
+      duration: 170,
+      complete: function() {
+        self._children.forEach(function(child) {
+          iQ(child.container).show();
+        });
 
-    if (!options || !options.immediately) {
-      $container.animate({
-        "-moz-transform": "scale(1)",
-        "opacity": 1
-      }, {
-        duration: 170,
-        complete: finalize
-      });
-    } else {
-      $container.css({"-moz-transform": "none", opacity: 1});
-      finalize();
-    }
+        UI.setActive(self);
+        self._sendToSubscribers("groupShown", { groupItemId: self.id });
+      }
+    });
 
     GroupItems.updateGroupCloseButtons();
   },
 
   // ----------
   // Function: closeHidden
   // Removes the group item, its children and its container.
   closeHidden: function GroupItem_closeHidden() {
@@ -795,83 +780,69 @@ GroupItem.prototype = Utils.extend(new I
 
     this._cancelFadeAwayUndoButtonTimer();
 
     // When the last non-empty groupItem is closed and there are no
     // pinned tabs then create a new group with a blank tab.
     let remainingGroups = GroupItems.groupItems.filter(function (groupItem) {
       return (groupItem != self && groupItem.getChildren().length);
     });
-
-    let tab = null;
-
     if (!gBrowser._numPinnedTabs && !remainingGroups.length) {
       let emptyGroups = GroupItems.groupItems.filter(function (groupItem) {
         return (groupItem != self && !groupItem.getChildren().length);
       });
       let group = (emptyGroups.length ? emptyGroups[0] : GroupItems.newGroup());
-      tab = group.newTab(null, {dontZoomIn: true});
+      group.newTab(null, { closedLastTab: true });
     }
 
-    let closed = this.destroy();
-
-    if (!tab)
-      return;
-
-    if (closed) {
-      // Let's make the new tab the selected tab.
-      UI.goToTab(tab);
-    } else {
-      // Remove the new tab and group, if this group is no longer closed.
-      tab._tabViewTabItem.parent.destroy({immediately: true});
-    }
+    this.destroy();
   },
 
   // ----------
   // Function: destroy
   // Close all tabs linked to children (tabItems), removes all children and 
   // close the groupItem.
   //
   // Parameters:
   //   options - An object with optional settings for this call.
   //
   // Options:
   //   immediately - (bool) if true, no animation will be used
-  //
-  // Returns true if the groupItem has been closed, or false otherwise. A group
-  // could not have been closed due to a tab with an onUnload handler (that
-  // waits for user interaction).
   destroy: function GroupItem_destroy(options) {
     let self = this;
 
     // when "TabClose" event is fired, the browser tab is about to close and our 
     // item "close" event is fired.  And then, the browser tab gets closed. 
     // In other words, the group "close" event is fired before all browser
     // tabs in the group are closed.  The below code would fire the group "close"
     // event only after all browser tabs in that group are closed.
-    this._children.concat().forEach(function(child) {
+    let shouldRemoveTabItems = [];
+    let toClose = this._children.concat();
+    toClose.forEach(function(child) {
       child.removeSubscriber("close", self._onChildClose);
 
-      if (child.close(true)) {
-        self.remove(child, { dontArrange: true });
+      let removed = child.close(true);
+      if (removed) {
+        shouldRemoveTabItems.push(child);
       } else {
         // child.removeSubscriber() must be called before child.close(), 
         // therefore we call child.addSubscriber() if the tab is not removed.
         child.addSubscriber("close", self._onChildClose);
       }
     });
 
-    if (this._children.length) {
-      if (this.hidden)
-        this.$undoContainer.fadeOut(function() { self._unhide() });
+    if (shouldRemoveTabItems.length != toClose.length) {
+      // remove children without the assiciated tab and show the group item
+      shouldRemoveTabItems.forEach(function(child) {
+        self.remove(child, { dontArrange: true });
+      });
 
-      return false;
+      this.$undoContainer.fadeOut(function() { self._unhide() });
     } else {
       this.close(options);
-      return true;
     }
   },
 
   // ----------
   // Function: _fadeAwayUndoButton
   // Fades away the undo button
   _fadeAwayUndoButton: function GroupItem__fadeAwayUdoButton() {
     let self = this;
@@ -1842,26 +1813,23 @@ GroupItem.prototype = Utils.extend(new I
   },
 
   // ----------
   // Function: newTab
   // Creates a new tab within this groupItem.
   // Parameters:
   //  url - the new tab should open this url as well
   //  options - the options object
-  //    dontZoomIn - set to true to not zoom into the newly created tab
   //    closedLastTab - boolean indicates the last tab has just been closed
   newTab: function GroupItem_newTab(url, options) {
     if (options && options.closedLastTab)
       UI.closedLastTabInTabView = true;
 
     UI.setActive(this, { dontSetActiveTabInGroup: true });
-
-    let dontZoomIn = !!(options && options.dontZoomIn);
-    return gBrowser.loadOneTab(url || "about:blank", { inBackground: dontZoomIn });
+    gBrowser.loadOneTab(url || "about:blank", { inBackground: false });
   },
 
   // ----------
   // Function: reorderTabItemsBasedOnTabOrder
   // Reorders the tabs in a groupItem based on the arrangment of the tabs
   // shown in the tab bar. It does it by sorting the children
   // of the groupItem by the positions of their respective tabs in the
   // tab bar.
--- a/browser/base/content/tabview/tabitems.js
+++ b/browser/base/content/tabview/tabitems.js
@@ -473,32 +473,39 @@ TabItem.prototype = Utils.extend(new Ite
   // Parameters:
   //   groupClose - true if this method is called by group close action.
   // Returns true if this tab is removed.
   close: function TabItem_close(groupClose) {
     // When the last tab is closed, put a new tab into closing tab's group. If
     // closing tab doesn't belong to a group and no empty group, create a new 
     // one for the new tab.
     if (!groupClose && gBrowser.tabs.length == 1) {
-      let group = this.tab._tabViewTabItem.parent;
+      let group;
+      if (this.tab._tabViewTabItem.parent) {
+        group = this.tab._tabViewTabItem.parent;
+      } else {
+        let emptyGroups = GroupItems.groupItems.filter(function (groupItem) {
+          return (!groupItem.getChildren().length);
+        });
+        group = (emptyGroups.length ? emptyGroups[0] : GroupItems.newGroup());
+      }
       group.newTab(null, { closedLastTab: true });
     }
-
     // when "TabClose" event is fired, the browser tab is about to close and our 
     // item "close" is fired before the browser tab actually get closed. 
     // Therefore, we need "tabRemoved" event below.
     gBrowser.removeTab(this.tab);
-    let tabClosed = !this.tab;
-
-    if (tabClosed)
+    let tabNotClosed = 
+      Array.some(gBrowser.tabs, function(tab) { return tab == this.tab; }, this);
+    if (!tabNotClosed)
       this._sendToSubscribers("tabRemoved");
 
     // No need to explicitly delete the tab data, becasue sessionstore data
     // associated with the tab will automatically go away
-    return tabClosed;
+    return !tabNotClosed;
   },
 
   // ----------
   // Function: addClass
   // Adds the specified CSS class to this item's container DOM element.
   addClass: function TabItem_addClass(className) {
     this.$container.addClass(className);
   },
--- a/browser/base/content/tabview/ui.js
+++ b/browser/base/content/tabview/ui.js
@@ -21,17 +21,16 @@
  * Contributor(s):
  * Ian Gilman <ian@iangilman.com>
  * Aza Raskin <aza@mozilla.com>
  * Michael Yoshitaka Erlewine <mitcho@mitcho.com>
  * Ehsan Akhgari <ehsan@mozilla.com>
  * Raymond Lee <raymond@appcoast.com>
  * Sean Dunn <seanedunn@yahoo.com>
  * Tim Taubert <tim.taubert@gmx.de>
- * Mihai Sucan <mihai.sucan@gmail.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
@@ -76,20 +75,16 @@ let UI = {
   // Variable: _closedSelectedTabInTabView
   // If true, a select tab has just been closed in TabView.
   _closedSelectedTabInTabView: false,
 
   // Variable: restoredClosedTab
   // If true, a closed tab has just been restored.
   restoredClosedTab: false,
 
-  // Variable: _isChangingVisibility
-  // Tracks whether we're currently in the process of showing/hiding the tabview.
-  _isChangingVisibility: false,
-
   // Variable: _reorderTabItemsOnShow
   // Keeps track of the <GroupItem>s which their tab items' tabs have been moved
   // and re-orders the tab items when switching to TabView.
   _reorderTabItemsOnShow: [],
 
   // Variable: _reorderTabsOnHide
   // Keeps track of the <GroupItem>s which their tab items have been moved in
   // TabView UI and re-orders the tabs when switcing back to main browser.
@@ -230,25 +225,16 @@ let UI = {
           }
         }
       });
 
       iQ(window).bind("unload", function() {
         self.uninit();
       });
 
-      // ___ setup DOMWillOpenModalDialog message handler
-      let mm = gWindow.messageManager;
-      let callback = this._onDOMWillOpenModalDialog.bind(this);
-      mm.addMessageListener("Panorama:DOMWillOpenModalDialog", callback);
-
-      this._cleanupFunctions.push(function () {
-        mm.removeMessageListener("Panorama:DOMWillOpenModalDialog", callback);
-      });
-
       // ___ setup key handlers
       this._setTabViewFrameKeyHandlers();
 
       // ___ add tab action handlers
       this._addTabActionHandlers();
 
       // ___ groups
       GroupItems.init();
@@ -281,20 +267,16 @@ let UI = {
         if (self.isTabViewVisible())
           GroupItems.removeHiddenGroups();
 
         Storage.saveActiveGroupName(gWindow);
         TabItems.saveAll(true);
         self._save();
       }, false);
 
-      // ___ load frame script
-      let frameScript = "chrome://browser/content/tabview-content.js";
-      gWindow.messageManager.loadFrameScript(frameScript, true);
-
       // ___ Done
       this._frameInitialized = true;
       this._save();
 
       // fire an iframe initialized event so everyone knows tab view is 
       // initialized.
       let event = document.createEvent("Events");
       event.initEvent("tabviewframeinitialized", true, false);
@@ -490,21 +472,19 @@ let UI = {
   },
 
   // ----------
   // Function: showTabView
   // Shows TabView and hides the main browser UI.
   // Parameters:
   //   zoomOut - true for zoom out animation, false for nothing.
   showTabView: function UI_showTabView(zoomOut) {
-    if (this.isTabViewVisible() || this._isChangingVisibility)
+    if (this.isTabViewVisible())
       return;
 
-    this._isChangingVisibility = true;
-
     // initialize the direction of the page
     this._initPageDirection();
 
     var self = this;
     var currentTab = this._currentTab;
 
     this._reorderTabItemsOnShow.forEach(function(groupItem) {
       groupItem.reorderTabItemsBasedOnTabOrder();
@@ -537,48 +517,44 @@ let UI = {
       // Zoom out!
       item.zoomOut(function() {
         if (!currentTab._tabViewTabItem) // if the tab's been destroyed
           item = null;
 
         self.setActive(item);
 
         self._resize(true);
-        self._isChangingVisibility = false;
         dispatchEvent(event);
 
         // Flush pending updates
         GroupItems.flushAppTabUpdates();
 
         TabItems.resumePainting();
       });
     } else {
       self.clearActiveTab();
-      self._isChangingVisibility = false;
       dispatchEvent(event);
 
       // Flush pending updates
       GroupItems.flushAppTabUpdates();
 
       TabItems.resumePainting();
     }
 
     if (gTabView.firstUseExperienced)
       gTabView.enableSessionRestore();
   },
 
   // ----------
   // Function: hideTabView
   // Hides TabView and shows the main browser UI.
   hideTabView: function UI_hideTabView() {
-    if (!this.isTabViewVisible() || this._isChangingVisibility)
+    if (!this.isTabViewVisible())
       return;
 
-    this._isChangingVisibility = true;
-
     // another tab might be select if user decides to stay on a page when
     // a onclose confirmation prompts.
     GroupItems.removeHiddenGroups();
     TabItems.pausePainting();
 
     this._reorderTabsOnHide.forEach(function(groupItem) {
       groupItem.reorderTabsBasedOnTabItemOrder();
     });
@@ -595,18 +571,16 @@ let UI = {
     gBrowser.contentWindow.focus();
 
     gBrowser.updateTitlebar();
 #ifdef XP_MACOSX
     this.setTitlebarColors(false);
 #endif
     Storage.saveVisibilityData(gWindow, "false");
 
-    this._isChangingVisibility = false;
-
     let event = document.createEvent("Events");
     event.initEvent("tabviewhidden", true, false);
     dispatchEvent(event);
   },
 
 #ifdef XP_MACOSX
   // ----------
   // Function: setTitlebarColors
@@ -770,24 +744,31 @@ let UI = {
           var groupItem = GroupItems.getActiveGroupItem();
 
           // 1) Only go back to the TabView tab when there you close the last
           // tab of a groupItem.
           let closingLastOfGroup = (groupItem && 
               groupItem._children.length == 1 && 
               groupItem._children[0].tab == tab);
 
-          // 2) When a blank tab is active while restoring a closed tab the
+          // 2) Take care of the case where you've closed the last tab in
+          // an un-named groupItem, which means that the groupItem is gone (null) and
+          // there are no visible tabs. 
+          let closingUnnamedGroup = (groupItem == null &&
+              gBrowser.visibleTabs.length <= 1); 
+
+          // 3) When a blank tab is active while restoring a closed tab the
           // blank tab gets removed. The active group is not closed as this is
           // where the restored tab goes. So do not show the TabView.
           let tabItem = tab && tab._tabViewTabItem;
           let closingBlankTabAfterRestore =
             (tabItem && tabItem.isRemovedAfterRestore);
 
-          if (closingLastOfGroup && !closingBlankTabAfterRestore) {
+          if ((closingLastOfGroup || closingUnnamedGroup) &&
+              !closingBlankTabAfterRestore) {
             // for the tab focus event to pick up.
             self._closedLastVisibleTab = true;
             self.showTabView();
           }
         }
       }
     };
 
@@ -897,24 +878,18 @@ let UI = {
     this._closedLastVisibleTab = false;
     this._closedSelectedTabInTabView = false;
     this.closedLastTabInTabView = false;
     this.restoredClosedTab = false;
     this._lastOpenedTab = null;
 
     // if TabView is visible but we didn't just close the last tab or
     // selected tab, show chrome.
-    if (this.isTabViewVisible()) {
-      // Unhide the group of the tab the user is activating.
-      if (tab && tab._tabViewTabItem && tab._tabViewTabItem.parent &&
-          tab._tabViewTabItem.parent.hidden)
-        tab._tabViewTabItem.parent._unhide({immediately: true});
-
+    if (this.isTabViewVisible())
       this.hideTabView();
-    }
 
     // another tab might be selected when hideTabView() is invoked so a
     // validation is needed.
     if (this._currentTab != tab)
       return;
 
     let newItem = null;
     // update the tab bar for the new tab's group
@@ -939,37 +914,16 @@ let UI = {
       }
 
       if (GroupItems.getActiveGroupItem())
         GroupItems._updateTabBar();
     }
   },
 
   // ----------
-  // Function: _onDOMWillOpenModalDialog
-  // Called when a web page is about to show a modal dialog.
-  _onDOMWillOpenModalDialog: function UI__onDOMWillOpenModalDialog(cx) {
-    if (!this.isTabViewVisible())
-      return;
-
-    let index = gBrowser.browsers.indexOf(cx.target);
-    if (index == -1)
-      return;
-
-    let tab = gBrowser.tabs[index];
-
-    // When TabView is visible, we need to call onTabSelect to make sure that
-    // TabView is hidden and that the correct group is activated. When a modal
-    // dialog is shown for currently selected tab the onTabSelect event handler
-    // is not called, so we need to do it.
-    if (gBrowser.selectedTab == tab && this._currentTab == tab)
-      this.onTabSelect(tab);
-  },
-
-  // ----------
   // Function: setReorderTabsOnHide
   // Sets the groupItem which the tab items' tabs should be re-ordered when
   // switching to the main browser UI.
   // Parameters:
   //   groupItem - the groupItem which would be used for re-ordering tabs.
   setReorderTabsOnHide: function UI_setReorderTabsOnHide(groupItem) {
     if (this.isTabViewVisible()) {
       var index = this._reorderTabsOnHide.indexOf(groupItem);
--- a/browser/base/content/test/tabview/Makefile.in
+++ b/browser/base/content/test/tabview/Makefile.in
@@ -106,17 +106,16 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug624727.js \
                  browser_tabview_bug624847.js \
                  browser_tabview_bug624931.js \
                  browser_tabview_bug624953.js \
                  browser_tabview_bug625195.js \
                  browser_tabview_bug625269.js \
                  browser_tabview_bug625424.js \
                  browser_tabview_bug626368.js \
-                 browser_tabview_bug626455.js \
                  browser_tabview_bug626525.js \
                  browser_tabview_bug626791.js \
                  browser_tabview_bug627239.js \
                  browser_tabview_bug627288.js \
                  browser_tabview_bug627736.js \
                  browser_tabview_bug628061.js \
                  browser_tabview_bug628165.js \
                  browser_tabview_bug628270.js \
--- a/browser/base/content/test/tabview/browser_tabview_bug597980.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug597980.js
@@ -5,17 +5,17 @@ function test() {
   waitForExplicitFinish();
 
   newWindowWithTabView(part1);
 }
 
 function part1(win) {
   registerCleanupFunction(function() win.close());
 
-  let contentWindow = win.TabView.getContentWindow();
+  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");
   
@@ -66,17 +66,20 @@ function part2(win) {
   let newTab = win.gBrowser.loadOneTab("about:blank", {inBackground: true});
   hideTabView(function() {
     let selectedTab = win.gBrowser.selectedTab;
     isnot(selectedTab, newTab, "They are different tabs");
 
     // switch the selected tab to new tab
     win.gBrowser.selectedTab = newTab;
 
-    showTabView(function () {
-      hideTabView(function () {
-        is(win.gBrowser.selectedTab, newTab,
-           "The selected tab should be the same as before (new tab)");
-        waitForFocus(finish);
-      }, win);
-    }, win);
-  }, win);
+    whenTabViewIsHidden(function () {
+      is(win.gBrowser.selectedTab, newTab, "The seleted tab should be the same as before (new tab)");
+       win.close();
+       finish();
+    });
+
+    // show tabview
+    EventUtils.synthesizeKey("e", { accelKey: true, shiftKey: true }, win);
+    // hide tabview
+    EventUtils.synthesizeKey("e", { accelKey: true, shiftKey: true }, win);
+  })
 }
--- a/browser/base/content/test/tabview/browser_tabview_bug599626.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug599626.js
@@ -16,17 +16,19 @@ function onTabViewShown() {
 
   afterAllTabsLoaded(function () {
     testStayOnPage(contentWindow, groupItemOne, groupItemTwo);
   });
 }
 
 function testStayOnPage(contentWindow, groupItemOne, groupItemTwo) {
   whenDialogOpened(function (dialog) {
-    executeSoon(function () {
+    groupItemTwo.addSubscriber("groupShown", function onShown() {
+      groupItemTwo.removeSubscriber("groupShown", onShown);
+
       is(gBrowser.tabs.length, 2, 
          "The total number of tab is 2 when staying on the page");
       is(contentWindow.TabItems.getItems().length, 2, 
          "The total number of tab items is 2 when staying on the page");
 
       showTabView(function () {
         // start the next test
         testLeavePage(contentWindow, groupItemOne, groupItemTwo);
--- a/browser/base/content/test/tabview/browser_tabview_bug604098.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug604098.js
@@ -20,17 +20,16 @@ function test() {
   });
 }
 
 function test1() {
   let groupItems = contentWindow.GroupItems.groupItems;
   is(groupItems.length, 1, "there is one groupItem");
 
   whenTabViewIsHidden(function() {
-    gBrowser.selectedTab = gBrowser.tabs[0];
     is(groupItems.length, 2, "there are two groupItems");
     closeGroupItem(groupItems[1], finish);
   });
 
   // first click
   mouseClick(contentElement, 0);
   // second click
   mouseClick(contentElement, 0);
--- a/browser/base/content/test/tabview/browser_tabview_bug624953.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug624953.js
@@ -13,11 +13,11 @@ function test() {
 
     groupItem.setSize(100, 100, true);
     groupItem.setUserSize();
     ok(!groupItem.isStacked(), 'groupItem is still not stacked');
 
     cw.GroupItems.resumeArrange();
     ok(groupItem.isStacked(), 'groupItem is now stacked');
 
-    closeGroupItem(groupItem, function () hideTabView(finish));
+    closeGroupItem(groupItem, finish);
   });
 }
--- a/browser/base/content/test/tabview/browser_tabview_bug625195.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug625195.js
@@ -29,17 +29,17 @@ function test() {
 
     whenTabViewIsHidden(function() {
       popup(gBrowser.tabs[0]);
 
       ok(!document.getElementById("context_closeTab").disabled, "The 'Close tab' menu item is enabled");
       ok(!document.getElementById("context_openTabInWindow").disabled, "The 'Move to New Window' menu item is enabled");
 
       let newTabTwo = gBrowser.selectedTab;
-      gBrowser.selectedTab = originalTab;
+      gBrowser.selected = originalTab;
 
       gBrowser.removeTab(newTabOne);
       gBrowser.removeTab(newTabTwo);
 
       finish();
     });
     let newGroup = contentWindow.GroupItems.newGroup();
     newGroup.newTab();
deleted file mode 100644
--- a/browser/base/content/test/tabview/browser_tabview_bug626455.js
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- *
- * Contributor(s):
- *   Mihai Sucan <mihai.sucan@gmail.com>
- *   Raymond Lee <raymond@appcoast.com>
- */
-
-const TEST_URL = 'data:text/html,<script>window.onbeforeunload=' +
-                 'function(e){e.returnValue="?"}</script><body ' +
-                 'onunload="alert(\'onunload\')" onpagehide="' +
-                 'alert(\'onpagehide\')"></body>';
-
-let contentWindow;
-let activeGroup;
-
-function test() {
-  waitForExplicitFinish();
-
-  showTabView(function () {
-    contentWindow = TabView.getContentWindow();
-    activeGroup = contentWindow.GroupItems.getActiveGroupItem();
-
-    gBrowser.browsers[0].contentWindow.location =
-      "data:text/html,<p>test for bug 626455, tab1";
-    gBrowser.addTab(TEST_URL);
-
-    afterAllTabsLoaded(testStayOnPage);
-  });
-}
-
-function testStayOnPage() {
-  whenDialogOpened(function (dialog) {
-    // stay on page
-    dialog.cancelDialog();
-
-    executeSoon(function () {
-      showTabView(function () {
-        is(gBrowser.tabs.length, 1,
-           "The total number of tab is 1 when staying on the page");
-
-        let location = gBrowser.browsers[0].contentWindow.location.toString();
-        isnot(location.indexOf("onbeforeunload"), -1,
-              "The open tab is the expected one");
-
-        is(contentWindow.GroupItems.getActiveGroupItem(), activeGroup,
-           "Active group is still the same");
-
-        is(contentWindow.GroupItems.groupItems.length, 1,
-           "Only one group is open");
-
-        // start the next test
-        testLeavePage();
-      });
-    });
-  });
-
-  closeGroupItem(activeGroup);
-}
-
-function testLeavePage() {
-  let dialogsAccepted = 0;
-
-  whenDialogOpened(function onDialogOpened(dialog) {
-    if (++dialogsAccepted < 3)
-      whenDialogOpened(onDialogOpened);
-
-    // Leave page
-    dialog.acceptDialog();
-  });
-
-  whenGroupClosed(activeGroup, finishTest);
-  closeGroupItem(activeGroup);
-}
-
-function finishTest() {
-  is(gBrowser.tabs.length, 1,
-     "The total number of tab is 1 after leaving the page");
-  is(contentWindow.TabItems.getItems().length, 1,
-     "The total number of tab items is 1 after leaving the page");
-
-  let location = gBrowser.browsers[0].contentWindow.location.toString();
-  is(location, "about:blank", "The open tab is the expected one");
-
-  isnot(contentWindow.GroupItems.getActiveGroupItem(), activeGroup,
-     "Active group is no longer the same");
-
-  is(contentWindow.GroupItems.groupItems.length, 1,
-     "Only one group is open");
-
-  finish();
-}
-
-// ----------
-function whenGroupClosed(group, callback) {
-  group.addSubscriber("close", function onClose() {
-    group.removeSubscriber("close", onClose);
-    callback();
-  });
-}
-
-// ----------
-function whenDialogOpened(callback) {
-  let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
-           .getService(Ci.nsIWindowMediator);
-
-  let listener = {
-    onCloseWindow: function () {},
-    onWindowTitleChange: function () {},
-
-    onOpenWindow: function (xulWin) {
-      let domWin = xulWin.QueryInterface(Ci.nsIInterfaceRequestor)
-                   .getInterface(Ci.nsIDOMWindow);
-
-      whenWindowLoaded(domWin, function () {
-        let dialog = domWin.document.querySelector("dialog");
-        if (dialog) {
-          wm.removeListener(listener);
-          callback(dialog);
-        }
-      });
-    }
-  };
-
-  wm.addListener(listener);
-}
--- a/browser/base/content/test/tabview/browser_tabview_bug663421.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug663421.js
@@ -62,17 +62,17 @@ function test() {
     let target = tab._tabViewTabItem.container;
 
     waitForFocus(function () {
       EventUtils.synthesizeMouseAtCenter(target, {type: "mousedown"}, cw);
       EventUtils.synthesizeMouse(target, 600, 5, {type: "mousemove"}, cw);
       EventUtils.synthesizeMouse(target, 600, 5, {type: "mouseup"}, cw);
 
       checkNumberOfGroupItems(2);
-      closeGroupItem(cw.GroupItems.groupItems[1], next);
+      next();
     }, win);
   }
 
   let tests = [test1, test2, test3, test4];
 
   waitForExplicitFinish();
 
   newWindowWithTabView(function (aWin) {
--- a/browser/base/content/test/tabview/browser_tabview_dragdrop.js
+++ b/browser/base/content/test/tabview/browser_tabview_dragdrop.js
@@ -1,39 +1,56 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 function test() {
   waitForExplicitFinish();
-  showTabView(onTabViewShown);
+
+  window.addEventListener("tabviewshown", onTabViewWindowLoaded, false);
+  TabView.toggle();
 }
 
-function onTabViewShown() {
+function onTabViewWindowLoaded() {
+  window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
+
   ok(TabView.isVisible(), "Tab View is visible");
 
-  let contentWindow = TabView.getContentWindow();
+  let contentWindow = document.getElementById("tab-view").contentWindow;
   let [originalTab] = gBrowser.visibleTabs;
 
-  let createGroupItem = function (left, top, width, height) {
-    let box = new contentWindow.Rect(left, top, width, height);
-    let groupItem = new contentWindow.GroupItem([], {bounds: box, immediately: true});
+  // create group one and two
+  let boxOne = new contentWindow.Rect(20, 20, 300, 300);
+  let groupOne = new contentWindow.GroupItem([], { bounds: boxOne });
+  ok(groupOne.isEmpty(), "This group is empty");
+
+  let boxTwo = new contentWindow.Rect(20, 400, 300, 300);
+  let groupTwo = new contentWindow.GroupItem([], { bounds: boxTwo });
 
-    contentWindow.UI.setActive(groupItem);
-    gBrowser.loadOneTab("about:blank", {inBackground: true});
+  groupOne.addSubscriber("childAdded", function onChildAdded() {
+    groupOne.removeSubscriber("childAdded", onChildAdded);
+    groupTwo.newTab();
+  });
 
-    return groupItem;
+  let count = 0;
+  let onTabViewShown = function() {
+    if (count == 2) {
+      window.removeEventListener("tabviewshown", onTabViewShown, false);
+      addTest(contentWindow, groupOne.id, groupTwo.id, originalTab);
+    }
   };
+  let onTabViewHidden = function() {
+    TabView.toggle();
+    if (++count == 2)
+      window.removeEventListener("tabviewhidden", onTabViewHidden, false);
+  };
+  window.addEventListener("tabviewshown", onTabViewShown, false);
+  window.addEventListener("tabviewhidden", onTabViewHidden, false);
 
-  // create group one and two
-  let groupOne = createGroupItem(20, 20, 300, 300);
-  let groupTwo = createGroupItem(20, 400, 300, 300);
-
-  waitForFocus(function () {
-    addTest(contentWindow, groupOne.id, groupTwo.id, originalTab);
-  });
+  // open tab in group
+  groupOne.newTab();
 }
 
 function addTest(contentWindow, groupOneId, groupTwoId, originalTab) {
   let groupOne = contentWindow.GroupItems.groupItem(groupOneId);
   let groupTwo = contentWindow.GroupItems.groupItem(groupTwoId);
   let groupOneTabItemCount = groupOne.getChildren().length;
   let groupTwoTabItemCount = groupTwo.getChildren().length;
   is(groupOneTabItemCount, 1, "GroupItem one has one tab");
@@ -52,23 +69,34 @@ function addTest(contentWindow, groupOne
 
   function endGame() {
     groupTwo.removeSubscriber("childAdded", endGame);
 
     is(groupOne.getChildren().length, --groupOneTabItemCount,
        "The number of children in group one is decreased by 1");
     is(groupTwo.getChildren().length, ++groupTwoTabItemCount,
        "The number of children in group two is increased by 1");
-
-    closeGroupItem(groupOne, function () {
-      closeGroupItem(groupTwo, function () hideTabView(finish));
+  
+    let onTabViewHidden = function() {
+      window.removeEventListener("tabviewhidden", onTabViewHidden, false);
+      groupTwo.closeAll();
+      // close undo group
+      let closeButton = groupTwo.$undoContainer.find(".close");
+      EventUtils.sendMouseEvent(
+        { type: "click" }, closeButton[0], contentWindow);
+    };
+    groupTwo.addSubscriber("close", function onClose() {
+      groupTwo.removeSubscriber("close", onClose);
+      finish(); 
     });
+    window.addEventListener("tabviewhidden", onTabViewHidden, false);
+    gBrowser.selectedTab = originalTab;
   }
-
   groupTwo.addSubscriber("childAdded", endGame);
+  
   simulateDragDrop(tabItem.container, offsetX, offsetY, contentWindow);
 }
 
 function simulateDragDrop(element, offsetX, offsetY, contentWindow) {
   let rect = element.getBoundingClientRect();
   let startX = (rect.right - rect.left)/2;
   let startY = (rect.bottom - rect.top)/2;
   let incrementX = offsetX / 2;
--- a/browser/base/content/test/tabview/browser_tabview_launch.js
+++ b/browser/base/content/test/tabview/browser_tabview_launch.js
@@ -1,54 +1,52 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+let timerId;
 let newWin;
 
 // ----------
 function test() {
   waitForExplicitFinish();
 
-  let panelSelected = false;
-  registerCleanupFunction(function () ok(panelSelected, "panel is selected"));
-
-  let onLoad = function (win) {
-    registerCleanupFunction(function () win.close());
-
+  // launch tab view for the first time
+  newWindowWithTabView(function() {}, function(win) {
     newWin = win;
 
     let onSelect = function(event) {
       if (deck != event.target)
         return;
 
       let iframe = win.document.getElementById("tab-view");
       if (deck.selectedPanel != iframe)
         return;
 
       deck.removeEventListener("select", onSelect, true);
-      panelSelected = true;
+
+      whenTabViewIsShown(function() {
+        executeSoon(function() {
+          testMethodToHideAndShowTabView(function() {
+            newWin.document.getElementById("menu_tabview").doCommand();
+          }, function() {
+            testMethodToHideAndShowTabView(function() {
+              EventUtils.synthesizeKey("e", { accelKey: true, shiftKey: true }, newWin);
+            }, finish);
+          });
+        });
+      }, win);
     };
 
     let deck = win.document.getElementById("tab-view-deck");
     deck.addEventListener("select", onSelect, true);
-  };
+  });
 
-  let onShow = function (win) {
-    executeSoon(function() {
-      testMethodToHideAndShowTabView(function() {
-        newWin.document.getElementById("menu_tabview").doCommand();
-      }, function() {
-        testMethodToHideAndShowTabView(function() {
-          EventUtils.synthesizeKey("E", { accelKey: true, shiftKey: true }, newWin);
-        }, finish);
-      });
-    });
-  };
-
-  newWindowWithTabView(onShow, onLoad);
+  registerCleanupFunction(function () {
+    newWin.close();
+  });
 }
 
 function testMethodToHideAndShowTabView(executeFunc, callback) {
   whenTabViewIsHidden(function() {
     ok(!newWin.TabView.isVisible(), "Tab View is not visible after executing the function");
     whenTabViewIsShown(function() {
       ok(newWin.TabView.isVisible(), "Tab View is visible after executing the function again");
       callback();
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -48,17 +48,16 @@ browser.jar:
 *       content/browser/sanitize.xul                  (content/sanitize.xul)
 *       content/browser/sanitizeDialog.js             (content/sanitizeDialog.js)
         content/browser/sanitizeDialog.css            (content/sanitizeDialog.css)
 *       content/browser/tabbrowser.css                (content/tabbrowser.css)
 *       content/browser/tabbrowser.xml                (content/tabbrowser.xml)
         content/browser/tabview.css                   (content/tabview/tabview.css)
 *       content/browser/tabview.js                    (content/tabview/tabview.js)
         content/browser/tabview.html                  (content/tabview/tabview.html)
-        content/browser/tabview-content.js            (content/tabview/content.js)
 *       content/browser/urlbarBindings.xml            (content/urlbarBindings.xml)
 *       content/browser/utilityOverlay.js             (content/utilityOverlay.js)
 *       content/browser/web-panels.js                 (content/web-panels.js)
 *       content/browser/web-panels.xul                (content/web-panels.xul)
 *       content/browser/baseMenuOverlay.xul           (content/baseMenuOverlay.xul)
 *       content/browser/nsContextMenu.js              (content/nsContextMenu.js)
 #ifdef MOZ_SERVICES_SYNC
 *       content/browser/aboutSyncTabs.xul             (content/aboutSyncTabs.xul)