Bug 347930 - Move the tabs outside the tabbrowser, put them in a toolbar. r=vlad
authorDão Gottwald <dao@mozilla.com>
Wed, 17 Mar 2010 07:36:13 +0100
changeset 39508 8ca8630b0c88cfb04d9ba8e2d861f06c3e6289d0
parent 39507 528a9b4f475d32599b4beb051b24f77c126ae63c
child 39509 11798edae90d13bdba1ae8dc9243be5f46b89bde
push id12237
push userdgottwald@mozilla.com
push dateWed, 17 Mar 2010 06:38:18 +0000
treeherdermozilla-central@8ca8630b0c88 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvlad
bugs347930
milestone1.9.3a4pre
Bug 347930 - Move the tabs outside the tabbrowser, put them in a toolbar. r=vlad
accessible/tests/mochitest/events/test_scroll.xul
accessible/tests/mochitest/name_nsRootAcc_wnd.xul
accessible/tests/mochitest/tree/test_tabbrowser.xul
browser/base/content/browser.css
browser/base/content/browser.js
browser/base/content/browser.xul
browser/base/content/tabbrowser.css
browser/base/content/tabbrowser.xml
browser/fuel/src/fuelApplication.js
browser/locales/en-US/chrome/browser/tabbrowser.dtd
browser/themes/gnomestripe/browser/browser.css
browser/themes/pinstripe/browser/browser.css
browser/themes/winstripe/browser/browser.css
browser/themes/winstripe/browser/jar.mn
browser/themes/winstripe/browser/tabbrowser/tabbrowser-tabs-bkgnd.png
browser/themes/winstripe/browser/tabbrowser/tabstrip-bottom.png
--- a/accessible/tests/mochitest/events/test_scroll.xul
+++ b/accessible/tests/mochitest/events/test_scroll.xul
@@ -31,16 +31,18 @@
   <script type="application/javascript">
   <![CDATA[
 
     ////////////////////////////////////////////////////////////////////////////
     // Hack to make xul:tabbrowser work
 
     const Ci = Components.interfaces;
 
+    Components.utils.import("resource://gre/modules/Services.jsm");
+
     var XULBrowserWindow = {
       isBusy: false,
       setOverLink: function (link, b) {
       }
     };
 
     ////////////////////////////////////////////////////////////////////////////
     // Tests
@@ -96,13 +98,22 @@
         <menu label="menu">
           <menupopup>
             <menuitem label="close window hook" id="menu_closeWindow"/>
             <menuitem label="close hook" id="menu_close"/>
           </menupopup>
         </menu>
       </menubar>
 
-      <tabbrowser type="content-primary" flex="1" id="tabBrowser"/>
+      <tabs id="tabbrowser-tabs" class="tabbrowser-tabs"
+            tabbrowser="tabBrowser"
+            flex="1"
+            setfocus="false">
+        <tab class="tabbrowser-tab" selected="true"/>
+      </tabs>
+      <tabbrowser id="tabBrowser"
+                  type="content-primary"
+                  tabcontainer="tabbrowser-tabs"
+                  flex="1"/>
     </vbox>
   </hbox>
 
 </window>
--- a/accessible/tests/mochitest/name_nsRootAcc_wnd.xul
+++ b/accessible/tests/mochitest/name_nsRootAcc_wnd.xul
@@ -18,16 +18,17 @@
       gOpenerWnd.SimpleTest.ok(aCond, aMsg);
     }
 
     function is(aExpected, aActual, aMsg) {
       gOpenerWnd.SimpleTest.is(aExpected, aActual, aMsg);
     }
 
     // Hack to make xul:tabbrowser work.
+    Components.utils.import("resource://gre/modules/Services.jsm");
     var XULBrowserWindow = {
       isBusy: false,
       setOverLink: function (link, b) {
       }
     };
     var gFindBar = {
       hidden: true
     };
@@ -104,11 +105,20 @@
     <menu label="menu">
       <menupopup>
         <menuitem label="close window hook" id="menu_closeWindow"/>
         <menuitem label="close hook" id="menu_close"/>
       </menupopup>
     </menu>
   </menubar>
 
-  <tabbrowser type="content-primary" flex="1" id="content"/>
+  <tabs id="tabbrowser-tabs" class="tabbrowser-tabs"
+        tabbrowser="content"
+        flex="1"
+        setfocus="false">
+    <tab class="tabbrowser-tab" selected="true"/>
+  </tabs>
+  <tabbrowser id="content"
+              type="content-primary"
+              tabcontainer="tabbrowser-tabs"
+              flex="1"/>
 
 </window>
--- a/accessible/tests/mochitest/tree/test_tabbrowser.xul
+++ b/accessible/tests/mochitest/tree/test_tabbrowser.xul
@@ -21,16 +21,17 @@
   <script type="application/javascript">
   <![CDATA[
     ////////////////////////////////////////////////////////////////////////////
     // Test
 
     const Ci = Components.interfaces;
 
     // Hack to make xul:tabbrowser work.
+    Components.utils.import("resource://gre/modules/Services.jsm");
     var XULBrowserWindow = {
       isBusy: false,
       setOverLink: function (link, b) {
       }
     };
     var gFindBar = {
       hidden: true
     };
@@ -62,71 +63,69 @@
       tabBrowser.addProgressListener(progressListener,
                                      Ci.nsIWebProgress.NOTIFY_STATE_WINDOW);
 
       tabBrowser.loadTabs(["about:", "about:mozilla"], false, true);
     }
 
     function testAccTree()
     {
-      var accTree = {
-        role: ROLE_PANE,
+      var tabsAccTree = {
+        role: ROLE_PAGETABLIST,
         children: [
           {
-            role: ROLE_TOOLTIP
-          },
-          {
             role: ROLE_MENUPOPUP
           },
           {
-            role: ROLE_PAGETABLIST,
+            role: ROLE_PAGETAB,
             children: [
               {
-                role: ROLE_PAGETAB,
-                children: [
-                  {
-                    role: ROLE_PUSHBUTTON
-                  }
-                ]
-              },
-              {
-                role: ROLE_PAGETAB,
-                children: [
-                  {
-                    role: ROLE_PUSHBUTTON
-                  }
-                ]
-              },
-              {
-                role: ROLE_PUSHBUTTON
-              },
-              {
                 role: ROLE_PUSHBUTTON
               }
             ]
           },
           {
+            role: ROLE_PAGETAB,
+            children: [
+              {
+                role: ROLE_PUSHBUTTON
+              }
+            ]
+          },
+          {
+            role: ROLE_PUSHBUTTON
+          },
+          {
+            role: ROLE_PUSHBUTTON
+          }
+        ]
+      };
+      var tabboxAccTree = {
+        role: ROLE_PANE,
+        children: [
+          {
             role: ROLE_PROPERTYPAGE
           },
           {
             role: ROLE_PROPERTYPAGE
           }
         ]
       };
-      testAccessibleTree(getNode("tabbrowser").mTabBox, accTree);
+      testAccessibleTree(getNode("tabbrowser").tabContainer, tabsAccTree);
+      testAccessibleTree(getNode("tabbrowser").mTabBox, tabboxAccTree);
 
       SimpleTest.finish()
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   ]]>
   </script>
 
-  <hbox flex="1" style="overflow: auto;">
+  <vbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=540389"
          title=" WARNING: Bad accessible tree!: [tabbrowser tab] ">
         Mozilla Bug 540389
       </a><br/>
       <p id="display"></p>
       <div id="content" style="display: none">
@@ -140,13 +139,21 @@
       <menu label="menu">
         <menupopup>
           <menuitem label="close window hook" id="menu_closeWindow"/>
           <menuitem label="close hook" id="menu_close"/>
         </menupopup>
       </menu>
     </menubar>
 
-    <tabbrowser type="content-primary" flex="1" id="tabbrowser"/>
-  </hbox>
+    <tabs id="tabbrowser-tabs" class="tabbrowser-tabs"
+          tabbrowser="tabbrowser"
+          setfocus="false">
+      <tab class="tabbrowser-tab" selected="true"/>
+    </tabs>
+    <tabbrowser id="tabbrowser"
+                type="content-primary"
+                tabcontainer="tabbrowser-tabs"
+                flex="1"/>
+  </vbox>
 
 </window>
 
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -4,16 +4,24 @@
 searchbar {
   -moz-binding: url("chrome://browser/content/search/search.xml#searchbar");
 }
 
 tabbrowser {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser");
 }
 
+.tabbrowser-tabs {
+  -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tabs");
+}
+
+.tabbrowser-tab {
+  -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
+}
+
 toolbar[printpreview="true"] {
   -moz-binding: url("chrome://global/content/printPreviewBindings.xml#printpreviewtoolbar");
 }
 
 toolbarpaletteitem[place="palette"] > toolbaritem > hbox[type="places"] {
   display: none;
 }
 
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -265,18 +265,18 @@ function SetClickAndHoldHandlers() {
     forwardButton.setAttribute("type", "menu");
     forwardButton.appendChild(popup);    
     _addClickAndHoldListenersOnElement(forwardButton);
     unifiedButton._clickHandlersAttached = true;
   }
 }
 #endif
 
-function BookmarkThisTab() {
-  PlacesCommandHook.bookmarkPage(gBrowser.mContextTab.linkedBrowser,
+function BookmarkThisTab(aTab) {
+  PlacesCommandHook.bookmarkPage(aTab.linkedBrowser,
                                  PlacesUtils.bookmarksMenuFolderId, true);
 }
 
 const gSessionHistoryObserver = {
   observe: function(subject, topic, data)
   {
     if (topic != "browser:purge-session-history")
       return;
@@ -1211,19 +1211,17 @@ function delayedStartup(isLoadingBlank, 
 
   gNavToolbox.customizeDone = BrowserToolboxCustomizeDone;
   gNavToolbox.customizeChange = BrowserToolboxCustomizeChange;
 
   // Set up Sanitize Item
   initializeSanitizer();
 
   // Enable/Disable auto-hide tabbar
-  gAutoHideTabbarPrefListener.toggleAutoHideTabbar();
-  gPrefService.addObserver(gAutoHideTabbarPrefListener.domain,
-                           gAutoHideTabbarPrefListener, false);
+  gBrowser.tabContainer.updateVisibility();
 
   gPrefService.addObserver(gHomeButton.prefDomain, gHomeButton, false);
 
   var homeButton = document.getElementById("home-button");
   gHomeButton.updateTooltip(homeButton);
   gHomeButton.updatePersonalToolbarStyle(homeButton);
 
 #ifdef HAVE_SHELL_SERVICE
@@ -1400,18 +1398,16 @@ function BrowserShutdown()
     gBrowser.removeProgressListener(window.XULBrowserWindow);
     gBrowser.removeTabsProgressListener(window.TabsProgressListener);
   } catch (ex) {
   }
 
   PlacesStarButton.uninit();
 
   try {
-    gPrefService.removeObserver(gAutoHideTabbarPrefListener.domain,
-                                gAutoHideTabbarPrefListener);
     gPrefService.removeObserver(gHomeButton.prefDomain, gHomeButton);
   } catch (ex) {
     Components.utils.reportError(ex);
   }
 
   BrowserOffline.uninit();
   OfflineApps.uninit();
   DownloadMonitorPanel.uninit();
@@ -1511,36 +1507,16 @@ function nonBrowserWindowDelayedStartup(
 function nonBrowserWindowShutdown()
 {
   BrowserOffline.uninit();
 
   gPrivateBrowsingUI.uninit();
 }
 #endif
 
-var gAutoHideTabbarPrefListener = {
-  domain: "browser.tabs.autoHide",
-  observe: function (aSubject, aTopic, aPrefName) {
-    if (aTopic == "nsPref:changed" && aPrefName == this.domain)
-      this.toggleAutoHideTabbar();
-  },
-  toggleAutoHideTabbar: function () {
-    if (gBrowser.tabContainer.childNodes.length == 1 &&
-        window.toolbar.visible) {
-      var aVisible = false;
-      try {
-        aVisible = !gPrefService.getBoolPref(this.domain);
-      }
-      catch (e) {
-      }
-      gBrowser.setStripVisibilityTo(aVisible);
-    }
-  }
-}
-
 function initializeSanitizer()
 {
   const kDidSanitizeDomain = "privacy.sanitize.didShutdownSanitize";
   if (gPrefService.prefHasUserValue(kDidSanitizeDomain)) {
     gPrefService.clearUserPref(kDidSanitizeDomain);
     // We need to persist this preference change, since we want to
     // check it at next app start even if the browser exits abruptly
     gPrefService.savePrefFile(null);
@@ -2590,33 +2566,29 @@ var PrintPreviewListener = {
   },
   _hideChrome: function () {
     this._chromeState = {};
 
     var sidebar = document.getElementById("sidebar-box");
     this._chromeState.sidebarOpen = !sidebar.hidden;
     this._sidebarCommand = sidebar.getAttribute("sidebarcommand");
 
-    gBrowser.mStrip.setAttribute("moz-collapsed", "true");
-
     var notificationBox = gBrowser.getNotificationBox();
     this._chromeState.notificationsOpen = !notificationBox.notificationsHidden;
     notificationBox.notificationsHidden = true;
 
     document.getElementById("sidebar").setAttribute("src", "about:blank");
     var statusbar = document.getElementById("status-bar");
     this._chromeState.statusbarOpen = !statusbar.hidden;
     statusbar.hidden = true;
 
     this._chromeState.findOpen = !gFindBar.hidden;
     gFindBar.close();
   },
   _showChrome: function () {
-    gBrowser.mStrip.removeAttribute("moz-collapsed");
-
     if (this._chromeState.notificationsOpen)
       gBrowser.getNotificationBox().notificationsHidden = false;
 
     if (this._chromeState.statusbarOpen)
       document.getElementById("status-bar").hidden = false;
 
     if (this._chromeState.findOpen)
       gFindBar.open();
@@ -3671,18 +3643,17 @@ var FullScreen =
       FullScreen._isAnimating = false;
       FullScreen._shouldAnimate = true;
       return;
     }
 
     var animateFrameAmount = 2;
     function animateUpFrame() {
       animateFrameAmount *= 2;
-      if (animateFrameAmount >=
-          (gNavToolbox.boxObject.height + gBrowser.mStrip.boxObject.height)) {
+      if (animateFrameAmount >= gNavToolbox.boxObject.height) {
         // We've animated enough
         clearInterval(FullScreen._animationInterval);
         gNavToolbox.style.marginTop = "0px";
         FullScreen._isAnimating = false;
         FullScreen._shouldAnimate = false; // Just to make sure
         FullScreen.mouseoverToggle(false);
         return;
       }
@@ -3721,17 +3692,16 @@ var FullScreen =
       gBrowser.mPanelContainer.addEventListener("mousemove",
                                                 this._collapseCallback, false);
     }
     else {
       gBrowser.mPanelContainer.removeEventListener("mousemove",
                                                    this._collapseCallback, false);
     }
 
-    gBrowser.mStrip.setAttribute("moz-collapsed", !aShow);
     var allFSToolbars = document.getElementsByTagNameNS(this._XULNS, "toolbar");
     for (var i = 0; i < allFSToolbars.length; i++) {
       if (allFSToolbars[i].getAttribute("fullscreentoolbar") == "true")
         allFSToolbars[i].setAttribute("moz-collapsed", !aShow);
     }
     document.getElementById("fullscr-toggler").setAttribute("moz-collapsed", aShow);
     this._isChromeCollapsed = !aShow;
     if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 2)
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -306,16 +306,18 @@
 
     <panel id="customizeToolbarSheetPopup"
            noautohide="true"
            onpopupshown="this.moveTo(this.boxObject.screenX + (window.innerWidth - this.boxObject.width) / 2, this.boxObject.screenY);">
       <iframe id="customizeToolbarSheetIFrame"
               style="&dialog.style;"
               hidden="true"/>
     </panel>
+
+    <tooltip id="tabbrowser-tab-tooltip" onpopupshowing="gBrowser.createTooltip(event);"/>
   </popupset>
 
   <toolbox id="navigator-toolbox" class="toolbox-top" mode="icons"
 #ifdef WINCE
            defaulticonsize="small" iconsize="small"
 #endif
            defaultmode="icons">
     <!-- Menu -->
@@ -511,16 +513,28 @@
                context="placesContext"
                onclick="BookmarksEventHandler.onClick(event);"
                oncommand="BookmarksEventHandler.onCommand(event);"
                onpopupshowing="BookmarksEventHandler.onPopupShowing(event);"
                tooltip="bhTooltip" popupsinherittooltip="true"/>
       </toolbaritem>
     </toolbar>
 
+    <toolbar id="TabsToolbar"
+             fullscreentoolbar="true"
+             collapsed="true">
+      <tabs id="tabbrowser-tabs" class="tabbrowser-tabs"
+            tabbrowser="content"
+            flex="1"
+            setfocus="false"
+            tooltip="tabbrowser-tab-tooltip">
+        <tab class="tabbrowser-tab" selected="true"/>
+      </tabs>
+    </toolbar>
+
     <toolbarpalette id="BrowserToolbarPalette">
 
       <toolbarbutton id="print-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                      label="&printButton.label;" command="cmd_print"
                      tooltiptext="&printButton.tooltip;"/>
 
       <toolbaritem id="navigator-throbber" title="&throbberItem.title;" align="center" pack="center"
                    mousethrough="always">
@@ -598,16 +612,17 @@
       <browser id="sidebar" flex="1" autoscroll="false" disablehistory="true"
                 style="min-width: 14em; width: 18em; max-width: 36em;"/>
     </vbox>
 
     <splitter id="sidebar-splitter" class="chromeclass-extrachrome" hidden="true"/>
     <vbox id="appcontent" flex="1">
       <tabbrowser id="content" disablehistory="true"
                   flex="1" contenttooltip="aHTMLTooltip"
+                  tabcontainer="tabbrowser-tabs"
                   contentcontextmenu="contentAreaContextMenu"
                   autocompletepopup="PopupAutoComplete"
                   ondrop="contentAreaDNDObserver.onDrop(event)"
                   onclick="return contentAreaClick(event, false);"/>
     </vbox>
   </hbox>
 
   <vbox id="browser-bottombox">
--- a/browser/base/content/tabbrowser.css
+++ b/browser/base/content/tabbrowser.css
@@ -1,14 +1,10 @@
-.tabbrowser-tabs {
-  -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tabs");
-}
-
-.tabbrowser-tab {
-  -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
+.tabbrowser-tabbox {
+  -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tabbox");
 }
 
 .tabbrowser-arrowscrollbox {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-arrowscrollbox");
 }
 
 .tabs-alltabs-popup {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-alltabs-popup");
@@ -26,18 +22,18 @@
 .tabbrowser-tabs:not([closebuttons="noclose"]):not([closebuttons="closeatend"]) > .tabbrowser-tab[selected="true"]:not(:only-child) > .tab-close-button {
   display: -moz-box;
 }
 
 .tabbrowser-tabs[closebuttons="alltabs"] > .tabbrowser-tab:not(:only-child) > .tab-close-button {
   display: -moz-box;
 }
 
-.tabs-container:not([overflow="true"]) > .tabs-newtab-button,
-.tabs-container[overflow="true"] > .tabbrowser-arrowscrollbox > .tabs-newtab-button {
+.tabbrowser-tabs:not([overflow="true"]) > .tabs-newtab-button,
+.tabbrowser-tabs[overflow="true"] > .tabbrowser-arrowscrollbox > .tabs-newtab-button {
   visibility: collapse;
 }
 
 .tabs-newtab-button > .toolbarbutton-text {
   display: none;
 }
 
 tabpanels {
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -60,82 +60,19 @@
 
   <binding id="tabbrowser">
     <resources>
       <stylesheet src="chrome://browser/content/tabbrowser.css"/>
     </resources>
 
     <content>
       <xul:stringbundle anonid="tbstringbundle" src="chrome://browser/locale/tabbrowser.properties"/>
-      <xul:tabbox anonid="tabbox" flex="1" eventnode="document" xbl:inherits="handleCtrlPageUpDown"
+      <xul:tabbox anonid="tabbox" class="tabbrowser-tabbox"
+                  flex="1" eventnode="document" xbl:inherits="handleCtrlPageUpDown"
                   onselect="if (event.target.localName == 'tabpanels') this.parentNode.updateCurrentBrowser();">
-        <xul:hbox class="tabbrowser-strip" collapsed="true" tooltip="_child" context="_child"
-                  anonid="strip"
-                  ondragstart="this.parentNode.parentNode._onDragStart(event);"
-                  ondragover="this.parentNode.parentNode._onDragOver(event);"
-                  ondrop="this.parentNode.parentNode._onDrop(event);"
-                  ondragend="this.parentNode.parentNode._onDragEnd(event);"
-                  ondragleave="this.parentNode.parentNode._onDragLeave(event);">
-          <xul:hbox align="start">
-            <xul:image class="tab-drop-indicator" anonid="tab-drop-indicator" collapsed="true"/>
-          </xul:hbox>
-          <xul:tooltip onpopupshowing="return this.parentNode.parentNode.parentNode.createTooltip(event);"/>
-          <xul:menupopup anonid="tabContextMenu" onpopupshowing="this.parentNode.parentNode.parentNode.updatePopupMenu(this);">
-            <xul:menuitem id="context_newTab" label="&newTab.label;" accesskey="&newTab.accesskey;"
-                          command="cmd_newNavigatorTab"/>
-            <xul:menuseparator/>
-            <xul:menuitem id="context_reloadTab" label="&reloadTab.label;" accesskey="&reloadTab.accesskey;"
-                          oncommand="var tabbrowser = this.parentNode.parentNode.parentNode.parentNode;
-                                     tabbrowser.reloadTab(tabbrowser.mContextTab);"/>
-            <xul:menuitem id="context_reloadAllTabs" label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;"
-                          tbattr="tabbrowser-multiple"
-                          oncommand="var tabbrowser = this.parentNode.parentNode.parentNode.parentNode;
-                                     tabbrowser.reloadAllTabs(tabbrowser.mContextTab);"/>
-            <xul:menuitem id="context_closeOtherTabs" label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
-                          tbattr="tabbrowser-multiple"
-                          oncommand="var tabbrowser = this.parentNode.parentNode.parentNode.parentNode;
-                                     tabbrowser.removeAllTabsBut(tabbrowser.mContextTab);"/>
-            <xul:menuseparator/>
-            <xul:menuitem id="context_openTabInWindow" label="&openTabInNewWindow.label;"
-                          accesskey="&openTabInNewWindow.accesskey;"
-                          tbattr="tabbrowser-multiple"
-                          oncommand="var tabbrowser = this.parentNode.parentNode.parentNode.parentNode;
-                                     tabbrowser.replaceTabWithWindow(tabbrowser.mContextTab);"/>
-            <xul:menuseparator/>
-            <xul:menuitem id="context_bookmarkTab"
-                          label="&bookmarkThisTab.label;"
-                          accesskey="&bookmarkThisTab.accesskey;"
-                          oncommand="BookmarkThisTab();"/>
-            <xul:menuitem id="context_bookmarkAllTabs"
-                          label="&bookmarkAllTabs.label;"
-                          accesskey="&bookmarkAllTabs.accesskey;"
-                          command="Browser:BookmarkAllTabs"/>
-            <xul:menuitem id="context_undoCloseTab"
-                          label="&undoCloseTab.label;"
-                          accesskey="&undoCloseTab.accesskey;"
-                          command="History:UndoCloseTab"
-                          anonid="undoCloseTabMenuItem"/>
-            <xul:menuseparator/>
-            <xul:menuitem id="context_closeTab" label="&closeTab.label;" accesskey="&closeTab.accesskey;"
-                          tbattr="tabbrowser-multiple"
-                          oncommand="var tabbrowser = this.parentNode.parentNode.parentNode.parentNode;
-                                     tabbrowser.removeTab(tabbrowser.mContextTab);"/>
-          </xul:menupopup>
-
-          <xul:tabs class="tabbrowser-tabs" flex="1"
-                    anonid="tabcontainer"
-                    setfocus="false"
-                    onclick="this.parentNode.parentNode.parentNode.onTabClick(event);"
-                    ondblclick="this.parentNode.parentNode.parentNode.onTabBarDblClick(event);">
-            <xul:tab selected="true" validate="never"
-                     onerror="this.removeAttribute('image');"
-                     maxwidth="250" width="0" minwidth="100" flex="100"
-                     class="tabbrowser-tab" label="&untitledTab;" crop="end"/>
-          </xul:tabs>
-        </xul:hbox>
         <xul:tabpanels flex="1" class="plain" selectedIndex="0" anonid="panelcontainer">
           <xul:notificationbox flex="1">
             <xul:browser flex="1" type="content-primary" message="true" disablehistory="true"
                          xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup"/>
           </xul:notificationbox>
         </xul:tabpanels>
       </xul:tabbox>
       <children/>
@@ -152,37 +89,28 @@
       </field>
       <field name="mFaviconService" readonly="true">
         Components.classes["@mozilla.org/browser/favicon-service;1"]
                   .getService(Components.interfaces.nsIFaviconService);
       </field>
       <field name="mTabBox" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "tabbox");
       </field>
-      <field name="_tabDropIndicator">
-        document.getAnonymousElementByAttribute(this, "anonid", "tab-drop-indicator");
-      </field>
-      <field name="mStrip" readonly="true">
-        document.getAnonymousElementByAttribute(this, "anonid", "strip");
-      </field>
       <field name="mTabContainer" readonly="true">
-        document.getAnonymousElementByAttribute(this, "anonid", "tabcontainer");
+        document.getElementById(this.getAttribute("tabcontainer"));
       </field>
       <field name="mPanelContainer" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "panelcontainer");
       </field>
       <field name="mTabs" readonly="true">
         this.mTabContainer.childNodes
       </field>
       <field name="mStringBundle">
         document.getAnonymousElementByAttribute(this, "anonid", "tbstringbundle");
       </field>
-      <field name="mUndoCloseTabMenuItem">
-        document.getAnonymousElementByAttribute(this, "anonid", "undoCloseTabMenuItem");
-      </field>
       <field name="mCurrentTab">
         null
       </field>
       <field name="_lastRelatedTab">
         null
       </field>
       <field name="mCurrentBrowser">
         null
@@ -200,36 +128,30 @@
         new Array()
       </field>
       <field name="mTabbedMode">
         false
       </field>
       <field name="mIsBusy">
         false
       </field>
-      <field name="mContextTab">
-        null
-      </field>
       <field name="arrowKeysShouldWrap" readonly="true">
 #ifdef XP_MACOSX
         true
 #else
         false
 #endif
       </field>
       <field name="mAddProgressListenerWasCalled">
         false
       </field>
       <field name="_browsers">
         null
       </field>
 
-      <field name="_blockDblClick">
-        false
-      </field>
       <field name="_autoScrollPopup">
         null
       </field>
 
       <field name="_previewMode">
         false
       </field>
 
@@ -848,38 +770,16 @@
       <method name="updateTitlebar">
         <body>
           <![CDATA[
             this.ownerDocument.title = this.getWindowTitleForBrowser(this.mCurrentBrowser);
           ]]>
         </body>
       </method>
 
-      <method name="updatePopupMenu">
-        <parameter name="aPopupMenu"/>
-        <body>
-          <![CDATA[
-            this.mContextTab = document.popupNode.localName == "tab" ?
-                               document.popupNode : this.selectedTab;
-            var disabled = this.mTabs.length == 1;
-            var menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-multiple");
-            for (var i = 0; i < menuItems.length; i++)
-              menuItems[i].disabled = disabled;
-
-            // Session store
-            // XXXzeniko should't we just disable this item as we disable
-            // the tabbrowser-multiple items above - for consistency?
-            this.mUndoCloseTabMenuItem.hidden =
-              Cc["@mozilla.org/browser/sessionstore;1"].
-              getService(Ci.nsISessionStore).
-              getClosedTabCount(window) == 0;
-          ]]>
-        </body>
-      </method>
-
       <method name="updateCurrentBrowser">
         <parameter name="aForceUpdate"/>
         <body>
           <![CDATA[
             var newBrowser = this.getBrowserAtIndex(this.mTabContainer.selectedIndex);
             if (this.mCurrentBrowser == newBrowser && !aForceUpdate)
               return;
 
@@ -1003,32 +903,16 @@
           // This event should be dispatched when any of these attributes change:
           // label, crop, busy, image, selected
           var event = document.createEvent("Events");
           event.initEvent("TabAttrModified", true, false);
           aTab.dispatchEvent(event);
         ]]></body>
       </method>
 
-      <method name="onTabClick">
-        <parameter name="event"/>
-        <body>
-          <![CDATA[
-            if (event.button != 1 || event.target.localName != 'tab')
-              return;
-
-            if (this.mTabs.length > 1 ||
-                !this.mPrefs.getBoolPref("browser.tabs.closeWindowWithLastTab"))
-              this.removeTab(event.target);
-
-            event.stopPropagation();
-          ]]>
-        </body>
-      </method>
-
       <method name="setTabTitleLoading">
         <parameter name="aTab"/>
         <body>
           <![CDATA[
             aTab.label = this.mStringBundle.getString("tabs.loading");
             aTab.setAttribute("crop", "end");
             this._tabAttrModified(aTab);
           ]]>
@@ -1071,46 +955,22 @@
 
             aTab.label = title;
             aTab.setAttribute("crop", crop);
             this._tabAttrModified(aTab);
           ]]>
         </body>
       </method>
 
-      <method name="setStripVisibilityTo">
-        <parameter name="aShow"/>
-        <body>
-        <![CDATA[
-          this.mStrip.collapsed = !aShow;
-          if (aShow) {
-            // XXXdwh temporary unclean dependency on specific menu items in navigator.xul
-            document.getElementById("menu_closeWindow").hidden = false;
-            document.getElementById("menu_close").setAttribute("label", this.mStringBundle.getString("tabs.closeTab"));
-            if (!this.mTabbedMode)
-              this.enterTabbedMode();
-          }
-          else {
-            // XXXdwh temporary unclean dependency on specific menu items in navigator.xul
-            document.getElementById("menu_closeWindow").hidden = true;
-            document.getElementById("menu_close").setAttribute("label", this.mStringBundle.getString("tabs.close"));
-          }
-        ]]>
-        </body>
-      </method>
-
-      <method name="getStripVisibility">
-        <body>
-          return !this.mStrip.collapsed;
-        </body>
-      </method>
-
       <method name="enterTabbedMode">
         <body>
           <![CDATA[
+            if (this.mTabbedMode)
+              return;
+
             this.mTabbedMode = true; // Welcome to multi-tabbed mode.
 
             if (XULBrowserWindow.isBusy) {
               this.mCurrentTab.setAttribute("busy", "true");
               this.mIsBusy = true;
               this.setTabTitleLoading(this.mCurrentTab);
               this.updateIcon(this.mCurrentTab);
             } else {
@@ -1256,18 +1116,17 @@
               aPostData             = params.postData;
               aOwner                = params.ownerTab;
               aAllowThirdPartyFixup = params.allowThirdPartyFixup;
               aRelatedToCurrent     = params.relatedToCurrent;
             }
 
             this._browsers = null; // invalidate cache
 
-            if (!this.mTabbedMode)
-              this.enterTabbedMode();
+            this.enterTabbedMode();
 
             // if we're adding tabs, we're past interrupt mode, ditch the owner
             if (this.mCurrentTab.owner)
               this.mCurrentTab.owner = null;
 
             var t = document.createElementNS(
               "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                              "tab");
@@ -1321,19 +1180,17 @@
             var notificationbox = document.createElementNS(
                                     "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                     "notificationbox");
             notificationbox.setAttribute("flex", "1");
             notificationbox.appendChild(b);
             b.setAttribute("flex", "1");
             this.mPanelContainer.appendChild(notificationbox);
 
-            if (this.mStrip.collapsed &&
-                this.mTabs.length - this._removingTabs.length > 1)
-              this.setStripVisibilityTo(true);
+            this.tabContainer.updateVisibility();
 
             // wire up a progress listener for the new browser object.
             var position = this.mTabContainer.childNodes.length-1;
             var tabListener = this.mTabProgressListener(t, b, blank);
             const filter = Components.classes["@mozilla.org/appshell/component/browser-status-filter;1"]
                                      .createInstance(Components.interfaces.nsIWebProgress);
             filter.addProgressListener(tabListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
             b.webProgress.addProgressListener(filter, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
@@ -1537,25 +1394,21 @@
                   aCloseWindowFastpath &&
                   this._removingTabs.length == 0 &&
                   (this._windowIsClosing = window.closeWindow(true)))
                 return null;
 
               newTab = true;
               l++;
             }
-            if (l == 2) {
-              let autohide = this.mPrefs.getBoolPref("browser.tabs.autoHide");
-              let tabStripHide = !window.toolbar.visible;
-              if (autohide || tabStripHide)
-                this.setStripVisibilityTo(false);
-            }
 
             this._removingTabs.push(aTab);
 
+            this.tabContainer.updateVisibility();
+
             // We're committed to closing the tab now.
             // Dispatch a notification.
             // We dispatch it before any teardown so that event listeners can
             // inspect the tab that's about to close.
             var evt = document.createEvent("UIEvent");
             evt.initUIEvent("TabClose", true, false, window, aTabWillBeMoved ? 1 : 0);
             aTab.dispatchEvent(evt);
 
@@ -1787,42 +1640,27 @@
         <parameter name="aTab"/>
         <body>
           <![CDATA[
             this.getBrowserForTab(aTab).reload();
           ]]>
         </body>
       </method>
 
-      <method name="onTabBarDblClick">
-        <parameter name="aEvent"/>
-        <body>
-          <![CDATA[
-            // See hack note in the tabbrowser-close-button binding
-            if (!this._blockDblClick && aEvent.button == 0 &&
-                aEvent.originalTarget.localName == "box")
-              BrowserOpenTab();
-          ]]>
-        </body>
-      </method>
-
       <method name="addProgressListener">
         <parameter name="aListener"/>
         <parameter name="aMask"/>
         <body>
           <![CDATA[
             if (!this.mAddProgressListenerWasCalled) {
               this.mAddProgressListenerWasCalled = true;
-              var autoHide = this.mPrefs.getBoolPref("browser.tabs.autoHide");
-              var tabStripHide = !window.toolbar.visible;
-              if (!autoHide && !tabStripHide)
-                this.setStripVisibilityTo(true);
+              this.tabContainer.updateVisibility();
             }
 
-            if (!this.mTabbedMode && this.mProgressListeners.length == 1) {
+            if (this.mProgressListeners.length == 1) {
               // If we are adding a 2nd progress listener, we need to enter tabbed mode
               // because the browser status filter can only handle one progress listener.
               // In tabbed mode, mTabProgressListener is used which will iterate over all listeners.
               this.enterTabbedMode();
             }
 
             this.mProgressListeners.push(aListener);
 
@@ -1861,18 +1699,17 @@
               this.mTabFilters[0].removeProgressListener(aListener);
          ]]>
         </body>
       </method>
 
       <method name="addTabsProgressListener">
         <parameter name="aListener"/>
         <body>
-          if (!this.mTabbedMode)
-            this.enterTabbedMode();
+          this.enterTabbedMode();
           this.mTabsProgressListeners.push(aListener);
         </body>
       </method>
 
       <method name="removeTabsProgressListener">
         <parameter name="aListener"/>
         <body>
         <![CDATA[
@@ -1941,354 +1778,16 @@
        <getter>
           <![CDATA[
             return this._browsers ||
                    (this._browsers = Array.map(this.mTabs, function (tab) tab.linkedBrowser));
           ]]>
         </getter>
       </property>
 
-      <method name="_onDragStart">
-        <parameter name="aEvent"/>
-        <body>
-        <![CDATA[
-          var target = aEvent.target;
-          if (target.localName == "tab" &&
-              aEvent.originalTarget.localName != "toolbarbutton") {
-            var dt = aEvent.dataTransfer;
-            dt.mozSetDataAt(TAB_DROP_TYPE, target, 0);
-            var uri = this.getBrowserForTab(aEvent.target).currentURI;
-            var spec = uri ? uri.spec : "about:blank";
-
-            // We must not set text/x-moz-url or text/plain data here,
-            // otherwise trying to deatch the tab by dropping it on the desktop
-            // may result in an "internet shortcut"
-            dt.mozSetDataAt("text/x-moz-text-internal", spec, 0);
-            
-            // Set the cursor to an arrow during tab drags.
-            dt.mozCursor = "default";
-
-            var canvas = tabPreviews.capture(target, false);
-            dt.setDragImage(canvas, 0, 0);
-            aEvent.stopPropagation();
-          }
-
-          this._dragLeftWindow = false;
-        ]]>
-        </body>
-      </method>
-
-      <field name="mDragTime">0</field>
-      <field name="mDragOverDelay">350</field>
-
-      <field name="_supportedLinkDropTypes"><![CDATA[
-        ["text/x-moz-url", "text/uri-list", "text/plain", "application/x-moz-file"]
-      ]]></field>
-
-      <method name="_setEffectAllowedForDataTransfer">
-        <parameter name="aEvent"/>
-        <body>
-          <![CDATA[
-            var dt = aEvent.dataTransfer;
-            // Disallow dropping multiple items
-            if (dt.mozItemCount > 1)
-              return dt.effectAllowed = "none";
-
-            var types = dt.mozTypesAt(0);
-            var sourceNode = null;
-            // tabs are always added as the first type
-            if (types[0] == TAB_DROP_TYPE) {
-              var sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
-              if (sourceNode instanceof XULElement &&
-                  sourceNode.localName == "tab" &&
-                  (sourceNode.parentNode == this.mTabContainer ||
-                   (sourceNode.ownerDocument.defaultView instanceof ChromeWindow &&
-                    sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser"))) {
-                if (sourceNode.parentNode == this.mTabContainer &&
-                    (aEvent.screenX >= sourceNode.boxObject.screenX &&
-                      aEvent.screenX <= (sourceNode.boxObject.screenX +
-                                         sourceNode.boxObject.width))) {
-                  return dt.effectAllowed = "none";
-                }
-
-                return dt.effectAllowed = "copyMove";
-              }
-            }
-
-            for (var i=0; i < this._supportedLinkDropTypes.length; i++) {
-              if (types.contains(this._supportedLinkDropTypes[i])) {
-                // Here we need to to do this manually
-                return dt.effectAllowed = dt.dropEffect = "link";
-              }
-            }
-            return dt.effectAllowed = "none";
-          ]]>
-        </body>
-      </method>
-
-      <method name="_continueScroll">
-        <parameter name="aEvent"/>
-        <body><![CDATA[
-          // Workaround for bug 481904: Dragging a tab stops scrolling at
-          // the tab's position when dragging to the first/last tab and back.
-          var t = this.selectedTab;
-          if (aEvent.screenX >= t.boxObject.screenX &&
-              aEvent.screenX <= t.boxObject.screenX + t.boxObject.width &&
-              aEvent.screenY >= t.boxObject.screenY &&
-              aEvent.screenY <= t.boxObject.screenY + t.boxObject.height)
-            this.tabContainer.mTabstrip.ensureElementIsVisible(t);
-        ]]></body>
-      </method>
-
-      <method name="_onDragOver">
-        <parameter name="aEvent"/>
-        <body>
-          <![CDATA[
-            var effects = this._setEffectAllowedForDataTransfer(aEvent);
-
-            var ind = this._tabDropIndicator;
-            if (effects == "" || effects == "none") {
-              ind.collapsed = true;
-              this._continueScroll(aEvent);
-              return;
-            }
-            aEvent.preventDefault();
-            aEvent.stopPropagation();
-
-            var tabStrip = this.mTabContainer.mTabstrip;
-            var ltr = (window.getComputedStyle(this.parentNode, null).direction
-                       == "ltr");
-
-            // autoscroll the tab strip if we drag over the scroll
-            // buttons, even if we aren't dragging a tab, but then
-            // return to avoid drawing the drop indicator
-            var pixelsToScroll = 0;
-            if (this.mTabContainer.getAttribute("overflow") == "true") {
-              var targetAnonid = aEvent.originalTarget.getAttribute("anonid");
-              switch (targetAnonid) {
-                case "scrollbutton-up":
-                  pixelsToScroll = tabStrip.scrollIncrement * -1;
-                  break;
-                case "scrollbutton-down":
-                case "alltabs-button":
-                case "newtab-button":
-                  pixelsToScroll = tabStrip.scrollIncrement;
-                  break;
-              }
-              if (pixelsToScroll)
-                tabStrip.scrollByPixels((ltr ? 1 : -1) * pixelsToScroll);
-            }
-
-            if (effects == "link" && aEvent.target.localName == "tab") {
-              if (!this.mDragTime) 
-                this.mDragTime = Date.now();
-              if (Date.now() >= this.mDragTime + this.mDragOverDelay)
-                this.mTabContainer.selectedItem = aEvent.target;
-              return;
-            }
-
-            var newIndex = this.getNewIndex(aEvent);
-            var scrollRect = tabStrip.scrollClientRect;
-            var rect = this.getBoundingClientRect();
-            var minMargin = scrollRect.left - rect.left;
-            var maxMargin = Math.min(minMargin + scrollRect.width, 
-                                     scrollRect.right);
-            if (!ltr)
-              [minMargin, maxMargin] = [this.clientWidth - maxMargin,
-                                        this.clientWidth - minMargin];
-            var newMargin;
-            if (pixelsToScroll) {
-              // if we are scrolling, put the drop indicator at the edge
-              // so that it doesn't jump while scrolling
-              newMargin = (pixelsToScroll > 0) ? maxMargin : minMargin;
-            }
-            else {
-              if (newIndex == this.mTabs.length) {
-                let tabRect = this.mTabs[newIndex-1].getBoundingClientRect();
-                if (ltr)
-                  newMargin = tabRect.right - rect.left;
-                else
-                  newMargin = rect.right - tabRect.left;
-              }
-              else {
-                let tabRect = this.mTabs[newIndex].getBoundingClientRect();
-                if (ltr)
-                  newMargin = tabRect.left - rect.left;
-                else
-                  newMargin = rect.right - tabRect.right;
-              }
-              // ensure we never place the drop indicator beyond our limits
-              if (newMargin < minMargin)
-                newMargin = minMargin;
-              else if (newMargin > maxMargin)
-                newMargin = maxMargin;
-            }
-
-            ind.collapsed = false;
- 
-            newMargin += ind.clientWidth / 2;
-            if (!ltr)
-              newMargin *= -1;
-
-            ind.style.MozTransform = "translate(" + Math.round(newMargin) + "px)";
-            ind.style.MozMarginStart = (-ind.clientWidth) + "px";
-            ind.style.marginTop = (-ind.clientHeight) + "px";
-          ]]>
-        </body>
-      </method>
-
-      <method name="_onDrop">
-        <parameter name="aEvent"/>
-        <body>
-          <![CDATA[
-            var dt = aEvent.dataTransfer;
-            var dropEffect = dt.dropEffect;
-            var draggedTab;
-            if (dropEffect != "link") { // copy or move
-              draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
-              // not our drop then
-              if (!draggedTab)
-                return;
-            }
-
-            this._tabDropIndicator.collapsed = true;
-            aEvent.stopPropagation();
-
-            if (draggedTab && (dropEffect == "copy" ||
-                draggedTab.parentNode == this.mTabContainer)) {
-              var newIndex = this.getNewIndex(aEvent);
-              if (dropEffect == "copy") {
-                // copy the dropped tab (wherever it's from)
-                var newTab = this.duplicateTab(draggedTab);
-                this.moveTabTo(newTab, newIndex);
-                if (draggedTab.parentNode != this.mTabContainer || aEvent.shiftKey)
-                  this.selectedTab = newTab;
-              }
-              else {
-                // move the dropped tab
-                if (newIndex > draggedTab._tPos)
-                  newIndex--;
-                this.moveTabTo(draggedTab, newIndex);
-              }
-            }
-            else if (draggedTab) {
-              // swap the dropped tab with a new one we create and then close
-              // it in the other window (making it seem to have moved between
-              // windows)
-              newIndex = this.getNewIndex(aEvent);
-              newTab = this.addTab("about:blank");
-              var newBrowser = this.getBrowserForTab(newTab);
-              // Stop the about:blank load
-              newBrowser.stop();
-              // make sure it has a docshell
-              newBrowser.docShell;
-              
-              this.moveTabTo(newTab, newIndex);
-              
-              this.swapBrowsersAndCloseOther(newTab, draggedTab);
-
-              // We need to set selectedTab after we've done
-              // swapBrowsersAndCloseOther, so that the updateCurrentBrowser
-              // it triggers will correctly update our URL bar.
-              this.selectedTab = newTab;
-            }
-            else {
-              var url;
-              for (var i=0; i < this._supportedLinkDropTypes.length; i++) {
-                let dataType = this._supportedLinkDropTypes[i];
-                // uri-list: for now, support dropping of the first URL
-                // only
-                var isURLList = dataType == "text/uri-list";
-                let urlData = isURLList ?
-                              dt.mozGetDataAt("URL", 0) : dt.mozGetDataAt(dataType, 0);
-                if (urlData) {
-                  url = transferUtils.retrieveURLFromData(urlData, isURLList ? "text/plain" : dataType);
-                  break;
-                }
-              }
-              NS_ASSERT(url, "In the drop event, at least one mime-type should match our supported types");
-
-              // valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
-              // Also disallow dropping javascript: or data: urls--bail out
-              if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
-                  /^\s*(javascript|data):/.test(url))
-                return;
-
-              // XXXmano: temporary fix until dragDropSecurityCheck make the
-              // drag-session an optional paramter
-              var dragService = Cc["@mozilla.org/widget/dragservice;1"].
-                                getService(Ci.nsIDragService);
-              var dragSession = dragService.getCurrentSession();
-              nsDragAndDrop.dragDropSecurityCheck(aEvent, dragSession, url);
-
-              var bgLoad = true;
-              try {
-                bgLoad = this.mPrefs.getBoolPref("browser.tabs.loadInBackground");
-              }
-              catch (e) { }
-
-              if (aEvent.shiftKey)
-                bgLoad = !bgLoad;
-
-              if (document.getBindingParent(aEvent.originalTarget).localName != "tab" || dropEffect == "copy") {
-                // We're adding a new tab.
-                newIndex = this.getNewIndex(aEvent);
-                newTab = this.loadOneTab(getShortcutOrURI(url), {inBackground: bgLoad});
-                this.moveTabTo(newTab, newIndex);
-              }
-              else {
-                // Load in an existing tab.
-                var tab = aEvent.target;
-                try {
-                  this.getBrowserForTab(tab).loadURI(getShortcutOrURI(url));
-                  if (this.mCurrentTab != tab && !bgLoad)
-                    this.selectedTab = tab;
-                } catch(ex) {
-                  // Just ignore invalid urls
-                }
-              }
-            }
-          ]]>
-        </body>
-      </method>
-
-      <method name="_onDragEnd">
-        <parameter name="aEvent"/>
-        <body>
-          <![CDATA[
-            // Note: while this case is correctly handled here, this event
-            // isn't dispatched when the tab is moved within the tabstrip,
-            // see bug 460801.
-
-            // * mozUserCancelled = the user pressed ESC to cancel the drag
-            var dt = aEvent.dataTransfer;
-            if (dt.mozUserCancelled || dt.dropEffect != "none")
-              return;
-
-            // Disable detach within the browser toolbox
-            var eX = aEvent.screenX;
-            var wX = window.screenX;
-            // check if the drop point is horizontally within the window
-            if (eX > wX && eX < (wX + window.outerWidth)) {
-              var bo = this.mTabContainer.mTabstrip.boxObject;
-              // also avoid detaching if the the tab was dropped too close to
-              // the tabbar (half a tab)
-              var endScreenY = bo.screenY + 1.5 * bo.height;
-              var eY = aEvent.screenY;
-              if (eY < endScreenY && eY > window.screenY)
-                return;
-            }
-
-            var draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
-            this.replaceTabWithWindow(draggedTab);
-            aEvent.stopPropagation();
-          ]]>
-        </body>
-      </method>
-
       <!-- Moves a tab to a new browser window, unless it's already the only tab
            in the current window, in which case this will do nothing. -->
       <method name="replaceTabWithWindow">
         <parameter name="aTab"/>
         <body>
           <![CDATA[
             if (this.mTabs.length == 1)
               return null;
@@ -2300,36 +1799,16 @@
                                  getBrowserURL(),
                                  null,
                                  "chrome,dialog=no,all",
                                  aTab);
           ]]>
         </body>
       </method>
 
-      <method name="_onDragLeave">
-        <parameter name="aEvent"/>
-        <body>
-          <![CDATA[
-            this.mDragTime = 0;
-
-            // This does not work at all (see bug 458613)
-            var target = aEvent.relatedTarget;
-            while (target && target != this)
-              target = target.parentNode;
-            if (target)
-              return;
-
-            this._tabDropIndicator.collapsed = true;
-            this._continueScroll(aEvent);
-            aEvent.stopPropagation();
-          ]]>
-        </body>
-      </method>
-
       <method name="moveTabTo">
         <parameter name="aTab"/>
         <parameter name="aIndex"/>
         <body>
         <![CDATA[
           var oldPosition = aTab._tPos;
           if (oldPosition == aIndex)
             return;
@@ -2356,36 +1835,16 @@
 
           var evt = document.createEvent("UIEvents");
           evt.initUIEvent("TabMove", true, false, window, oldPosition);
           aTab.dispatchEvent(evt);
         ]]>
         </body>
       </method>
 
-      <method name="getNewIndex">
-        <parameter name="aEvent"/>
-        <body>
-          <![CDATA[
-            var i;
-            if (window.getComputedStyle(this.parentNode, null).direction == "ltr") {
-              for (i = aEvent.target.localName == "tab" ? aEvent.target._tPos : 0; i < this.mTabs.length; i++)
-                if (aEvent.screenX < this.mTabs[i].boxObject.screenX + this.mTabs[i].boxObject.width / 2) 
-                  return i;
-            } else {
-              for (i = aEvent.target.localName == "tab" ? aEvent.target._tPos : 0; i < this.mTabs.length; i++)
-                if (aEvent.screenX > this.mTabs[i].boxObject.screenX + this.mTabs[i].boxObject.width / 2)
-                  return i;
-            }
-            return this.mTabs.length;
-          ]]>
-        </body>
-      </method>
-
-
       <method name="moveTabForward">
         <body>
           <![CDATA[
             var tabPos = this.mCurrentTab._tPos;
             if (tabPos < this.browsers.length - 1) {
               this.moveTabTo(this.mCurrentTab, tabPos + 1);
               this.mCurrentTab.focus();
             }
@@ -2756,33 +2215,27 @@
                 onset="return this.mCurrentBrowser.userTypedClear = val;"/>
 
       <property name="userTypedValue"
                 onget="return this.mCurrentBrowser.userTypedValue;"
                 onset="return this.mCurrentBrowser.userTypedValue = val;"/>
 
       <method name="createTooltip">
         <parameter name="event"/>
-        <body>
-          <![CDATA[
-            event.stopPropagation();
-            var tn = document.tooltipNode;
-            if (tn.localName != "tab")
-              return false; // Not a tab, so cancel the tooltip
-            if ("mOverCloseButton" in tn && tn.mOverCloseButton) {
-              event.target.setAttribute("label", tn.getAttribute("closetabtext"));
-              return true;
-            }
-            if (tn.hasAttribute("label")) {
-              event.target.setAttribute("label", tn.getAttribute("label"));
-              return true;
-            }
-            return false;
-          ]]>
-        </body>
+        <body><![CDATA[
+          event.stopPropagation();
+          var tab = document.tooltipNode;
+          if (tab.localName != "tab") {
+            event.preventDefault();
+            return;
+          }
+          event.target.setAttribute("label", tab.mOverCloseButton ?
+                                             tab.getAttribute("closetabtext") :
+                                             tab.getAttribute("label"));
+        ]]></body>
       </method>
 
       <method name="handleEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
           switch (aEvent.type) {
             case "keypress":
               this._handleKeyEvent(aEvent);
@@ -2794,19 +2247,19 @@
       <constructor>
         <![CDATA[
           this.mCurrentBrowser = this.mPanelContainer.childNodes[0].firstChild;
           this.mCurrentTab = this.mTabContainer.firstChild;
           document.addEventListener("keypress", this, false);
 
           var uniqueId = "panel" + Date.now();
           this.mPanelContainer.childNodes[0].id = uniqueId;
-          this.mTabContainer.childNodes[0].linkedPanel = uniqueId;
-          this.mTabContainer.childNodes[0]._tPos = 0;
-          this.mTabContainer.childNodes[0].linkedBrowser = this.mPanelContainer.childNodes[0].firstChild;
+          this.mCurrentTab.linkedPanel = uniqueId;
+          this.mCurrentTab._tPos = 0;
+          this.mCurrentTab.linkedBrowser = this.mCurrentBrowser;
 
           // set up the shared autoscroll popup
           this._autoScrollPopup = this.mCurrentBrowser._createAutoScrollPopup();
           this._autoScrollPopup.id = "autoscroller";
           this.appendChild(this._autoScrollPopup);
           this.mCurrentBrowser.setAttribute("autoscrollpopup", this._autoScrollPopup.id);
         ]]>
       </constructor>
@@ -2818,16 +2271,31 @@
             this.mTabFilters[i].removeProgressListener(this.mTabListeners[i]);
             this.mTabFilters[i] = null;
             this.mTabListeners[i].destroy();
             this.mTabListeners[i] = null;
           }
           document.removeEventListener("keypress", this, false);
         ]]>
       </destructor>
+
+      <!-- Deprecated stuff, implemented for backwards compatibility. -->
+      <method name="setStripVisibilityTo">
+        <parameter name="aShow"/>
+        <body>
+          this.tabContainer.visible = aShow;
+        </body>
+      </method>
+      <method name="getStripVisibility">
+        <body>
+          return this.tabContainer.visible;
+        </body>
+      </method>
+      <property name="mContextTab" readonly="true"
+                onget="return this.tabContainer._contextTab;"/>
     </implementation>
 
     <handlers>
       <handler event="DOMWindowClose" phase="capturing">
         <![CDATA[
           if (!event.isTrusted)
             return;
 
@@ -2864,16 +2332,24 @@
           this.setTabTitle(tab);
           if (tab == this.mCurrentTab)
             this.updateTitlebar();
         ]]>
       </handler>
     </handlers>
   </binding>
 
+  <binding id="tabbrowser-tabbox"
+           extends="chrome://global/content/bindings/tabbox.xml#tabbox">
+    <implementation>
+      <property name="tabs" readonly="true"
+                onget="return document.getBindingParent(this).tabContainer;"/>
+    </implementation>
+  </binding>
+
   <binding id="tabbrowser-arrowscrollbox" extends="chrome://global/content/bindings/scrollbox.xml#arrowscrollbox-clicktoscroll">
     <implementation>
       <!-- Override scrollbox.xml method, since our scrollbox's children are
            inherited from the binding parent -->
       <method name="_getScrollableElements">
         <body><![CDATA[
           return document.getBindingParent(this).childNodes;
         ]]></body>
@@ -2896,58 +2372,90 @@
          tabs.setAttribute("overflow", "true");
          this.ensureElementIsVisible(tabs.selectedItem, false);
       ]]></handler>
     </handlers>
   </binding>
 
   <binding id="tabbrowser-tabs"
            extends="chrome://global/content/bindings/tabbox.xml#tabs">
-    <content>
-      <xul:stack flex="1" class="tabs-stack">
-        <xul:vbox>
-          <xul:spacer flex="1"/>
-          <xul:hbox class="tabs-bottom" align="center"/>
-        </xul:vbox>
-        <xul:hbox xbl:inherits="overflow" class="tabs-container">
-#ifdef XP_MACOSX
-          <xul:stack>
-            <xul:spacer class="tabs-left"/>
-          </xul:stack>
+    <resources>
+      <stylesheet src="chrome://browser/content/tabbrowser.css"/>
+    </resources>
+
+    <content context="_child">
+      <xul:hbox align="start">
+        <xul:image class="tab-drop-indicator" anonid="tab-drop-indicator" collapsed="true"/>
+      </xul:hbox>
+      <xul:menupopup anonid="tabContextMenu"
+                     onpopupshowing="if (event.target == this) this.parentNode._updateContextMenu(this);"
+                     onpopuphidden="if (event.target == this) this.parentNode._contextTab = null;">
+        <xul:menuitem id="context_newTab" label="&newTab.label;" accesskey="&newTab.accesskey;"
+                      command="cmd_newNavigatorTab"/>
+        <xul:menuseparator/>
+        <xul:menuitem id="context_reloadTab" label="&reloadTab.label;" accesskey="&reloadTab.accesskey;"
+                      oncommand="this.parentNode.parentNode._contextMenuAction('reloadTab');"/>
+        <xul:menuitem id="context_reloadAllTabs" label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;"
+                      tbattr="tabbrowser-multiple"
+                      oncommand="this.parentNode.parentNode._contextMenuAction('reloadAllTabs');"/>
+        <xul:menuitem id="context_closeOtherTabs" label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
+                      tbattr="tabbrowser-multiple"
+                      oncommand="this.parentNode.parentNode._contextMenuAction('removeAllTabsBut');"/>
+        <xul:menuseparator/>
+        <xul:menuitem id="context_openTabInWindow" label="&openTabInNewWindow.label;"
+                      accesskey="&openTabInNewWindow.accesskey;"
+                      tbattr="tabbrowser-multiple"
+                      oncommand="this.parentNode.parentNode._contextMenuAction('replaceTabWithWindow');"/>
+        <xul:menuseparator/>
+        <xul:menuitem id="context_bookmarkTab"
+                      label="&bookmarkThisTab.label;"
+                      accesskey="&bookmarkThisTab.accesskey;"
+                      oncommand="this.parentNode.parentNode._contextMenuAction('BookmarkThisTab', window);"/>
+        <xul:menuitem id="context_bookmarkAllTabs"
+                      label="&bookmarkAllTabs.label;"
+                      accesskey="&bookmarkAllTabs.accesskey;"
+                      command="Browser:BookmarkAllTabs"/>
+        <xul:menuitem id="context_undoCloseTab"
+                      label="&undoCloseTab.label;"
+                      accesskey="&undoCloseTab.accesskey;"
+                      command="History:UndoCloseTab"/>
+        <xul:menuseparator/>
+        <xul:menuitem id="context_closeTab" label="&closeTab.label;" accesskey="&closeTab.accesskey;"
+                      tbattr="tabbrowser-multiple"
+                      oncommand="this.parentNode.parentNode._contextMenuAction('removeTab');"/>
+      </xul:menupopup>
+      <xul:arrowscrollbox anonid="arrowscrollbox" orient="horizontal" flex="1"
+                          style="min-width: 1px;"
+#ifndef XP_MACOSX
+                          clicktoscroll="true"
 #endif
-          <xul:arrowscrollbox anonid="arrowscrollbox" orient="horizontal" flex="1"
-                              style="min-width: 1px;"
-#ifndef XP_MACOSX
-                              clicktoscroll="true"
-#endif
-                              class="tabbrowser-arrowscrollbox">
+                          class="tabbrowser-arrowscrollbox">
 # This is a hack to circumvent bug 472020, otherwise the tabs show up on the
 # right of the newtab button.
-            <children includes="tab"/>
+        <children includes="tab"/>
 # This is to ensure anything extensions put here will go before the newtab
 # button, necessary due to the previous hack.
-            <children/>
-            <xul:toolbarbutton class="tabs-newtab-button"
-                               command="cmd_newNavigatorTab"
-                               tooltiptext="&newTabButton.tooltip;"/>
-          </xul:arrowscrollbox>
-          <xul:toolbarbutton class="tabs-newtab-button" anonid="newtab-button"
-                             command="cmd_newNavigatorTab"
-                             tooltiptext="&newTabButton.tooltip;"/>
-          <xul:toolbarbutton class="tabs-alltabs-button" anonid="alltabs-button"
-                             type="menu"
-                             tooltiptext="&listAllTabs.label;">
-            <xul:menupopup class="tabs-alltabs-popup" anonid="alltabs-popup"
-                           position="after_end"/>
-          </xul:toolbarbutton>
-          <xul:toolbarbutton anonid="tabs-closebutton"
-                             class="close-button tabs-closebutton"/>
-        </xul:hbox>
-      </xul:stack>
+        <children/>
+        <xul:toolbarbutton class="tabs-newtab-button"
+                           command="cmd_newNavigatorTab"
+                           tooltiptext="&newTabButton.tooltip;"/>
+      </xul:arrowscrollbox>
+      <xul:toolbarbutton class="tabs-newtab-button" anonid="newtab-button"
+                         command="cmd_newNavigatorTab"
+                         tooltiptext="&newTabButton.tooltip;"/>
+      <xul:toolbarbutton class="tabs-alltabs-button" anonid="alltabs-button"
+                         type="menu"
+                         tooltiptext="&listAllTabs.label;">
+        <xul:menupopup class="tabs-alltabs-popup" anonid="alltabs-popup"
+                       position="after_end"/>
+      </xul:toolbarbutton>
+      <xul:toolbarbutton anonid="tabs-closebutton"
+                         class="close-button tabs-closebutton"/>
     </content>
+
     <implementation implements="nsIDOMEventListener">
       <constructor>
         <![CDATA[
           var pb2 =
               Components.classes['@mozilla.org/preferences-service;1'].
               getService(Components.interfaces.nsIPrefBranch2);
 
           try {
@@ -2962,75 +2470,125 @@
             this.mTabClipWidth = pb2.getIntPref("browser.tabs.tabClipWidth");
           } catch (e) {
           }
           try {
             this.mCloseButtons = pb2.getIntPref("browser.tabs.closeButtons");
           } catch (e) {
           }
 
-          this.firstChild.minWidth = this.mTabMinWidth;
-          this.firstChild.maxWidth = this.mTabMaxWidth;
+          var tab = this.firstChild;
+          tab.setAttribute("label",
+                           this.tabbrowser.mStringBundle.getString("tabs.untitled"));
+          tab.minWidth = this.mTabMinWidth;
+          tab.maxWidth = this.mTabMaxWidth;
+          tab.width = 0;
+          tab.setAttribute("flex", "100");
+          tab.setAttribute("crop", "end");
+          tab.setAttribute("validate", "never");
+          tab.setAttribute("onerror", "this.removeAttribute('image');");
           this.adjustTabstrip();
 
-          pb2.addObserver("browser.tabs.closeButtons", 
-                          this._prefObserver, false);
+          pb2.addObserver("browser.tabs.closeButtons", this._prefObserver, false);
+          pb2.addObserver("browser.tabs.autoHide", this._prefObserver, false);
 
           window.addEventListener("resize", this, false);
         ]]>
       </constructor>
 
       <destructor>
         <![CDATA[
           var pb2 =
               Components.classes['@mozilla.org/preferences-service;1'].
               getService(Components.interfaces.nsIPrefBranch2);
           pb2.removeObserver("browser.tabs.closeButtons", this._prefObserver);
+          pb2.removeObserver("browser.tabs.autoHide", this._prefObserver);
         ]]>
       </destructor>
 
+      <field name="tabbrowser" readonly="true">
+        document.getElementById(this.getAttribute("tabbrowser"));
+      </field>
+
+      <field name="tabbox" readonly="true">
+        this.tabbrowser.mTabBox;
+      </field>
+
       <field name="mTabstripWidth">0</field>
 
       <field name="mTabstrip">
         document.getAnonymousElementByAttribute(this, "anonid", "arrowscrollbox");
       </field>
 
       <field name="mTabstripClosebutton">
         document.getAnonymousElementByAttribute(this, "anonid", "tabs-closebutton");
       </field>
 
-      <field name="_prefObserver">({
-        tabbox: this,
-  
-        observe: function(subject, topic, data)
-        {
-          if (topic == "nsPref:changed") {
-            switch (data) {
+      <field name="_prefObserver"><![CDATA[({
+        tabContainer: this,
+
+        observe: function (subject, topic, data) {
+          switch (data) {
             case "browser.tabs.closeButtons":
               subject.QueryInterface(Components.interfaces.nsIPrefBranch);
-              this.tabbox.mCloseButtons = subject.getIntPref("browser.tabs.closeButtons");
-              this.tabbox.adjustTabstrip();
+              this.tabContainer.mCloseButtons = subject.getIntPref("browser.tabs.closeButtons");
+              this.tabContainer.adjustTabstrip();
               break;
-            }
+            case "browser.tabs.autoHide":
+              this.tabContainer.updateVisibility();
+              break;
           }
-        },
-  
-        QueryInterface: function(aIID)
-        {
-          if (aIID.equals(Components.interfaces.nsIObserver) ||
-              aIID.equals(Components.interfaces.nsISupports))
-            return this;
-          throw Components.results.NS_NOINTERFACE;
         }
-        });
-      </field>
+      });]]></field>
       <field name="mTabMinWidth">100</field>
       <field name="mTabMaxWidth">250</field>
       <field name="mTabClipWidth">140</field>
       <field name="mCloseButtons">1</field>
+      <field name="_blockDblClick">false</field>
+
+      <field name="_tabDropIndicator">
+        document.getAnonymousElementByAttribute(this, "anonid", "tab-drop-indicator");
+      </field>
+
+      <field name="_dragOverDelay">350</field>
+      <field name="_dragTime">0</field>
+
+      <field name="_supportedLinkDropTypes"><![CDATA[
+        ["text/x-moz-url", "text/uri-list", "text/plain", "application/x-moz-file"]
+      ]]></field>
+
+      <field name="_container" readonly="true"><![CDATA[
+        this.parentNode && this.parentNode.localName == "toolbar" ? this.parentNode : this;
+      ]]></field>
+
+      <property name="visible"
+                onget="return !this._container.collapsed;">
+        <setter><![CDATA[
+          this._container.collapsed = !val;
+
+          if (val)
+            this.tabbrowser.enterTabbedMode();
+
+          document.getElementById("menu_closeWindow").hidden = !val;
+          document.getElementById("menu_close").setAttribute("label",
+            this.tabbrowser.mStringBundle.getString(val ? "tabs.closeTab" : "tabs.close"));
+
+          return val;
+        ]]></setter>
+      </property>
+
+      <method name="updateVisibility">
+        <body><![CDATA[
+          if (this.childNodes.length - this.tabbrowser._removingTabs.length == 1 &&
+              window.toolbar.visible)
+            this.visible = !Services.prefs.getBoolPref("browser.tabs.autoHide");
+          else
+            this.visible = true;
+        ]]></body>
+      </method>
 
       <method name="adjustTabstrip">
         <body><![CDATA[
           // modes for tabstrip
           // 0 - activetab  = close button on active tab only
           // 1 - alltabs    = close buttons on all tabs
           // 2 - noclose    = no close buttons at all
           // 3 - closeatend = close button at the end of the tabstrip
@@ -3142,98 +2700,505 @@
           if (!this._animateElement.hasAttribute("notifybgtab")) {
             this._animateElement.setAttribute("notifybgtab", "true");
             setTimeout(function (ele) {
               ele.removeAttribute("notifybgtab");
             }, 150, this._animateElement);
           }
         ]]></body>
       </method>
+
+      <field name="_contextTab">null</field>
+      <method name="_updateContextMenu">
+        <parameter name="aPopupMenu"/>
+        <body><![CDATA[
+          this._contextTab = document.popupNode.localName == "tab" ?
+                             document.popupNode : this.selectedItem;
+          var disabled = this.childNodes.length == 1;
+          var menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-multiple");
+          for (var i = 0; i < menuItems.length; i++)
+            menuItems[i].disabled = disabled;
+
+          // Session store
+          // XXXzeniko should't we just disable this item as we disable
+          // the tabbrowser-multiple items above - for consistency?
+          document.getElementById("context_undoCloseTab").hidden =
+            Cc["@mozilla.org/browser/sessionstore;1"].
+            getService(Ci.nsISessionStore).
+            getClosedTabCount(window) == 0;
+        ]]></body>
+      </method>
+
+      <method name="_contextMenuAction">
+        <parameter name="aMethod"/>
+        <parameter name="aContext"/>
+        <body><![CDATA[
+          (aContext || this.tabbrowser)[aMethod](this._contextTab);
+        ]]></body>
+      </method>
+
+      <method name="_getDragTargetTab">
+        <parameter name="event"/>
+        <body><![CDATA[
+          var node = event.originalTarget;
+          if (node.localName == "tab")
+            return node;
+
+          node = document.getBindingParent(node);
+          if (node.localName == "tab")
+            return node;
+
+          return null;
+        ]]></body>
+      </method>
+
+      <method name="_getDropIndex">
+        <parameter name="event"/>
+        <body><![CDATA[
+          var tabs = this.childNodes;
+          var tab = this._getDragTargetTab(event);
+          if (window.getComputedStyle(this, null).direction == "ltr") {
+            for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
+              if (event.screenX < tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2) 
+                return i;
+          } else {
+            for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
+              if (event.screenX > tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2)
+                return i;
+          }
+          return tabs.length;
+        ]]></body>
+      </method>
+
+      <method name="_setEffectAllowedForDataTransfer">
+        <parameter name="event"/>
+        <body><![CDATA[
+          var dt = event.dataTransfer;
+          // Disallow dropping multiple items
+          if (dt.mozItemCount > 1)
+            return dt.effectAllowed = "none";
+
+          var types = dt.mozTypesAt(0);
+          var sourceNode = null;
+          // tabs are always added as the first type
+          if (types[0] == TAB_DROP_TYPE) {
+            var sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
+            if (sourceNode instanceof XULElement &&
+                sourceNode.localName == "tab" &&
+                (sourceNode.parentNode == this ||
+                 (sourceNode.ownerDocument.defaultView instanceof ChromeWindow &&
+                  sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser"))) {
+              if (sourceNode.parentNode == this &&
+                  (event.screenX >= sourceNode.boxObject.screenX &&
+                    event.screenX <= (sourceNode.boxObject.screenX +
+                                       sourceNode.boxObject.width))) {
+                return dt.effectAllowed = "none";
+              }
+
+              return dt.effectAllowed = "copyMove";
+            }
+          }
+
+          for (let i = 0; i < this._supportedLinkDropTypes.length; i++) {
+            if (types.contains(this._supportedLinkDropTypes[i])) {
+              // Here we need to to do this manually
+              return dt.effectAllowed = dt.dropEffect = "link";
+            }
+          }
+          return dt.effectAllowed = "none";
+        ]]></body>
+      </method>
+
+      <method name="_continueScroll">
+        <parameter name="event"/>
+        <body><![CDATA[
+          // Workaround for bug 481904: Dragging a tab stops scrolling at
+          // the tab's position when dragging to the first/last tab and back.
+          var t = this.selectedItem;
+          if (event.screenX >= t.boxObject.screenX &&
+              event.screenX <= t.boxObject.screenX + t.boxObject.width &&
+              event.screenY >= t.boxObject.screenY &&
+              event.screenY <= t.boxObject.screenY + t.boxObject.height)
+            this.mTabstrip.ensureElementIsVisible(t);
+        ]]></body>
+      </method>
     </implementation>
+
     <handlers>
       <handler event="TabSelect" action="this._handleTabSelect();"/>
+
+      <handler event="dblclick"><![CDATA[
+        // See hack note in the tabbrowser-close-button binding
+        if (!this._blockDblClick && event.button == 0 &&
+            event.originalTarget.localName == "box")
+          BrowserOpenTab();
+      ]]></handler>
+
+      <handler event="click"><![CDATA[
+        if (event.button != 1 || event.target.localName != "tab")
+          return;
+
+        if (this.childNodes.length > 1 ||
+            !Services.prefs.getBoolPref("browser.tabs.closeWindowWithLastTab"))
+          this.tabbrowser.removeTab(event.target);
+
+        event.stopPropagation();
+      ]]></handler>
+
+      <handler event="dragstart"><![CDATA[
+        var tab = this._getDragTargetTab(event);
+        if (!tab)
+          return;
+
+        let dt = event.dataTransfer;
+        dt.mozSetDataAt(TAB_DROP_TYPE, tab, 0);
+        let uri = this.tabbrowser.getBrowserForTab(tab).currentURI;
+        let spec = uri ? uri.spec : "about:blank";
+
+        // We must not set text/x-moz-url or text/plain data here,
+        // otherwise trying to deatch the tab by dropping it on the desktop
+        // may result in an "internet shortcut"
+        dt.mozSetDataAt("text/x-moz-text-internal", spec, 0);
+        
+        // Set the cursor to an arrow during tab drags.
+        dt.mozCursor = "default";
+
+        let canvas = tabPreviews.capture(tab, false);
+        dt.setDragImage(canvas, 0, 0);
+        event.stopPropagation();
+      ]]></handler>
+
+      <handler event="dragover"><![CDATA[
+        var effects = this._setEffectAllowedForDataTransfer(event);
+
+        var ind = this._tabDropIndicator;
+        if (effects == "" || effects == "none") {
+          ind.collapsed = true;
+          this._continueScroll(event);
+          return;
+        }
+        event.preventDefault();
+        event.stopPropagation();
+
+        var tabStrip = this.mTabstrip;
+        var ltr = (window.getComputedStyle(this, null).direction == "ltr");
+
+        // autoscroll the tab strip if we drag over the scroll
+        // buttons, even if we aren't dragging a tab, but then
+        // return to avoid drawing the drop indicator
+        var pixelsToScroll = 0;
+        if (this.getAttribute("overflow") == "true") {
+          var targetAnonid = event.originalTarget.getAttribute("anonid");
+          switch (targetAnonid) {
+            case "scrollbutton-up":
+              pixelsToScroll = tabStrip.scrollIncrement * -1;
+              break;
+            case "scrollbutton-down":
+            case "alltabs-button":
+            case "newtab-button":
+              pixelsToScroll = tabStrip.scrollIncrement;
+              break;
+          }
+          if (pixelsToScroll)
+            tabStrip.scrollByPixels((ltr ? 1 : -1) * pixelsToScroll);
+        }
+
+        if (effects == "link") {
+          let tab = this._getDragTargetTab(event);
+          if (tab) {
+            if (!this._dragTime)
+              this._dragTime = Date.now();
+            if (Date.now() >= this._dragTime + this._dragOverDelay)
+              this.selectedItem = tab;
+            return;
+          }
+        }
+
+        var newIndex = this._getDropIndex(event);
+        var scrollRect = tabStrip.scrollClientRect;
+        var rect = this.getBoundingClientRect();
+        var minMargin = scrollRect.left - rect.left;
+        var maxMargin = Math.min(minMargin + scrollRect.width, 
+                                 scrollRect.right);
+        if (!ltr)
+          [minMargin, maxMargin] = [this.clientWidth - maxMargin,
+                                    this.clientWidth - minMargin];
+        var newMargin;
+        if (pixelsToScroll) {
+          // if we are scrolling, put the drop indicator at the edge
+          // so that it doesn't jump while scrolling
+          newMargin = (pixelsToScroll > 0) ? maxMargin : minMargin;
+        }
+        else {
+          if (newIndex == this.childNodes.length) {
+            let tabRect = this.childNodes[newIndex-1].getBoundingClientRect();
+            if (ltr)
+              newMargin = tabRect.right - rect.left;
+            else
+              newMargin = rect.right - tabRect.left;
+          }
+          else {
+            let tabRect = this.childNodes[newIndex].getBoundingClientRect();
+            if (ltr)
+              newMargin = tabRect.left - rect.left;
+            else
+              newMargin = rect.right - tabRect.right;
+          }
+          // ensure we never place the drop indicator beyond our limits
+          if (newMargin < minMargin)
+            newMargin = minMargin;
+          else if (newMargin > maxMargin)
+            newMargin = maxMargin;
+        }
+
+        ind.collapsed = false;
+
+        newMargin += ind.clientWidth / 2;
+        if (!ltr)
+          newMargin *= -1;
+
+        ind.style.MozTransform = "translate(" + Math.round(newMargin) + "px)";
+        ind.style.MozMarginStart = (-ind.clientWidth) + "px";
+        ind.style.marginTop = (-ind.clientHeight) + "px";
+      ]]></handler>
+
+      <handler event="drop"><![CDATA[
+        var dt = event.dataTransfer;
+        var dropEffect = dt.dropEffect;
+        var draggedTab;
+        if (dropEffect != "link") { // copy or move
+          draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
+          // not our drop then
+          if (!draggedTab)
+            return;
+        }
+
+        this._tabDropIndicator.collapsed = true;
+        event.stopPropagation();
+
+        if (draggedTab && (dropEffect == "copy" ||
+            draggedTab.parentNode == this)) {
+          let newIndex = this._getDropIndex(event);
+          if (dropEffect == "copy") {
+            // copy the dropped tab (wherever it's from)
+            let newTab = this.tabbrowser.duplicateTab(draggedTab);
+            this.tabbrowser.moveTabTo(newTab, newIndex);
+            if (draggedTab.parentNode != this || event.shiftKey)
+              this.selectedItem = newTab;
+          } else {
+            // move the dropped tab
+            if (newIndex > draggedTab._tPos)
+              newIndex--;
+            this.tabbrowser.moveTabTo(draggedTab, newIndex);
+          }
+        } else if (draggedTab) {
+          // swap the dropped tab with a new one we create and then close
+          // it in the other window (making it seem to have moved between
+          // windows)
+          let newIndex = this._getDropIndex(event);
+          let newTab = this.tabbrowser.addTab("about:blank");
+          let newBrowser = this.tabbrowser.getBrowserForTab(newTab);
+          // Stop the about:blank load
+          newBrowser.stop();
+          // make sure it has a docshell
+          newBrowser.docShell;
+
+          this.tabbrowser.moveTabTo(newTab, newIndex);
+
+          this.tabbrowser.swapBrowsersAndCloseOther(newTab, draggedTab);
+
+          // We need to select the tab after we've done
+          // swapBrowsersAndCloseOther, so that the updateCurrentBrowser
+          // it triggers will correctly update our URL bar.
+          this.tabbrowser.selectedTab = newTab;
+        } else {
+          let url;
+          for (let i = 0; i < this._supportedLinkDropTypes.length; i++) {
+            let dataType = this._supportedLinkDropTypes[i];
+            // uri-list: for now, support dropping of the first URL
+            // only
+            let isURLList = dataType == "text/uri-list";
+            let urlData = isURLList ?
+                          dt.mozGetDataAt("URL", 0) : dt.mozGetDataAt(dataType, 0);
+            if (urlData) {
+              url = transferUtils.retrieveURLFromData(urlData, isURLList ? "text/plain" : dataType);
+              break;
+            }
+          }
+          NS_ASSERT(url, "In the drop event, at least one mime-type should match our supported types");
+
+          // valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
+          // Also disallow dropping javascript: or data: urls--bail out
+          if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
+              /^\s*(javascript|data):/.test(url))
+            return;
+
+          // XXXmano: temporary fix until dragDropSecurityCheck make the
+          // drag-session an optional paramter
+          let dragService = Cc["@mozilla.org/widget/dragservice;1"].
+                            getService(Ci.nsIDragService);
+          let dragSession = dragService.getCurrentSession();
+          nsDragAndDrop.dragDropSecurityCheck(event, dragSession, url);
+
+          let bgLoad = true;
+          try {
+            bgLoad = Services.prefs.getBoolPref("browser.tabs.loadInBackground");
+          }
+          catch (e) { }
+
+          if (event.shiftKey)
+            bgLoad = !bgLoad;
+
+          let tab = this._getDragTargetTab(event);
+          if (!tab || dropEffect == "copy") {
+            // We're adding a new tab.
+            let newIndex = this._getDropIndex(event);
+            let newTab = this.tabbrowser.loadOneTab(getShortcutOrURI(url), {inBackground: bgLoad});
+            this.tabbrowser.moveTabTo(newTab, newIndex);
+          } else {
+            // Load in an existing tab.
+            try {
+              this.tabbrowser.getBrowserForTab(tab).loadURI(getShortcutOrURI(url));
+              if (!bgLoad)
+                this.selectedItem = tab;
+            } catch(ex) {
+              // Just ignore invalid urls
+            }
+          }
+        }
+      ]]></handler>
+
+      <handler event="dragend"><![CDATA[
+        // Note: while this case is correctly handled here, this event
+        // isn't dispatched when the tab is moved within the tabstrip,
+        // see bug 460801.
+
+        // * mozUserCancelled = the user pressed ESC to cancel the drag
+        var dt = event.dataTransfer;
+        if (dt.mozUserCancelled || dt.dropEffect != "none")
+          return;
+
+        // Disable detach within the browser toolbox
+        var eX = event.screenX;
+        var wX = window.screenX;
+        // check if the drop point is horizontally within the window
+        if (eX > wX && eX < (wX + window.outerWidth)) {
+          let bo = this.mTabstrip.boxObject;
+          // also avoid detaching if the the tab was dropped too close to
+          // the tabbar (half a tab)
+          let endScreenY = bo.screenY + 1.5 * bo.height;
+          let eY = event.screenY;
+          if (eY < endScreenY && eY > window.screenY)
+            return;
+        }
+
+        var draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
+        this.tabbrowser.replaceTabWithWindow(draggedTab);
+        event.stopPropagation();
+      ]]></handler>
+
+      <handler event="dragleave"><![CDATA[
+        this._dragTime = 0;
+
+        // This does not work at all (see bug 458613)
+        var target = event.relatedTarget;
+        while (target && target != this)
+          target = target.parentNode;
+        if (target)
+          return;
+
+        this._tabDropIndicator.collapsed = true;
+        this._continueScroll(event);
+        event.stopPropagation();
+      ]]></handler>
     </handlers>
   </binding>
 
   <!-- close-tab-button binding
        This binding relies on the structure of the tabbrowser binding.
        Therefore it should only be used as a child of the tab or the tabs
        element (in both cases, when they are anonymous nodes of <tabbrowser>).
-       This binding is exposed as a pseudo-public-API so themes can customize
-       the tabbar appearance without having to be scriptable
-       (see globalBindings.xml in Pinstripe for example).
   -->
   <binding id="tabbrowser-close-tab-button"
            extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image">
     <handlers>
       <handler event="click" button="0"><![CDATA[
         var bindingParent = document.getBindingParent(this);
-        if (bindingParent) {
-          var tabbedBrowser = document.getBindingParent(bindingParent);
-          if (bindingParent.localName == "tab") {
-            /* The only sequence in which a second click event (i.e. dblclik)
-             * can be dispatched on an in-tab close button is when it is shown
-             * after the first click (i.e. the first click event was dispatched
-             * on the tab). This happens when we show the close button only on
-             * the active tab. (bug 352021)
-             * The only sequence in which a third click event can be dispatched
-             * on an in-tab close button is when the tab was opened with a
-             * double click on the tabbar. (bug 378344)
-             * In both cases, it is most likely that the close button area has
-             * been accidentally clicked, therefore we do not close the tab.
-             *
-             * We don't want to ignore processing of more than one click event,
-             * though, since the user might actually be repeatedly clicking to
-             * close many tabs at once.
-             */
-            if (event.detail > 1 && !this._ignoredClick) {
-              this._ignoredClick = true;
+
+        if (bindingParent.localName == "tab") {
+          let tabContainer = bindingParent.parentNode;
+          /* The only sequence in which a second click event (i.e. dblclik)
+           * can be dispatched on an in-tab close button is when it is shown
+           * after the first click (i.e. the first click event was dispatched
+           * on the tab). This happens when we show the close button only on
+           * the active tab. (bug 352021)
+           * The only sequence in which a third click event can be dispatched
+           * on an in-tab close button is when the tab was opened with a
+           * double click on the tabbar. (bug 378344)
+           * In both cases, it is most likely that the close button area has
+           * been accidentally clicked, therefore we do not close the tab.
+           *
+           * We don't want to ignore processing of more than one click event,
+           * though, since the user might actually be repeatedly clicking to
+           * close many tabs at once.
+           */
+          if (event.detail > 1 && !this._ignoredClick) {
+            this._ignoredClick = true;
+            return;
+          }
+
+          // Reset the "ignored click" flag
+          this._ignoredClick = false;
+
+          tabContainer.tabbrowser.removeTab(bindingParent);
+          this._blockDblClick = true;
+
+          /* XXXmano hack (see bug 343628):
+           * Since we're removing the event target, if the user
+           * double-clicks this button, the dblclick event will be dispatched
+           * with the tabbar as its event target (and explicit/originalTarget),
+           * which treats that as a mouse gesture for opening a new tab.
+           * In this context, we're manually blocking the dblclick event
+           * (see dblclick handler).
+           */
+          let self = this;
+          let clickedOnce = false;
+          function enableDblClick(event) {
+            if (event.detail == 1 && !clickedOnce) {
+              clickedOnce = true;
               return;
             }
-
-            // Reset the "ignored click" flag
-            this._ignoredClick = false;
-
-            tabbedBrowser.removeTab(bindingParent);
-            tabbedBrowser._blockDblClick = true;
-
-            /* XXXmano hack (see bug 343628):
-             * Since we're removing the event target, if the user
-             * double-clicks this button, the dblclick event will be dispatched
-             * with the tabbar as its event target (and explicit/originalTarget),
-             * which treats that as a mouse gesture for opening a new tab.
-             * In this context, we're manually blocking the dblclick event
-             * (see onTabBarDblClick).
-             */
-            var clickedOnce = false;
-            function enableDblClick(event) {
-              if (event.detail == 1 && !clickedOnce) {
-                clickedOnce = true;
-                return;
-              }
-              setTimeout(function() {
-                tabbedBrowser._blockDblClick = false;
-              }, 0);
-              tabbedBrowser.removeEventListener("click", enableDblClick, false);
-            }
-            tabbedBrowser.addEventListener("click", enableDblClick, false);
+            setTimeout(function() {
+              self._blockDblClick = false;
+            }, 0);
+            tabContainer.removeEventListener("click", enableDblClick, false);
           }
-          else // "tabs"
-            tabbedBrowser.removeCurrentTab();
+          tabContainer.addEventListener("click", enableDblClick, false);
         }
+        else // "tabs"
+          bindingParent.tabbrowser.removeCurrentTab();
       ]]></handler>
+
       <handler event="dblclick" button="0" phase="capturing">
         // for the one-close-button case
         event.stopPropagation();
       </handler>
+
+      <handler event="dragstart">
+        event.stopPropagation();
+      </handler>
     </handlers>
   </binding>
 
   <binding id="tabbrowser-tab" display="xul:hbox"
            extends="chrome://global/content/bindings/tabbox.xml#tab">
+    <resources>
+      <stylesheet src="chrome://browser/content/tabbrowser.css"/>
+    </resources>
+
     <content closetabtext="&closeTab.label;">
       <xul:image xbl:inherits="validate,src=image"
                  class="tab-icon-image"
                  role="presentation"/>
       <xul:label flex="1"
                  xbl:inherits="value=label,crop,accesskey"
                  class="tab-text"
                  role="presentation"/>
--- a/browser/fuel/src/fuelApplication.js
+++ b/browser/fuel/src/fuelApplication.js
@@ -118,17 +118,17 @@ Window.prototype = {
   },
 
   /*
    * Helper used to setup event handlers on the XBL element. Note that the events
    * are actually dispatched to tabs, so we capture them.
    */
   _watch : function win_watch(aType) {
     var self = this;
-    this._tabbrowser.addEventListener(aType,
+    this._tabbrowser.tabContainer.addEventListener(aType,
       this._cleanup[aType] = function(e){ self._event(e); },
       true);
   },
 
   /*
    * Helper event callback used to redirect events made on the XBL element
    */
   _event : function win_event(aEvent) {
--- a/browser/locales/en-US/chrome/browser/tabbrowser.dtd
+++ b/browser/locales/en-US/chrome/browser/tabbrowser.dtd
@@ -1,9 +1,8 @@
-<!ENTITY  untitledTab            "(Untitled)">
 <!ENTITY  newTab.label           "New Tab">
 <!ENTITY  newTab.accesskey       "N">
 <!ENTITY  closeTab.label         "Close Tab">
 <!ENTITY  closeTab.accesskey         "c">
 <!ENTITY  closeOtherTabs.accesskey  "o">
 <!ENTITY  closeOtherTabs.label   "Close Other Tabs">
 <!ENTITY  reloadAllTabs.label    "Reload All Tabs">
 <!ENTITY  reloadAllTabs.accesskey         "A">
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -1100,16 +1100,23 @@ statusbarpanel#statusbar-display {
 }
 
 #navigator-throbber,
 #wrapper-navigator-throbber > #navigator-throbber {
   list-style-image: url("chrome://global/skin/icons/notloading_16.png");
 }
 
 /* Tabs */
+#TabsToolbar {
+  -moz-appearance: none;
+  min-height: 0;
+  padding: 0;
+  -moz-box-shadow: ThreeDShadow 0 -1px inset;
+}
+
 .tabbrowser-tab {
   border: none !important;
   padding: 0px;
   margin-bottom: 1px;
 }
 
 .tabbrowser-tab[selected="true"] {
   margin-bottom: 0px;
@@ -1151,20 +1158,16 @@ statusbarpanel#statusbar-display {
 }
 .tabbrowser-tab[busy][progress="7"] > .tab-icon-image {
   -moz-image-region: rect(0, 128px, 16px, 112px);
 }
 .tabbrowser-tab[busy][progress="8"] > .tab-icon-image {
   -moz-image-region: rect(0, 144px, 16px, 128px);
 }
 
-.tabs-bottom {
-  border-bottom: 1px solid threedshadow;
-}
-
 #context_newTab {
   list-style-image: url("chrome://browser/skin/Toolbar-small.png");
   -moz-image-region: rect(0px 64px 16px 48px);
 }
 
 #context_newTab[disabled] {
   -moz-image-region: rect(16px 64px 32px 48px);
 }
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -62,21 +62,16 @@
 #nav-bar:-moz-lwtheme {
   -moz-appearance: none !important;
   background: none !important;
   /* Switching to a lightweight theme shouldn't move the content area,
      so avoid changing border widths here. */
   border-color: transparent !important;
 }
 
-.tabbrowser-strip:-moz-lwtheme,
-.tabbrowser-tabs:-moz-lwtheme {
-  background: none !important;
-}
-
 .tabbrowser-tab:-moz-lwtheme[selected="true"] {
   background-color: transparent !important;
 }
 .tabbrowser-tab:-moz-lwtheme:not([selected="true"]):not(:hover) > .tab-text {
   opacity: .8;
 }
 
 .tabbrowser-arrowscrollbox:-moz-lwtheme > .tabs-newtab-button {
@@ -96,26 +91,26 @@
 .tabbrowser-tab:-moz-lwtheme-brighttext[selected="true"] {
   -moz-border-left-colors: rgba(255,255,255,.6) rgba(255,255,255,.2);
   -moz-border-bottom-colors: rgba(255,255,255,.6) rgba(255,255,255,.2);
   -moz-border-right-colors: rgba(255,255,255,.6) rgba(255,255,255,.2);
 }
 
 .tabs-newtab-button:-moz-lwtheme-darktext,
 .tabs-alltabs-button:-moz-lwtheme-darktext,
-.tabs-container:-moz-lwtheme-darktext > .tabs-closebutton,
+.tabbrowser-tabs:-moz-lwtheme-darktext > .tabs-closebutton,
 .tabbrowser-arrowscrollbox:-moz-lwtheme-darktext > .scrollbutton-up,
 .tabbrowser-arrowscrollbox:-moz-lwtheme-darktext > .scrollbutton-down,
 .tabbrowser-tab:-moz-lwtheme-darktext:not([selected="true"]) {
   -moz-box-shadow: inset 0 1px 0 rgba(50,50,50,.5);
 }
 
 .tabs-newtab-button:-moz-lwtheme-brighttext,
 .tabs-alltabs-button:-moz-lwtheme-brighttext,
-.tabs-container:-moz-lwtheme-brighttext > .tabs-closebutton,
+.tabbrowser-tabs:-moz-lwtheme-brighttext > .tabs-closebutton,
 .tabbrowser-arrowscrollbox:-moz-lwtheme-brighttext > .scrollbutton-up,
 .tabbrowser-arrowscrollbox:-moz-lwtheme-brighttext > .scrollbutton-down,
 .tabbrowser-tab:-moz-lwtheme-brighttext:not([selected="true"]) {
   -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.6);
 }
 
 #main-window {
   -moz-appearance: none;
@@ -132,31 +127,31 @@
   background-image: url("chrome://global/skin/toolbar/toolbar-background-inactive.png");
 }
 
 #main-window:not([active="true"]) > #navigator-toolbox > #PersonalToolbar {
   background-color: -moz-mac-chrome-inactive;
   border-bottom-color: rgba(0, 0, 0, 0.32);
 }
 
+#main-window:not([active="true"]) > #navigator-toolbox > #TabsToolbar:not(:-moz-lwtheme) {
+  background-color: #e2e2e2;
+}
+
 #main-window:not([active="true"]) > #navigator-toolbox > toolbar > toolbaritem,
 #main-window:not([active="true"]) > #navigator-toolbox > toolbar > toolbarbutton,
 #main-window:not([active="true"]) .tabs-newtab-button > .toolbarbutton-icon {
   opacity: 0.75;
 }
 
 #main-window:not([active="true"]) > #browser > vbox > #sidebar,
 #main-window:not([active="true"]) > #browser > vbox > sidebarheader { 
   background-color: #e8e8e8;
 }
 
-#main-window:not([active="true"]) .tabbrowser-strip {
-  background-color: #e2e2e2;
-}
-
 #main-window:not([active="true"]) .tabbrowser-tab {
   color: #575757;
 }
 
 #main-window:not([active="true"]) .tabbrowser-tab[selected="true"] {
   background-color: -moz-mac-chrome-inactive;
 }
 
@@ -1481,17 +1476,17 @@ toolbarbutton.chevron > .toolbarbutton-m
 }
 
 .openintabs-menuitem {
   list-style-image: none;
 }
 
 /* ::::: tabbrowser ::::: */
 
-tabbrowser > tabbox {
+.tabbrowser-tabbox {
   margin: 0;
 }
 
 .tab-icon-image {
   width: 16px;
   height: 16px;
   list-style-image: url("chrome://global/skin/tree/item.png");
   margin-top: 2px;
@@ -1585,38 +1580,33 @@ tabbrowser > tabbox {
 }
 
 .tabbrowser-tab:-moz-lwtheme,
 #main-window:not([active="true"]) .tabbrowser-tab:-moz-lwtheme {
   color: inherit;
   text-shadow: inherit;
 }
 
-.tabbrowser-strip {
+#TabsToolbar {
+  -moz-appearance: none;
   margin-top: -1px;
   border-bottom: 1px solid #404040;
-  background-color: #9B9B9B;
+}
+
+#TabsToolbar:not(:-moz-lwtheme) {
+  background: #9B9B9B url("chrome://browser/skin/tabbrowser/tabbrowser-tabs-bkgnd.png") repeat-x;
 }
 
 .tabbrowser-tabs {
-  border: none;
-  -moz-box-pack: center;
-  -moz-box-align: center;
-  background: url("chrome://browser/skin/tabbrowser/tabbrowser-tabs-bkgnd.png") repeat-x;
+  -moz-box-align: stretch;
   height: 25px;
-  margin-bottom: 0;
 }
 
-.tabs-left {
-  display: -moz-box;
-  width: 3px;
-}
-
-.tabbrowser-tabs[overflow="true"] .tabs-left {
-  display: none;
+.tabbrowser-tabs:not([overflow="true"]) {
+  -moz-padding-start: 3px;
 }
 
 /**
  * Tab Drag and Drop
  */
 
 .tab-drop-indicator {
   margin-top: -8px !important;
@@ -1707,17 +1697,17 @@ tabbrowser > tabbox {
   background-color: transparent !important; 
 }
 
 
 /**
  * Tabstrip New Tab & All Tabs Buttons
  */
 
-.tabs-container > .tabs-newtab-button,
+.tabbrowser-tabs > .tabs-newtab-button,
 .tabs-alltabs-button {
   -moz-border-start: 2px solid;
   -moz-border-end: none;
   -moz-border-left-colors: rgba(0,0,0,0.25) rgba(255,255,255,0.15);
   -moz-border-right-colors: rgba(0,0,0,0.25) rgba(255,255,255,0.15);
   margin: 0;
   padding: 0;
 }
@@ -1741,21 +1731,21 @@ tabbrowser > tabbox {
 }
 .tabs-alltabs-button:hover {
   -moz-image-region: rect(0, 44px, 20px, 22px);
 }
 .tabs-alltabs-button[type="menu"][open="true"],
 .tabs-alltabs-button:hover:active {
   -moz-image-region: rect(0, 66px, 20px, 44px);
 }
-.tabs-container > .tabs-newtab-button:hover,
+.tabbrowser-tabs > .tabs-newtab-button:hover,
 .tabs-alltabs-button:hover {
   background-color: rgba(0,0,0,0.10);
 }
-.tabs-container > .tabs-newtab-button:hover:active,
+.tabbrowser-tabs > .tabs-newtab-button:hover:active,
 .tabs-alltabs-button:hover:active {
   background-color: rgba(0,0,0,0.20);
 }
 
 .tabs-alltabs-button[type="menu"] > .toolbarbutton-menu-dropmarker,
 .tabs-alltabs-button > .toolbarbutton-text {
   display: none;
 }
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -49,26 +49,26 @@
 #menubar-items {
   -moz-box-orient: vertical; /* for flex hack */
 }
 
 #main-menubar {
   -moz-box-flex: 1; /* make menu items expand to fill toolbar height */
 }
 
+#nav-bar {
+  -moz-appearance: none;
+  border-style: none;
+}
+
 #personal-bookmarks {
   min-height: 24px;
 }
 
-#navigator-toolbox:-moz-system-metric(windows-default-theme):not(:-moz-lwtheme) {
-  padding-bottom: 1px; /* uxtheme border drawing fix/hack */
-}
-
-#navigator-toolbox[inFullscreen="true"],
-#navigator-toolbox[inFullscreen="true"] > #nav-bar {
+#navigator-toolbox[inFullscreen="true"] {
   border-top: none;
 }
 
 #print-preview-toolbar:not(:-moz-lwtheme) {
   -moz-appearance: toolbox;
 }
 
 statusbarpanel#statusbar-display {
@@ -885,44 +885,42 @@ toolbar:not([iconsize="small"])[mode="ic
 }
 
 #navigator-throbber,
 #wrapper-navigator-throbber > #navigator-throbber {
   list-style-image: url("chrome://global/skin/icons/notloading_16.png");
 }
 
 /* Tabstrip */
