Bug 626791 - Add the Panorama button to the toolbar automatically after the user has used Panorama for the first time. r=dao a=beltzner
authorTim Taubert <tim.taubert@gmx.de>
Wed, 16 Feb 2011 17:06:54 +0100
changeset 62729 4b9e814fe3ab
parent 62728 311b7d07893d
child 62730 2042b8f9756d
push id18845
push userdgottwald@mozilla.com
push dateThu, 17 Feb 2011 08:43:42 +0000
treeherdermozilla-central@4b9e814fe3ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdao, beltzner
bugs626791
milestone2.0b12pre
first release with
nightly linux32
4b9e814fe3ab / 4.0b12pre / 20110217030357 / files
nightly linux64
4b9e814fe3ab / 4.0b12pre / 20110217030357 / files
nightly mac
4b9e814fe3ab / 4.0b12pre / 20110217030357 / files
nightly win32
4b9e814fe3ab / 4.0b12pre / 20110217030357 / files
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 626791 - Add the Panorama button to the toolbar automatically after the user has used Panorama for the first time. r=dao a=beltzner
browser/base/content/browser-tabview.js
browser/base/content/browser.js
browser/base/content/tabview/groupitems.js
browser/base/content/tabview/items.js
browser/base/content/tabview/tabview.js
browser/base/content/tabview/ui.js
browser/base/content/test/tabview/Makefile.in
browser/base/content/test/tabview/browser_tabview_bug589324.js
browser/base/content/test/tabview/browser_tabview_bug626525.js
browser/base/content/test/tabview/browser_tabview_bug626791.js
--- a/browser/base/content/browser-tabview.js
+++ b/browser/base/content/browser-tabview.js
@@ -34,42 +34,48 @@
 # 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 *****
 
 let TabView = {
   _deck: null,
   _window: null,
-  _firstRunExperienced: false,
+  _firstUseExperienced: false,
   _browserKeyHandlerInitialized: false,
   VISIBILITY_IDENTIFIER: "tabview-visibility",
 
   // ----------
   get windowTitle() {
     delete this.windowTitle;
     let brandBundle = document.getElementById("bundle_brand");
     let brandShortName = brandBundle.getString("brandShortName");
     let title = gNavigatorBundle.getFormattedString("tabView2.title", [brandShortName]);
     return this.windowTitle = title;
   },
-  
+
   // ----------
-  get firstRunExperienced() {
-    return this._firstRunExperienced;
+  get firstUseExperienced() {
+    return this._firstUseExperienced;
+  },
+
+  // ----------
+  set firstUseExperienced(val) {
+    if (val != this._firstUseExperienced)
+      Services.prefs.setBoolPref("browser.panorama.experienced_first_use", val);
   },
 
   // ----------
   init: function TabView_init() {
-    if (!Services.prefs.prefHasUserValue("browser.panorama.experienced_first_run") ||
-        !Services.prefs.getBoolPref("browser.panorama.experienced_first_run")) {
+    if (!Services.prefs.prefHasUserValue("browser.panorama.experienced_first_use") ||
+        !Services.prefs.getBoolPref("browser.panorama.experienced_first_use")) {
       Services.prefs.addObserver(
-        "browser.panorama.experienced_first_run", this, false);
+        "browser.panorama.experienced_first_use", this, false);
     } else {
-      this._firstRunExperienced = true;
+      this._firstUseExperienced = true;
 
       if ((gBrowser.tabs.length - gBrowser.visibleTabs.length) > 0)
         this._setBrowserKeyHandlers();
 
       // ___ visibility
       let sessionstore =
         Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
       let data = sessionstore.getWindowValue(window, this.VISIBILITY_IDENTIFIER);
@@ -93,27 +99,28 @@ let TabView = {
     }
   },
 
   // ----------
   // Observes topic changes.
   observe: function TabView_observe(subject, topic, data) {
     if (topic == "nsPref:changed") {
       Services.prefs.removeObserver(
-        "browser.panorama.experienced_first_run", this);
-      this._firstRunExperienced = true;
+        "browser.panorama.experienced_first_use", this);
+      this._firstUseExperienced = true;
+      this._addToolbarButton();
     }
   },
 
   // ----------
   // Uninitializes TabView.
   uninit: function TabView_uninit() {
-    if (!this._firstRunExperienced) {
+    if (!this._firstUseExperienced) {
       Services.prefs.removeObserver(
-        "browser.panorama.experienced_first_run", this);
+        "browser.panorama.experienced_first_use", this);
     }
     if (this._tabShowEventListener) {
       gBrowser.tabContainer.removeEventListener(
         "TabShow", this._tabShowEventListener, true);
     }
   },
 
   // ----------
@@ -317,10 +324,33 @@ let TabView = {
   },
 
   // ----------
   // On move to group pop showing.
   moveToGroupPopupShowing: function TabView_moveToGroupPopupShowing(event) {
     // there are hidden tabs so initialize the iframe and update the context menu
     if ((gBrowser.tabs.length - gBrowser.visibleTabs.length) > 0)
       this.updateContextMenu(TabContextMenu.contextTab, event.target);
+  },
+
+  // ----------
+  // Function: _addToolbarButton
+  // Adds the TabView button to the TabsToolbar.
+  _addToolbarButton: function TabView__addToolbarButton() {
+    let buttonId = "tabview-button";
+
+    if (document.getElementById(buttonId))
+      return;
+
+    let toolbar = document.getElementById("TabsToolbar");
+    let currentSet = toolbar.currentSet.split(",");
+
+    let alltabsPos = currentSet.indexOf("alltabs-button");
+    if (-1 == alltabsPos)
+      return;
+
+    currentSet[alltabsPos] += "," + buttonId;
+    currentSet = currentSet.join(",");
+    toolbar.currentSet = currentSet;
+    toolbar.setAttribute("currentset", currentSet);
+    document.persist(toolbar.id, "currentset");
   }
 };
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -8489,17 +8489,17 @@ var TabContextMenu = {
     // Hide "Bookmark All Tabs" for a pinned tab.  Update its state if visible.
     let bookmarkAllTabs = document.getElementById("context_bookmarkAllTabs");
     bookmarkAllTabs.hidden = this.contextTab.pinned;
     if (!bookmarkAllTabs.hidden)
       PlacesCommandHook.updateBookmarkAllTabsCommand();
 
     // Hide "Move to Group" if it's a pinned tab.
     document.getElementById("context_tabViewMenu").hidden =
-      (this.contextTab.pinned || !TabView.firstRunExperienced);
+      (this.contextTab.pinned || !TabView.firstUseExperienced);
   }
 };
 
 XPCOMUtils.defineLazyGetter(this, "HUDConsoleUI", function () {
   Cu.import("resource:///modules/HUDService.jsm");
   try {
     return HUDService.consoleUI;
   }
--- a/browser/base/content/tabview/groupitems.js
+++ b/browser/base/content/tabview/groupitems.js
@@ -185,16 +185,18 @@ function GroupItem(listOfEls, options) {
     self.adjustTitleSize();
     self.save();
   };
 
   this.$title
     .blur(function() {
       self._titleFocused = false;
       self.$titleShield.show();
+      if (self.getTitle())
+        gTabView.firstUseExperienced = true;
     })
     .focus(function() {
       if (!self._titleFocused) {
         (self.$title)[0].select();
         self._titleFocused = true;
       }
     })
     .mousedown(function(e) {
--- a/browser/base/content/tabview/items.js
+++ b/browser/base/content/tabview/items.js
@@ -177,16 +177,18 @@ Item.prototype = {
         drag.info = new Drag(this, e);
       },
       drag: function(e) {
         drag.info.drag(e);
       },
       stop: function() {
         drag.info.stop();
         drag.info = null;
+        if (!this.isAGroupItem && !this.parent)
+          gTabView.firstUseExperienced = true;
       },
       // The minimum the mouse must move after mouseDown in order to move an 
       // item
       minDragDistance: 3
     };
 
     // ___ drop
     this.dropOptions = {
--- a/browser/base/content/tabview/tabview.js
+++ b/browser/base/content/tabview/tabview.js
@@ -2,46 +2,38 @@ const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource:///modules/tabview/AllTabs.jsm");
 Cu.import("resource:///modules/tabview/utils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-XPCOMUtils.defineLazyGetter(this, "gWindow", function() {
-  return window.parent;
-});
-
-XPCOMUtils.defineLazyGetter(this, "gBrowser", function() gWindow.gBrowser);
-
-XPCOMUtils.defineLazyGetter(this, "gTabViewDeck", function() {
-  return gWindow.document.getElementById("tab-view-deck");
-});
-
-XPCOMUtils.defineLazyGetter(this, "gTabViewFrame", function() {
-  return gWindow.document.getElementById("tab-view");
-});
-
 XPCOMUtils.defineLazyGetter(this, "tabviewBundle", function() {
   return Services.strings.
     createBundle("chrome://browser/locale/tabview.properties");
 });
 
 function tabviewString(name) tabviewBundle.GetStringFromName('tabview.' + name);
 
 XPCOMUtils.defineLazyGetter(this, "gPrefBranch", function() {
   return Services.prefs.getBranch("browser.panorama.");
 });
 
 XPCOMUtils.defineLazyGetter(this, "gPrivateBrowsing", function() {
   return Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
 });
 
+var gWindow = window.parent;
+var gBrowser = gWindow.gBrowser;
+var gTabView = gWindow.TabView;
+var gTabViewDeck = gWindow.document.getElementById("tab-view-deck");
+var gTabViewFrame = gWindow.document.getElementById("tab-view");
+
 # NB: Certain files need to evaluate before others
 
 #include iq.js
 #include storage.js
 #include items.js
 #include groupitems.js
 #include tabitems.js
 #include drag.js
--- a/browser/base/content/tabview/ui.js
+++ b/browser/base/content/tabview/ui.js
@@ -188,16 +188,17 @@ let UI = {
             newTab._tabViewTabItem.pushAway(true);
             GroupItems.setActiveOrphanTab(newTab._tabViewTabItem);
 
             TabItems.creatingNewOrphanTab = false;
             newTab._tabViewTabItem.zoomIn(true);
 
             self._lastClick = 0;
             self._lastClickPositions = null;
+            gTabView.firstUseExperienced = true;
           } else {
             self._lastClick = Date.now();
             self._lastClickPositions = new Point(e.clientX, e.clientY);
             self._createGroupItemOnDrag(e);
           }
         }
       });
 
@@ -219,23 +220,18 @@ let UI = {
       GroupItems.init();
       GroupItems.pauseArrange();
       let hasGroupItemsData = GroupItems.load();
 
       // ___ tabs
       TabItems.init();
       TabItems.pausePainting();
 
-      // if first time in Panorama or no group data:
-      let firstTime = true;
-      if (gPrefBranch.prefHasUserValue("experienced_first_run"))
-        firstTime = !gPrefBranch.getBoolPref("experienced_first_run");
-
-      if (firstTime || !hasGroupItemsData)
-        this.reset(firstTime);
+      if (!hasGroupItemsData)
+        this.reset();
 
       // ___ resizing
       if (this._pageBounds)
         this._resize(true);
       else
         this._pageBounds = Items.getPageBounds();
 
       iQ(window).resize(function() {
@@ -294,18 +290,17 @@ let UI = {
   },
 
   // Property: rtl
   // Returns true if we are in RTL mode, false otherwise
   rtl: false,
 
   // Function: reset
   // Resets the Panorama view to have just one group with all tabs
-  // and, if firstTime == true, add the welcome video/tab
-  reset: function UI_reset(firstTime) {
+  reset: function UI_reset() {
     let padding = Trenches.defaultRadius;
     let welcomeWidth = 300;
     let pageBounds = Items.getPageBounds();
     pageBounds.inset(padding, padding);
 
     let $actions = iQ("#actions");
     if ($actions) {
       pageBounds.width -= $actions.width();
@@ -333,41 +328,16 @@ let UI = {
     let groupItem = new GroupItem([], options);
     let items = TabItems.getItems();
     items.forEach(function(item) {
       if (item.parent)
         item.parent.remove(item);
       groupItem.add(item, {immediately: true});
     });
     GroupItems.setActiveGroupItem(groupItem);
-
-    if (firstTime) {
-      gPrefBranch.setBoolPref("experienced_first_run", true);
-      // ensure that the first run pref is flushed to the file, in case a crash 
-      // or force quit happens before the pref gets flushed automatically.
-      Services.prefs.savePrefFile(null);
-
-      /* DISABLED BY BUG 626754. To be reenabled via bug 626926.
-      let url = gPrefBranch.getCharPref("welcome_url");
-      let newTab = gBrowser.loadOneTab(url, {inBackground: true});
-      let newTabItem = newTab._tabViewTabItem;
-      let parent = newTabItem.parent;
-      Utils.assert(parent, "should have a parent");
-
-      newTabItem.parent.remove(newTabItem);
-      let aspect = TabItems.tabHeight / TabItems.tabWidth;
-      let welcomeBounds = new Rect(UI.rtl ? pageBounds.left : box.right, box.top,
-                                   welcomeWidth, welcomeWidth * aspect);
-      newTabItem.setBounds(welcomeBounds, true);
-
-      // Remove the newly created welcome-tab from the tab bar
-      if (!this.isTabViewVisible())
-        GroupItems._updateTabBar();
-      */
-    }
   },
 
   // Function: blurAll
   // Blurs any currently focused element
   //
   blurAll: function UI_blurAll() {
     iQ(":focus").each(function(element) {
       element.blur();
@@ -607,17 +577,17 @@ let UI = {
   // Function: storageReady
   // Resumes the activity paused by storageBusy, and updates for any new group
   // information in sessionstore. Calls can be nested. 
   storageReady: function UI_storageReady() {
     this._storageBusyCount--;
     if (!this._storageBusyCount) {
       let hasGroupItemsData = GroupItems.load();
       if (!hasGroupItemsData)
-        this.reset(false);
+        this.reset();
   
       TabItems.resumeReconnecting();
       GroupItems._updateTabBar();
       GroupItems.resumeAutoclose();
     }
   },
 
   // ----------
@@ -1188,16 +1158,17 @@ let UI = {
           if (bounds.contains(tab.bounds))
             insideTabs.push(tab);
         }
 
         var groupItem = new GroupItem(insideTabs,{bounds:bounds});
         GroupItems.setActiveGroupItem(groupItem);
         phantom.remove();
         dragOutInfo = null;
+        gTabView.firstUseExperienced = true;
       } else {
         collapse();
       }
     }
 
     iQ(window).mousemove(updateSize)
     iQ(gWindow).one("mouseup", finalize);
     e.preventDefault();
@@ -1447,13 +1418,13 @@ let UI = {
   // ----------
   // Function: _saveAll
   // Saves all data associated with TabView.
   // TODO: Save info items
   _saveAll: function UI__saveAll() {
     this._save();
     GroupItems.saveAll();
     TabItems.saveAll();
-  },
+  }
 };
 
 // ----------
 UI.init();
--- a/browser/base/content/test/tabview/Makefile.in
+++ b/browser/base/content/test/tabview/Makefile.in
@@ -98,16 +98,17 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug624931.js \
                  browser_tabview_bug624727.js \
                  browser_tabview_bug624847.js \
                  browser_tabview_bug624953.js \
                  browser_tabview_bug625269.js \
                  browser_tabview_bug625424.js \
                  browser_tabview_bug626368.js \
                  browser_tabview_bug626525.js \
+                 browser_tabview_bug626791.js \
                  browser_tabview_bug627288.js \
                  browser_tabview_bug627736.js \
                  browser_tabview_bug628165.js \
                  browser_tabview_bug628270.js \
                  browser_tabview_bug629189.js \
                  browser_tabview_bug629195.js \
                  browser_tabview_bug630102.js \
                  browser_tabview_bug630157.js \
@@ -121,17 +122,16 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_multiwindow_search.js \
                  browser_tabview_orphaned_tabs.js \
                  browser_tabview_privatebrowsing.js \
                  browser_tabview_rtl.js \
                  browser_tabview_search.js \
                  browser_tabview_snapping.js \
                  browser_tabview_startup_transitions.js \
                  browser_tabview_undo_group.js \
-                 browser_tabview_firstrun_pref.js \
                  dummy_page.html \
                  head.js \
                  search1.html \
                  search2.html \
                  test_bug599626.html \
                  test_bug600645.html \
                  $(NULL)
 
--- a/browser/base/content/test/tabview/browser_tabview_bug589324.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug589324.js
@@ -99,17 +99,17 @@ function test() {
       // check the hidden state of both tabs.
       ok(firstTab.hidden, "The first tab is hidden");
       ok(!secondTab.hidden, "The second tab is not hidden");
       is(secondTab, newWin.gBrowser.selectedTab, "The second tab is selected");
 
       // when the second tab is hidden, the iframe should be initialized and 
       // the first tab should be visible.
       let onTabHide = function() {
-        newWin.gBrowser.tabContainer.addEventListener("TabHide", onTabHide, true);
+        newWin.gBrowser.tabContainer.removeEventListener("TabHide", onTabHide, true);
 
         ok(newWin.TabView.getContentWindow(), "");
 
         ok(!firstTab.hidden, "The first tab is not hidden");
         is(firstTab, newWin.gBrowser.selectedTab, "The first tab is selected");
         ok(secondTab.hidden, "The second tab is hidden");
 
         // clean up and finish
--- a/browser/base/content/test/tabview/browser_tabview_bug626525.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug626525.js
@@ -4,17 +4,17 @@
 let prefsBranch;
 let currentActiveGroupItemId;
 
 function test() {
   waitForExplicitFinish();
 
   // disable the first run pref
   prefsBranch = Services.prefs.getBranch("browser.panorama.");
-  prefsBranch.setBoolPref("experienced_first_run", false);
+  prefsBranch.setBoolPref("experienced_first_use", false);
 
   let win =
     window.openDialog(getBrowserURL(), "_blank", "all,dialog=no", "about:blank");
 
   let onLoad = function() {
     win.removeEventListener("load", onLoad, false);
 
     let theObserver = function(subject, topic, data) {
@@ -62,17 +62,17 @@ function test2(win) {
     test3(win);
   });
 }
 
 // first run has happened, open the tab context menupopup and the tabview menu,
 // move a tab to another group including iframe initialization.  Then,
 // use the key combination to change to the next group.
 function test3(win) {
-  prefsBranch.setBoolPref("experienced_first_run", true);
+  prefsBranch.setBoolPref("experienced_first_use", true);
 
   let newTab = win.gBrowser.addTab("about:blank");
 
   // open the tab context menupopup and the tabview menupopup
   openTabContextPopup(win, newTab);
   win.document.getElementById("context_tabViewMenuPopup").openPopup(
     win.document.getElementById("context_tabViewMenu"), "end_after", 0, 0,
     true, false);
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabview/browser_tabview_bug626791.js
@@ -0,0 +1,192 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+  let cw;
+  let win;
+  let prefix;
+
+  let getToolbar = function () {
+    return win.document.getElementById("TabsToolbar");
+  }
+
+  let assertToolbarButtonExists = function () {
+    isnot(getToolbar().currentSet.indexOf("tabview-button"), -1,
+          prefix + ": panorama button should be in the toolbar");
+  }
+
+  let assertToolbarButtonNotExists = function () {
+    is(getToolbar().currentSet.indexOf("tabview-button"), -1,
+       prefix + ": panorama button should not be in the toolbar");
+  }
+
+  let assertNumberOfGroups = function (num) {
+    is(cw.GroupItems.groupItems.length, num, prefix + ': there are ' + num + ' groups');
+  }
+
+  let assertNumberOfTabs = function (num) {
+    is(win.gBrowser.tabs.length, num, prefix + ': there are ' + num + ' tabs');
+  }
+
+  let removeToolbarButton = function () {
+    let toolbar = getToolbar();
+    let currentSet = toolbar.currentSet.split(",");
+    let buttonId = "tabview-button";
+    let pos = currentSet.indexOf(buttonId);
+
+    if (-1 < pos) {
+      currentSet.splice(pos, 1);
+      toolbar.setAttribute("currentset", currentSet.join(","));
+      toolbar.currentSet = currentSet.join(",");
+      win.document.persist(toolbar.id, "currentset");
+    }
+  }
+
+  let newWindowWithTabView = function (callback) {
+    win = window.openDialog(getBrowserURL(), "_blank", 
+                            "chrome,all,dialog=no,height=800,width=800");
+    let onLoad = function() {
+      win.removeEventListener("load", onLoad, false);
+
+      removeToolbarButton();
+      TabView.firstUseExperienced = false;
+      TabView.init();
+
+      let onShown = function() {
+        win.removeEventListener("tabviewshown", onShown, false);
+
+        cw = win.TabView.getContentWindow();
+        let groupItem = cw.GroupItems.groupItems[0];
+        groupItem.setSize(200, 200, true);
+        groupItem.setUserSize();
+
+        callback();
+      };
+
+      win.addEventListener("tabviewshown", onShown, false);
+      win.TabView.toggle();
+    }
+    win.addEventListener("load", onLoad, false);
+  }
+
+  let testNameGroup = function () {
+    prefix = 'name-group';
+    assertToolbarButtonNotExists();
+    let groupItem = cw.GroupItems.groupItems[0];
+
+    groupItem.setTitle('title');
+    assertToolbarButtonNotExists();
+    groupItem.setTitle('');
+
+    EventUtils.synthesizeMouseAtCenter(groupItem.$titleShield[0], {}, cw);
+    EventUtils.synthesizeKey('t', {}, cw);
+    groupItem.$title[0].blur();
+
+    assertToolbarButtonExists();
+    next();
+  }
+
+  let testDragToCreateGroup = function () {
+    prefix = 'drag-to-create-group';
+    assertToolbarButtonNotExists();
+    let width = cw.innerWidth;
+    let height = cw.innerHeight;
+
+    let body = cw.document.body;
+    EventUtils.synthesizeMouse(body, width - 10, height - 10, {type: 'mousedown'}, cw);
+    EventUtils.synthesizeMouse(body, width - 200, height - 200, {type: 'mousemove'}, cw);
+    EventUtils.synthesizeMouse(body, width - 200, height - 200, {type: 'mouseup'}, cw);
+
+    assertToolbarButtonExists();
+    next();
+  }
+
+  let testCreateOrphan = function (tab) {
+    prefix = 'create-orphan';
+    assertNumberOfTabs(1);
+    assertToolbarButtonNotExists();
+
+    let width = cw.innerWidth;
+    let height = cw.innerHeight;
+
+    let body = cw.document.body;
+    EventUtils.synthesizeMouse(body, width - 10, height - 10, {}, cw);
+    EventUtils.synthesizeMouse(body, width - 10, height - 10, {}, cw);
+
+    whenTabViewIsHidden(function () {
+      assertNumberOfTabs(2);
+      assertToolbarButtonExists();
+
+      next();
+    });
+  }
+
+  let testDragToCreateOrphan = function (tab) {
+    if (!tab) {
+      let tab = win.gBrowser.loadOneTab('about:blank', {inBackground: true});
+      afterAllTabsLoaded(function () testDragToCreateOrphan(tab), win);
+      return;
+    }
+
+    prefix = 'drag-to-create-orphan';
+    assertNumberOfTabs(2);
+    assertToolbarButtonNotExists();
+
+    let width = cw.innerWidth;
+    let height = cw.innerHeight;
+
+    let target = tab._tabViewTabItem.container;
+    let rect = target.getBoundingClientRect();
+    EventUtils.synthesizeMouseAtCenter(target, {type: 'mousedown'}, cw);
+    EventUtils.synthesizeMouse(target, rect.width - 10, rect.height - 10, {type: 'mousemove'}, cw);
+    EventUtils.synthesizeMouse(target, width - 300, height - 300, {type: 'mousemove'}, cw);
+    EventUtils.synthesizeMouse(target, width - 200, height - 200, {type: 'mousemove'}, cw);
+    EventUtils.synthesizeMouseAtCenter(target, {type: 'mouseup'}, cw);
+
+    assertToolbarButtonExists();
+    next();
+  }
+
+  let testReAddingAfterRemoval = function () {
+    prefix = 're-adding-after-removal';
+    assertToolbarButtonNotExists();
+
+    TabView.firstUseExperienced = true;
+    removeToolbarButton();
+
+    TabView.firstUseExperienced = true;
+    TabView._addToolbarButton();
+
+    assertToolbarButtonNotExists();
+    next();
+  }
+
+  let tests = [testNameGroup, testDragToCreateGroup, testCreateOrphan,
+               testDragToCreateOrphan, testReAddingAfterRemoval];
+
+  let next = function () {
+    let test = tests.shift();
+
+    if (win)
+      win.close();
+
+    if (!test) {
+      finish();
+      return;
+    }
+
+    newWindowWithTabView(function () {
+      assertToolbarButtonNotExists();
+      test();
+    });
+  }
+
+  waitForExplicitFinish();
+
+  registerCleanupFunction(function () {
+    if (win && !win.closed)
+      win.close();
+  });
+
+  next();
+}