-.tabbrowser-tabs {
-  -moz-appearance: -moz-win-browsertabbar-toolbox;
-  background: -moz-dialog url("chrome://browser/skin/tabbrowser/tabbrowser-tabs-bkgnd.png") repeat-x;
-}
-
-.tabbrowser-tabs:-moz-lwtheme {
+#TabsToolbar {
   -moz-appearance: none;
-  background: none;
+  min-height: 0;
+  padding: 0;
   border-style: none;
+  margin-bottom: 2px;
+  -moz-box-shadow: ThreeDShadow 0 -1px inset, -moz-dialog 0 2px;
 }
 
 .tabbrowser-tabs:-moz-system-metric(touch-enabled) {
   min-height: .81cm;
 }
 
-.tabs-container:not([overflow="true"]) {
+.tabbrowser-tabs:not([overflow="true"]) {
   -moz-padding-start: 3px;
 }
 
 /* Tabs */
 .tabbrowser-tab,
 .tabbrowser-arrowscrollbox > .scrollbutton-up,
 .tabbrowser-arrowscrollbox > .scrollbutton-down,
 .tabs-newtab-button,
 .tabs-alltabs-button {
   -moz-appearance: none;
   background: url("chrome://browser/skin/tabbrowser/tab-bkgnd.png") repeat-x;
-  margin: 3px 0px 4px;
+  margin: 3px 0 1px;
   border: 2px solid;
   border-right-width: 1px;
   border-bottom: none;
   -moz-border-top-colors: ThreeDShadow rgba(255,255,255,.3);
   -moz-border-left-colors: ThreeDShadow rgba(255,255,255,.3);
 }
 
 .tabbrowser-tab:-moz-lwtheme-brighttext,
@@ -954,23 +952,23 @@ toolbar:not([iconsize="small"])[mode="ic
   -moz-border-radius-topleft: 4px;
   -moz-border-radius-topright: 4px;
   -moz-border-top-colors: ThreeDShadow;
   -moz-border-right-colors: ThreeDShadow;
   -moz-border-left-colors: ThreeDShadow;
 }
 
 .tabbrowser-tab:not([selected="true"]):hover {
-  margin: 2px 0px 4px;
+  margin: 2px 0 1px;
   padding: 2px 1px 1px;
   background-image: url("chrome://browser/skin/tabbrowser/tab-hover-bkgnd.png");
 }
 
 .tabbrowser-tab[selected="true"] {
-  margin: 2px 0px 3px;
+  margin: 2px 0 0;
   padding: 1px;
   background-image: url("chrome://browser/skin/tabbrowser/tab-active-bkgnd.png");
   background-color: -moz-dialog;
   font-weight: bold;
 }
 
 .tabbrowser-tab:-moz-lwtheme[selected="true"] {
   text-shadow: none;
@@ -1017,24 +1015,16 @@ toolbar:not([iconsize="small"])[mode="ic
   -moz-margin-start: 7px;
   -moz-margin-end: 3px;
   width: 16px;
   height: 16px;
   list-style-image: url("chrome://global/skin/icons/folder-item.png");
   -moz-image-region: rect(0px, 16px, 16px, 0px);
 }
 
-.tabs-bottom {
-  height: 4px;
-  margin: 0px;
-  background: -moz-dialog url("chrome://browser/skin/tabbrowser/tabstrip-bottom.png") repeat;
-  border-top: 1px solid threedshadow;
-  border-bottom: 1px solid threedshadow;
-}
-
 /* tabbrowser-tab focus ring */
 .tabbrowser-tab > .tab-text {
   border: 1px dotted transparent;
 }
 
 .tabbrowser-tab:focus > .tab-text {
   border: 1px dotted -moz-DialogText;
 }
@@ -1145,34 +1135,34 @@ toolbar:not([iconsize="small"])[mode="ic
 
 .tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-locale-dir(rtl) {
   border-right-style: none;
   -moz-border-radius-topleft: 2px;
   list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-right.png");
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-locale-dir(ltr),
-.tabs-container > .tabs-newtab-button:-moz-locale-dir(ltr),
+.tabbrowser-tabs > .tabs-newtab-button:-moz-locale-dir(ltr),
 .tabs-alltabs-button:-moz-locale-dir(ltr) {
   border-right-style: none;
   -moz-border-radius-topleft: 2px;
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-down {
   list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-right.png");
   -moz-transition: 1s background-color ease-out;
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-down[notifybgtab] {
   background-color: Highlight;
   -moz-transition: none;
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-locale-dir(rtl),
-.tabs-container > .tabs-newtab-button:-moz-locale-dir(rtl),
+.tabbrowser-tabs > .tabs-newtab-button:-moz-locale-dir(rtl),
 .tabs-alltabs-button:-moz-locale-dir(rtl) {
   border-left-style: none;
   -moz-border-radius-topright: 2px;
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-locale-dir(rtl) {
   list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-left.png");
 }
@@ -1253,26 +1243,26 @@ toolbar:not([iconsize="small"])[mode="ic
 .tabs-closebutton:hover {
   -moz-image-region: rect(0px, 28px, 14px, 14px);
 }
 
 .tabs-closebutton:hover:active {
   -moz-image-region: rect(0px, 42px, 14px, 28px);
 }
 
-.tabs-container > .tabs-closebutton {
+.tabbrowser-tabs > .tabs-closebutton {
   margin: 3px 0px 3px;
   padding: 4px 2px 2px;
   background: -moz-dialog url("chrome://browser/skin/tabbrowser/tab-active-bkgnd.png") repeat-x;
   border-left: 1px solid threedshadow;
   border-top: 1px solid threedshadow;
   -moz-border-radius-topleft: 2px;
 }
 
-.tabs-container > .tabs-closebutton:-moz-locale-dir(rtl) {
+.tabbrowser-tabs > .tabs-closebutton:-moz-locale-dir(rtl) {
   border-left: none;
   border-right: 1px solid threedshadow;
   -moz-border-radius-topleft: 0px;
   -moz-border-radius-topright: 2px;
 }
 
 #sidebar-box .tabs-closebutton {
   list-style-image: url("chrome://global/skin/icons/closeSidebar.png");
--- a/browser/themes/winstripe/browser/jar.mn
+++ b/browser/themes/winstripe/browser/jar.mn
@@ -75,22 +75,20 @@ browser.jar:
         skin/classic/browser/preferences/preferences.css             (preferences/preferences.css)
         skin/classic/browser/preferences/applications.css            (preferences/applications.css)
         skin/classic/browser/tabbrowser/alltabs.png                             (tabbrowser/alltabs.png)
         skin/classic/browser/tabbrowser/newtab.png                              (tabbrowser/newtab.png)
         skin/classic/browser/tabbrowser/progress.png                            (tabbrowser/progress.png)
         skin/classic/browser/tabbrowser/progress-pulsing.png                    (tabbrowser/progress-pulsing.png)
         skin/classic/browser/tabbrowser/tab-arrow-left.png                      (tabbrowser/tab-arrow-left.png)
         skin/classic/browser/tabbrowser/tab-arrow-right.png                     (tabbrowser/tab-arrow-right.png)
-        skin/classic/browser/tabbrowser/tabbrowser-tabs-bkgnd.png               (tabbrowser/tabbrowser-tabs-bkgnd.png)
         skin/classic/browser/tabbrowser/tabDragIndicator.png                    (tabbrowser/tabDragIndicator.png)
         skin/classic/browser/tabbrowser/tab-bkgnd.png                           (tabbrowser/tab-bkgnd.png)
         skin/classic/browser/tabbrowser/tab-active-bkgnd.png                    (tabbrowser/tab-active-bkgnd.png)
         skin/classic/browser/tabbrowser/tab-hover-bkgnd.png                     (tabbrowser/tab-hover-bkgnd.png)
-        skin/classic/browser/tabbrowser/tabstrip-bottom.png                     (tabbrowser/tabstrip-bottom.png)
 
 #ifdef XP_WIN
 browser.jar:
 % skin browser classic/1.0 %skin/classic/aero/browser/ os=WINNT osversion>=6
         skin/classic/aero/browser/sanitizeDialog.css                       (sanitizeDialog.css)
 *       skin/classic/aero/browser/aboutPrivateBrowsing.css           (aboutPrivateBrowsing.css)
 *       skin/classic/aero/browser/aboutSessionRestore.css            (aboutSessionRestore.css)
         skin/classic/aero/browser/aboutSessionRestore-window-icon.png (aboutSessionRestore-window-icon-aero.png)
@@ -164,15 +162,13 @@ browser.jar:
         skin/classic/aero/browser/preferences/preferences.css        (preferences/preferences.css)
         skin/classic/aero/browser/preferences/applications.css       (preferences/applications.css)
         skin/classic/aero/browser/tabbrowser/alltabs.png                        (tabbrowser/alltabs-aero.png)
         skin/classic/aero/browser/tabbrowser/newtab.png                         (tabbrowser/newtab-aero.png)
         skin/classic/aero/browser/tabbrowser/progress.png                       (tabbrowser/progress.png)
         skin/classic/aero/browser/tabbrowser/progress-pulsing.png               (tabbrowser/progress-pulsing.png)
         skin/classic/aero/browser/tabbrowser/tab-arrow-left.png                 (tabbrowser/tab-arrow-left-aero.png)
         skin/classic/aero/browser/tabbrowser/tab-arrow-right.png                (tabbrowser/tab-arrow-right-aero.png)
-        skin/classic/aero/browser/tabbrowser/tabbrowser-tabs-bkgnd.png          (tabbrowser/tabbrowser-tabs-bkgnd.png)
         skin/classic/aero/browser/tabbrowser/tabDragIndicator.png               (tabbrowser/tabDragIndicator-aero.png)
         skin/classic/aero/browser/tabbrowser/tab-bkgnd.png                      (tabbrowser/tab-bkgnd.png)
         skin/classic/aero/browser/tabbrowser/tab-active-bkgnd.png               (tabbrowser/tab-active-bkgnd.png)
         skin/classic/aero/browser/tabbrowser/tab-hover-bkgnd.png                (tabbrowser/tab-hover-bkgnd.png)
-        skin/classic/aero/browser/tabbrowser/tabstrip-bottom.png                (tabbrowser/tabstrip-bottom.png)
 #endif
deleted file mode 100644
index eb8e901d032983bf821f718c4e1eb5718e5b3b80..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 945f42da7c50d40398555fe91501adbdfab21012..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001