b=446673, r=gavin. Sidebar never goes away
authorMark Finkle <mfinkle@mozilla.com>
Fri, 25 Jul 2008 14:10:35 -0400
changeset 64774 32df5158ba17354cc1903035af7e7ed8e70f8357
parent 64773 6d9deaa041faf77db398e429cb5742352f78877c
child 64775 30bb7c9f5a549ad5ce8ecad66351f5dfc0082efe
push idunknown
push userunknown
push dateunknown
reviewersgavin
bugs446673
b=446673, r=gavin. Sidebar never goes away
mobile/chrome/content/browser-ui.js
mobile/chrome/content/browser.js
mobile/chrome/content/browser.xul
mobile/chrome/content/deckbrowser.xml
mobile/chrome/locale/en-US/browser.dtd
mobile/chrome/skin/browser.css
--- a/mobile/chrome/content/browser-ui.js
+++ b/mobile/chrome/content/browser-ui.js
@@ -34,31 +34,33 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TOOLBARSTATE_LOADING        = 1;
 const TOOLBARSTATE_LOADED         = 2;
 const TOOLBARSTATE_INDETERMINATE  = 3;
 
-const PANELMODE_VIEW              = 1;
-const PANELMODE_EDIT              = 2;
+const PANELMODE_NONE              = 0;
+const PANELMODE_URLVIEW           = 1;
+const PANELMODE_URLEDIT           = 2;
 const PANELMODE_BOOKMARK          = 3;
 const PANELMODE_BOOKMARKLIST      = 4;
+const PANELMODE_SIDEBAR           = 5;
+const PANELMODE_TABLIST           = 6;
+const PANELMODE_FULL              = 7;
 
 var BrowserUI = {
   _panel : null,
   _caption : null,
   _edit : null,
   _throbber : null,
   _autocompleteNavbuttons : null,
   _favicon : null,
   _faviconAdded : false,
-  _fadeoutID : null,
-  _allowHide : true,
 
   _titleChanged : function(aEvent) {
     if (aEvent.target != getBrowser().contentDocument)
       return;
 
     this._caption.value = aEvent.target.title;
   },
 
@@ -142,52 +144,49 @@ var BrowserUI = {
     this._edit.addEventListener("input", this, false);
     this._throbber = document.getElementById("urlbar-throbber");
     this._favicon = document.getElementById("urlbar-favicon");
     this._favicon.addEventListener("error", this, false);
     this._autocompleteNavbuttons = document.getElementById("autocomplete_navbuttons");
 
     getBrowser().addEventListener("DOMTitleChanged", this, true);
     getBrowser().addEventListener("DOMLinkAdded", this, true);
+    Browser.content.addEventListener("overpan", this, false);
+    Browser.content.addEventListener("pan", this, true);
   },
 
   update : function(aState) {
     if (aState == TOOLBARSTATE_INDETERMINATE) {
       this._faviconAdded = false;
       aState = TOOLBARSTATE_LOADED;
       this.setURI();
     }
 
     var toolbar = document.getElementById("toolbar-main");
     if (aState == TOOLBARSTATE_LOADING) {
-      this._showMode(PANELMODE_VIEW);
+      this.show(PANELMODE_URLVIEW);
 
       toolbar.setAttribute("mode", "loading");
       this._throbber.setAttribute("src", "chrome://browser/skin/images/throbber.gif");
       this._favicon.setAttribute("src", "");
       this._faviconAdded = false;
     }
     else if (aState == TOOLBARSTATE_LOADED) {
       toolbar.setAttribute("mode", "view");
       this._throbber.setAttribute("src", "");
       if (this._faviconAdded == false) {
         var faviconURI = getBrowser().currentURI.prePath + "/favicon.ico";
         this._setIcon(faviconURI);
       }
-/*
-      if (this._allowHide)
-        this.hide(3000);
-      this._allowHide = true;
-*/
     }
   },
 
   /* Set the location to the current content */
   setURI : function() {
-    var browser = getBrowser();
+    var browser = Browser.currentBrowser;
     var back = document.getElementById("cmd_back");
     var forward = document.getElementById("cmd_forward");
 
     back.setAttribute("disabled", !browser.canGoBack);
     forward.setAttribute("disabled", !browser.canGoForward);
 
     // Check for a bookmarked page
     var star = document.getElementById("tool-star");
@@ -207,46 +206,46 @@ var BrowserUI = {
 
     try {
       uri = this._URIFixup.createExposableURI(uri);
     } catch (ex) {}
 
     var urlString = uri.spec;
     if (urlString == "about:blank") {
       urlString = "";
-      this._showMode(PANELMODE_EDIT);
-      this._allowHide = false;
+      this.show(PANELMODE_URLEDIT);
     }
 
     this._caption.value = urlString;
     this._edit.value = urlString;
   },
 
   goToURI : function(aURI) {
     this._edit.reallyClosePopup();
 
     if (!aURI)
       aURI = this._edit.value;
 
     var flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
     getBrowser().loadURIWithFlags(aURI, flags, null, null);
-    this._showMode(PANELMODE_VIEW);
+    this.show(PANELMODE_URLVIEW);
   },
 
   search : function() {
     var queryURI = "http://www.google.com/search?q=" + this._edit.value + "&hl=en&lr=&btnG=Search";
     getBrowser().loadURI(queryURI, null, null, false);
 
-    this._showMode(PANELMODE_VIEW);
+    this.show(PANELMODE_URLVIEW);
   },
 
   sizeAutocompletePopup : function () {
     var rect = document.getElementById("browser-container").getBoundingClientRect();
+    var toolbar = document.getElementById("toolbar-main");
     var popup = document.getElementById("popup_autocomplete");
-    popup.height = rect.bottom - rect.top;
+    popup.height = rect.bottom - rect.top - toolbar.boxObject.height;
   },
 
   openDefaultHistory : function () {
     if (!this._edit.value) {
       this._autocompleteNavbuttons.hidden = true;
       this._edit.showHistoryPopup();
     }
   },
@@ -291,54 +290,102 @@ var BrowserUI = {
       button.setAttribute("label", engine.name);
       if (engine.iconURI)
         button.setAttribute("image", engine.iconURI.spec);
       container.insertBefore(button, container.firstChild);
       button.engine = engine;
     }
   },
 
-  _showMode : function(aMode) {
-    if (this._fadeoutID) {
-      clearTimeout(this._fadeoutID);
-      this._fadeoutID = null;
-    }
+  mode : PANELMODE_NONE,
+  show : function(aMode) {
+    if (this.mode == aMode)
+      return;
+    this.mode = aMode;
 
     var toolbar = document.getElementById("toolbar-main");
     var bookmark = document.getElementById("bookmark-container");
     var urllist = document.getElementById("urllist-container");
-    if (aMode == PANELMODE_VIEW) {
+    var sidebar = document.getElementById("browser-controls");
+    var tablist = document.getElementById("tab-list-container");
+    var container = document.getElementById("browser-container");
+
+    // Make sure the UI elements are sized correctly since the window size can change
+    sidebar.left = toolbar.width = container.boxObject.width;
+    sidebar.height = tablist.height = container.boxObject.height - toolbar.boxObject.height;
+
+    if (aMode == PANELMODE_URLVIEW || aMode == PANELMODE_SIDEBAR ||
+        aMode == PANELMODE_TABLIST || aMode == PANELMODE_FULL)
+    {
       toolbar.setAttribute("mode", "view");
+      toolbar.top = 0;
+
       this._edit.hidden = true;
+      this._edit.reallyClosePopup();
       this._caption.hidden = false;
       bookmark.hidden = true;
       urllist.hidden = true;
+
+      let sidebarTo = toolbar.boxObject.width;
+      let tablistTo = -tablist.boxObject.width;
+      if (aMode == PANELMODE_SIDEBAR || aMode == PANELMODE_FULL)
+        sidebarTo -= sidebar.boxObject.width;
+      if (aMode == PANELMODE_TABLIST || aMode == PANELMODE_FULL)
+        tablistTo = 0;
+      sidebar.left = sidebarTo;
+      tablist.left = tablistTo;
     }
-    else if (aMode == PANELMODE_EDIT) {
+    else if (aMode == PANELMODE_URLEDIT) {
       toolbar.setAttribute("mode", "edit");
+      toolbar.top = 0;
       this._caption.hidden = true;
       this._edit.hidden = false;
       this._edit.focus();
+
       bookmark.hidden = true;
       urllist.hidden = true;
+      sidebar.left = toolbar.boxObject.width;
+      tablist.left = -tablist.boxObject.width;
     }
     else if (aMode == PANELMODE_BOOKMARK) {
+      toolbar.top = 0;
       toolbar.setAttribute("mode", "view");
       this._edit.hidden = true;
+      this._edit.reallyClosePopup();
       this._caption.hidden = false;
 
       urllist.hidden = true;
+      sidebar.left = toolbar.boxObject.width;
+      tablist.left = -tablist.boxObject.width;
+
       bookmark.hidden = false;
+      bookmark.width = container.boxObject.width;
     }
     else if (aMode == PANELMODE_BOOKMARKLIST) {
+      toolbar.top = 0;
       toolbar.setAttribute("mode", "view");
       this._edit.hidden = true;
+      this._edit.reallyClosePopup();
       this._caption.hidden = false;
 
+      bookmark.hidden = true;
+      sidebar.left = toolbar.boxObject.width;
+      tablist.left = -tablist.boxObject.width;
+
       urllist.hidden = false;
+      urllist.width = container.boxObject.width;
+      urllist.height = container.boxObject.height - toolbar.boxObject.height;
+    }
+    else if (aMode == PANELMODE_NONE) {
+      toolbar.top = -toolbar.boxObject.height;
+      sidebar.left = toolbar.boxObject.width;
+      tablist.left = -tablist.boxObject.width;
+
+      this._edit.reallyClosePopup();
+      urllist.hidden = true;
       bookmark.hidden = true;
     }
   },
 
   _showPlaces : function(aItems) {
     var list = document.getElementById("urllist-items");
     while (list.firstChild) {
       list.removeChild(list.firstChild);
@@ -374,80 +421,97 @@ var BrowserUI = {
     list.focus();
   },
 
   showHistory : function() {
     this._showPlaces(this._getHistory(6));
   },
 
   showBookmarks : function () {
+    this.show(PANELMODE_BOOKMARKLIST);
+
     var bms = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
     this._showPlaces(this._getBookmarks([bms.bookmarksMenuFolder]));
   },
 
-  show : function() {
-    this._showMode(PANELMODE_VIEW);
+  newTab : function() {
+    Browser.content.newTab(true);
+    this.show(PANELMODE_URLEDIT);
   },
 
-  hide : function(aFadeout) {
-    if (!aFadeout) {
-      //FIXME hide toolbar stuff
-      this._showMode(PANELMODE_VIEW);
-    }
-    else {
-      //FIXME animate the close
-      //var self = this;
-      //this.fadeoutID = setTimeout(function() { self.hide(); }, aFadeout);
-    }
+  selectTab : function(aTab) {
+    Browser.content.selectTab(aTab);
+    this.show(PANELMODE_NONE);
   },
 
   handleEvent: function (aEvent) {
     switch (aEvent.type) {
       // Browser events
       case "DOMTitleChanged":
         this._titleChanged(aEvent);
         break;
       case "DOMLinkAdded":
         this._linkAdded(aEvent);
         break;
       // URL textbox events
       case "click":
-        this._showMode(PANELMODE_EDIT);
+        this.show(PANELMODE_URLEDIT);
         this.openDefaultHistory();
         break;
       case "input":
         if (this._edit.value) {
           this.updateSearchEngines();
           this._autocompleteNavbuttons.hidden = false;
         }
         break;
       case "keypress":
         if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
           this._edit.reallyClosePopup();
-          this._showMode(PANELMODE_VIEW);
+          this.show(PANELMODE_URLVIEW);
         }
         break;
       // Favicon events
       case "error":
         this._favicon.setAttribute("src", "chrome://browser/skin/images/default-favicon.png");
         break;
+      case "pan": {
+        // Default to hide the controls when user pans
+        let mode = PANELMODE_NONE;
+        // Open the urlbar controls if browser is at top of content
+        if (Browser.content.scrollY == 0)
+          mode = PANELMODE_URLVIEW
+
+        this.show(mode);
+        break;
+      }
+      case "overpan":
+        // Open the sidebar controls if we get a right side overpan
+        if (aEvent.detail == 2)
+          this.show(PANELMODE_SIDEBAR);
+        // Close the sidebar controls if we get a left side overpan
+        else if (aEvent.detail == 1)
+          this.show(PANELMODE_TABLIST);
+        break;
     }
   },
 
   supportsCommand : function(cmd) {
     var isSupported = false;
     switch (cmd) {
       case "cmd_back":
       case "cmd_forward":
       case "cmd_reload":
       case "cmd_stop":
       case "cmd_search":
       case "cmd_go":
       case "cmd_star":
       case "cmd_bookmarks":
+      case "cmd_menu":
+      case "cmd_newTab":
+      case "cmd_closeTab":
         isSupported = true;
         break;
       default:
         isSupported = false;
         break;
     }
     return isSupported;
   },
@@ -489,27 +553,39 @@ var BrowserUI = {
           document.getElementById("tool-star").setAttribute("starred", "true");
 
           var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
           var favicon = document.getElementById("urlbar-favicon");
           var faviconURI = ios.newURI(favicon.src, null, null);
 
           var fis = Cc["@mozilla.org/browser/favicon-service;1"].getService(Ci.nsIFaviconService);
           fis.setAndLoadFaviconForPage(bookmarkURI, faviconURI, true);
+
+          this.show(PANELMODE_NONE);
         }
         else {
-          this._showMode(PANELMODE_BOOKMARK);
+          this.show(PANELMODE_BOOKMARK);
           BookmarkHelper.edit(bookmarkURI);
         }
         break;
       }
       case "cmd_bookmarks":
-         this._showMode(PANELMODE_BOOKMARKLIST);
         this.showBookmarks();
         break;
+      case "cmd_menu":
+        if (this.mode == PANELMODE_FULL)
+          this.show(PANELMODE_NONE);
+        else
+          this.show(PANELMODE_FULL);
+        break;
+      case "cmd_newTab":
+        this.newTab();
+        break;
+      case "cmd_closeTab":
+        Browser.content.removeTab(Browser.content.browser);
     }
   }
 };
 
 var BookmarkHelper = {
   _item : null,
   _uri : null,
   _bmksvc : null,
@@ -584,17 +660,17 @@ var BookmarkHelper = {
 
     }
     this.close();
   },
 
   close : function() {
     window.removeEventListener("keypress", this, true);
     this._item = null;
-    BrowserUI.hide();
+    BrowserUI.show(PANELMODE_NONE);
   },
 
   handleEvent: function (aEvent) {
     switch (aEvent.type) {
       case "keypress":
         if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE)
           this.close();
         break;
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -92,19 +92,19 @@ var Browser = {
     var styleURI = ios.newURI("chrome://browser/content/scrollbars.css", null, null);
     styleSheets.loadAndRegisterSheet(styleURI, styleSheets.AGENT_SHEET);
 
     this._content = document.getElementById("content");
     this._content.progressListenerCreator = function (content, browser) {
       return new ProgressController(content, browser);
     };
 
+    this._content.tabList = document.getElementById("tab-list");
     this._content.newTab(true);
     this._content.addEventListener("DOMTitleChanged", this, true);
-    this._content.addEventListener("overpan", this, false);
     this._content.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver.onUpdatePageReport, false);
     BrowserUI.init();
 
     this._spatialNavigation  = new SpatialNavigation(this.content);
 
     this.setupGeolocationPrompt();
 
     Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
@@ -139,17 +139,18 @@ var Browser = {
         if (uriFlag) {
           whereURI = cmdLine.resolveURI(uriFlag);
           if (whereURI)
             whereURI = whereURI.spec;
         }
       } catch (e) {}
 
       if (whereURI) {
-        this.currentBrowser.loadURI(whereURI, null, null, false);
+        var self = this;
+        setTimeout(function() { self.currentBrowser.loadURI(whereURI, null, null, false); }, 0);
       }
     }
   },
 
   setupGeolocationPrompt: function() {
     try {
       var geolocationService = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationService);
     }
@@ -203,58 +204,42 @@ var Browser = {
     return this._content.browser;
   },
 
   handleEvent: function (aEvent) {
     switch (aEvent.type) {
       case "DOMTitleChanged":
         this._titleChanged(aEvent);
         break;
-      case "overpan":
-        // Open the sidebar controls if we get a right side overpan
-        if (aEvent.detail == 2)
-          document.getElementById("browser-controls").collapsed = false;
-        // Close the sidebar controls if we get a left side overpan
-        else if (aEvent.detail == 1)
-          document.getElementById("browser-controls").collapsed = true;
-        break;
     }
   },
 
   supportsCommand : function(cmd) {
     var isSupported = false;
     switch (cmd) {
-      case "cmd_menu":
       case "cmd_fullscreen":
       case "cmd_addons":
       case "cmd_downloads":
-      case "cmd_newTab":
-      case "cmd_closeTab":
         isSupported = true;
         break;
       default:
         isSupported = false;
         break;
     }
     return isSupported;
   },
 
   isCommandEnabled : function(cmd) {
     return true;
   },
 
   doCommand : function(cmd) {
     var browser = this.content.browser;
-    var controls = document.getElementById("browser-controls");
 
     switch (cmd) {
-      case "cmd_menu":
-        this.content.tabListVisible = !this.content.tabListVisible;
-        controls.collapsed = !controls.collapsed;
-        break;
       case "cmd_fullscreen":
         window.fullScreen = !window.fullScreen;
         break;
       case "cmd_addons":
       {
         const EMTYPE = "Extension:Manager";
 
         var aOpenMode = "extensions";
@@ -276,33 +261,23 @@ var Browser = {
           const EMFEATURES = "chrome,dialog=no,resizable=yes";
           window.openDialog(EMURL, "", EMFEATURES);
         }
         break;
       }
       case "cmd_downloads":
         Cc["@mozilla.org/download-manager-ui;1"].getService(Ci.nsIDownloadManagerUI).show(window);
         break;
-      case "cmd_newTab":
-        this.newTab();
-        break;
-      case "cmd_closeTab":
-        this.content.removeTab(this.content.browser);
     }
   },
 
   getNotificationBox : function() {
     return document.getElementById("notifications");
   },
 
-  newTab: function() {
-    this.content.newTab(true);
-    BrowserUI._showMode(PANELMODE_EDIT);
-  },
-
   findState: FINDSTATE_FIND,
   openFind: function(aState) {
     this.findState = aState;
 
     var findbar = document.getElementById("findbar");
     var browser = findbar.browser;
     if (!browser) {
       browser = this.content.browser;
--- a/mobile/chrome/content/browser.xul
+++ b/mobile/chrome/content/browser.xul
@@ -69,16 +69,17 @@
     <!-- basic navigation -->
     <command id="cmd_back" label="&back.label;" disabled="true" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_forward" label="&forward.label;" disabled="true" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_reload" label="&reload.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_stop" label="&stop.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_search" label="&search.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_go" label="&go.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
 
+    <!-- tabs -->
     <command id="cmd_newTab" label="&newtab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_closeTab" label="&closetab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
 
     <!-- bookmarking -->
     <command id="cmd_star" label="&star.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_bookmarks" label="&bookmarks.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
 
     <!-- misc -->
@@ -94,24 +95,23 @@
     <!-- editing -->
     <command id="cmd_cut" label="&cut.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_copy" label="&copy.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_copylink" label="&copylink.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_paste" label="&paste.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_delete" label="&delete.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
     <command id="cmd_selectAll" label="&selectAll.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
 
+    <!-- find -->
     <command id="cmd_find" oncommand="Browser.openFind(FINDSTATE_FIND);"/>
     <command id="cmd_findAgain" oncommand="Browser.openFind(FINDSTATE_FIND_AGAIN);"/>
     <command id="cmd_findPrevious" oncommand="Browser.openFind(FINDSTATE_FIND_PREVIOUS);"/>
   </commandset>
 
   <keyset id="mainKeyset">
-    <key id="key_menu" keycode="T" modifiers="accel" command="cmd_newTab"/>
-
     <!-- basic navigation -->
     <key id="key_back" keycode="VK_LEFT" command="cmd_back" modifiers="control"/>
     <key id="key_forward" keycode="VK_RIGHT" command="cmd_forward" modifiers="control"/>
     <key id="key_back2" keycode="VK_BACK" command="cmd_back"/>
     <key id="key_forward2" keycode="VK_BACK" command="cmd_forward" modifiers="shift"/>
     <key id="key_reload" keycode="VK_F5" command="cmd_reload"/>
 
     <!-- scrolling -->
@@ -119,16 +119,21 @@
     <key id="key_pageDown" keycode="VK_DOWN" command="cmd_scrollPageDown" modifiers="shift"/>
 
     <!-- misc -->
     <key id="key_menu" keycode="VK_F4" command="cmd_menu"/>
     <key id="key_fullscreen" keycode="VK_F6" command="cmd_fullscreen"/>
     <key id="key_addons" key="E" command="cmd_addons" modifiers="control"/>
     <key id="key_downloads" key="J" command="cmd_downloads" modifiers="control"/>
 
+    <!-- tabs -->
+    <key id="key_newTab" keycode="T" modifiers="accel" command="cmd_newTab"/>
+    <key id="key_closeTab" keycode="W" modifiers="accel" command="cmd_closeTab"/>
+
+    <!-- find -->
     <key id="key_find" key="&findOnCmd.commandkey;" command="cmd_find" modifiers="accel"/>
     <key id="key_findAgain" key="&findAgainCmd.commandkey;" command="cmd_findAgain" modifiers="accel"/>
     <key id="key_findPrevious" key="&findAgainCmd.commandkey;" command="cmd_findPrevious" modifiers="accel,shift"/>
     <key keycode="&findAgainCmd.commandkey2;" command="cmd_findAgain"/>
     <key keycode="&findAgainCmd.commandkey2;"  command="cmd_findPrevious" modifiers="shift"/>
   </keyset>
 
   <popupset id="mainPopupSet">
@@ -163,18 +168,38 @@
             </vbox>
             <description id="identity-popup-encryption-label" flex="1"/>
           </hbox>
         </vbox>
       </hbox>
     </panel>
   </popupset>
 
-  <toolbox id="toolbox-main">
-    <toolbar id="toolbar-main">
+  <stack id="browser-container" flex="1" style="overflow: hidden;">
+    <vbox id="browser">
+      <notificationbox id="notifications" flex="1">
+        <deckbrowser id="content" autocompletepopup="popup_autocomplete_content" flex="1"
+                     onnewtab="CommandUpdater.doCommand('cmd_newTab');"/>
+      </notificationbox>
+    </vbox>
+
+    <vbox id="browser-controls" style="-moz-stack-sizing: ignore; width: 80px;" top="60" left="0">
+      <toolbarbutton id="tool-back" class="browser-control-button" command="cmd_back"/>
+      <toolbarbutton id="tool-forward" class="browser-control-button" command="cmd_forward"/>
+      <toolbarbutton id="tool-star" class="browser-control-button" command="cmd_star"/>
+      <toolbarbutton id="tool-bookmarks" class="browser-control-button" command="cmd_bookmarks"/>
+      <toolbarbutton id="tool-actions" class="browser-control-button" command="cmd_actions"/>
+    </vbox>
+
+    <vbox id="tab-list-container" style="-moz-stack-sizing: ignore;" top="60" left="0">
+      <richlistbox id="tab-list" onselect="BrowserUI.selectTab(this.selectedItem);"/>
+      <button id="newtab-button" label="+" command="cmd_newTab"/>
+    </vbox>
+
+    <toolbar id="toolbar-main" style="-moz-stack-sizing: ignore; height: 60px;" top="0" left="0">
       <hbox id="urlbar-container" flex="1">
         <box id="identity-box"
              onclick="getIdentityHandler().handleIdentityButtonEvent(event);"
              onkeypress="getIdentityHandler().handleIdentityButtonEvent(event);">
           <stack id="urlbar-image-stack">
             <image id="urlbar-throbber" src=""/>
             <image id="urlbar-favicon" src=""/>
           </stack>
@@ -194,46 +219,24 @@
                  clickSelectsAll="true"/>
       </hbox>
       <hbox id="urlbar-icons">
         <toolbarbutton id="tool-reload" class="urlbar-icon-button" command="cmd_reload"/>
         <toolbarbutton id="tool-stop" class="urlbar-icon-button" command="cmd_stop"/>
         <toolbarbutton id="tool-go" class="urlbar-icon-button" command="cmd_go"/>
       </hbox>
     </toolbar>
-  </toolbox>
 
-  <stack flex="1">
-    <hbox id="browser-container" flex="1">
-      <vbox id="browser" flex="1">
-        <notificationbox id="notifications" flex="1">
-          <deckbrowser id="content" autocompletepopup="popup_autocomplete_content" flex="1"
-                       onnewtab="Browser.newTab()"/>
-        </notificationbox>
-      </vbox>
-      <vbox id="browser-controls" collapsed="true">
-        <toolbarbutton id="tool-back" class="browser-control-button" command="cmd_back"/>
-        <toolbarbutton id="tool-forward" class="browser-control-button" command="cmd_forward"/>
-        <toolbarbutton id="tool-star" class="browser-control-button" command="cmd_star"/>
-        <toolbarbutton id="tool-bookmarks" class="browser-control-button" command="cmd_bookmarks"/>
-        <toolbarbutton id="tool-actions" class="browser-control-button" command="cmd_actions"/>
-      </vbox>
-    </hbox>
-
-    <vbox id="urllist-container" flex="1" hidden="true">
+    <vbox id="urllist-container" hidden="true" style="-moz-stack-sizing: ignore;" top="60" left="0">
       <hbox id="urllist-items-container" flex="1">
         <richlistbox id="urllist-items" flex="1"/>
       </hbox>
-      <separator class="thin"/>
-      <hbox id="urllist-search">
-        <image class="tool-search"/>
-      </hbox>
     </vbox>
 
-    <vbox id="bookmark-container" flex="1" hidden="true">
+    <vbox id="bookmark-container" hidden="true" style="-moz-stack-sizing: ignore;" top="60" left="0">
       <vbox id="bookmark-form">
         <hbox align="start">
           <image id="bookmark-image" src="chrome://browser/skin/images/starred48.png"/>
           <grid id="bookmark-grid" flex="1">
             <columns>
               <column/>
               <column flex="1"/>
             </columns>
--- a/mobile/chrome/content/deckbrowser.xml
+++ b/mobile/chrome/content/deckbrowser.xml
@@ -4,21 +4,16 @@
 <bindings
     xmlns="http://www.mozilla.org/xbl"
     xmlns:xbl="http://www.mozilla.org/xbl"
     xmlns:html="http://www.w3.org/1999/xhtml"
     xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <binding id="deckbrowser">
     <content>
-      <xul:vbox class="tab-list-container" collapsed="true">
-        <xul:richlistbox anonid="tab-list" class="tab-list"
-                         onselect="this.parentNode.parentNode.selectTab(this.selectedItem)"/>
-        <xul:button class="newtab-button" label="+" xbl:inherits="oncommand=onnewtab"/>
-      </xul:vbox>
       <xul:deck flex="1" selectedIndex="0">
         <xul:stack anonid="cstack" flex="1" style="overflow: hidden;">
           <html:canvas anonid="ccanvas"
                        moz-opaque="true"
                        style="-moz-stack-sizing: ignore;"/>
         </xul:stack>
         <xul:deck anonid="display-list" flex="1"/>
       </xul:deck>
@@ -83,24 +78,19 @@
       </property>
 
       <property name="displayList" readonly="true">
         <getter>
           return document.getAnonymousElementByAttribute(this, "anonid", "display-list");
         </getter>
       </property>
 
-      <property name="tabList" readonly="true">
-        <getter>
-          return document.getAnonymousElementByAttribute(this, "anonid", "tab-list");
-        </getter>
-      </property>
-
-      <property name="tabListVisible" onget="return !this.tabList.parentNode.collapsed"
-                                      onset="this.tabList.parentNode.collapsed = !val; return val;"/>
+      <field name="tabList">
+        null
+      </field>
 
       <field name="progressListenerCreator"/>
 
       <method name="updateCanvasState">
         <parameter name="aNewDoc"/>
         <body><![CDATA[
           if (aNewDoc)
             this._updateViewState();
@@ -368,17 +358,17 @@
           if (doc instanceof HTMLDocument) {
             var tags = ["input", "textarea", "select"];
 
             for (var t = 0; t < tags.length; t++) {
               var elements = doc.getElementsByTagName(tags[t]);
               for (var e = 0; e < elements.length; e++) {
                 var element = elements[e];
                 var id;
-                if (element.id) 
+                if (element.id)
                   id = "#" + element.id;
                 else if (element.name)
                   id = "$" + element.name;
 
                 if (id)
                   state[id] = element.value;
               }
             }
@@ -635,16 +625,28 @@
 
       <property name="_effectiveCanvasDimensions" readonly="true">
         <getter><![CDATA[
           return [this._canvas.width / this._zoomLevel,
                   this._canvas.height / this._zoomLevel];
          ]]></getter>
       </property>
 
+      <property name="scrollX" readonly="true">
+        <getter><![CDATA[
+          return this.dragData.pageX - this.dragData.dragX / this._zoomLevel;
+         ]]></getter>
+      </property>
+
+      <property name="scrollY" readonly="true">
+        <getter><![CDATA[
+          return this.dragData.pageY - this.dragData.dragY / this._zoomLevel;
+         ]]></getter>
+      </property>
+
       <field name="_fireOverpan">
         0
       </field>
 
       /**
        * Given a set of page coordinates, constrain them such that they
        * fit within the rect defined by [0,0] and [x,y], where x and y are
        * the maximum values that can be used for the canvas' .top and .left
@@ -715,24 +717,29 @@
           return [aX, aY];
         ]]></body>
       </method>
 
       <method name="_moveCanvas">
         <parameter name="aDx"/>
         <parameter name="aDy"/>
         <body><![CDATA[
-          // constrain offsets to the actual scrollWidth/scrollHeight
-          var [x, y] = this._constrainPanCoords(aDx, aDy);
+          // Fire the panning event
+          var event = document.createEvent("UIEvents");
+          event.initUIEvent("pan", true, true, window, 0);
+          if (this.dispatchEvent(event)) {
+            // Constrain offsets to the actual scrollWidth/scrollHeight
+            var [x, y] = this._constrainPanCoords(aDx, aDy);
 
-          // Canvas needs to move up for content to scroll down
-          this.dragData.dragX = -x;
-          this.dragData.dragY = -y;
+            // Canvas needs to move up for content to scroll down
+            this.dragData.dragX = -x;
+            this.dragData.dragY = -y;
 
-          this._updateCanvasPosition();
+            this._updateCanvasPosition();
+          }
         ]]></body>
       </method>
 
       <!-- Pans directly to a given X/Y (in page coordinates) -->
       <method name="_panTo">
         <parameter name="aX"/>
         <parameter name="aY"/>
         <body><![CDATA[
--- a/mobile/chrome/locale/en-US/browser.dtd
+++ b/mobile/chrome/locale/en-US/browser.dtd
@@ -11,17 +11,17 @@
 <!ENTITY go.label              "Go">
 <!ENTITY go.tooltip            "Go">
 <!ENTITY star.label            "Star">
 <!ENTITY star.tooltip          "Bookmark this page">
 <!ENTITY bookmarks.label       "Bookmarks">
 <!ENTITY bookmarks.tooltip     "View bookmarks">
 
 <!ENTITY newtab.label          "New Tab">
-<!ENTITY closetab.label         "Close Tab">
+<!ENTITY closetab.label        "Close Tab">
 
 <!ENTITY cut.label             "Cut">
 <!ENTITY copy.label            "Copy">
 <!ENTITY copylink.label        "Copy Link Location">
 <!ENTITY paste.label           "Paste">
 <!ENTITY delete.label          "Delete">
 <!ENTITY selectAll.label       "Select All">
 <!ENTITY noSuggestions.label   "(No suggestions)">
--- a/mobile/chrome/skin/browser.css
+++ b/mobile/chrome/skin/browser.css
@@ -243,21 +243,21 @@ toolbarbutton.browser-control-button {
   background-color: rgba(207,207,207,0.9);
   border: 2px solid #fff !important;
   -moz-border-radius: 10px;
   _moz-box-align: start;
 }
 
 /* tab list */
 
-.tab-list-container {
+#tab-list-container {
   background-color: rgb(123,125,123);
 }
 
-.tab-list {
+#tab-list {
   -moz-appearance: none;
   margin: 0;
   padding: 4px;
   background-color: rgb(123,125,123);
 }
 
 richlistitem[type="documenttab"] {
   -moz-appearance: none;
@@ -266,20 +266,19 @@ richlistitem[type="documenttab"] {
   background: none;
   padding: 4px;
 }
 
 richlistitem[type="documenttab"][selected="true"] {
   border: 1px solid white !important;
 }
 
-.newtab-button {
+#newtab-button {
   -moz-appearance: none;
   background-color: rgba(207,207,207,0.9);
-  font-size: 24pt;
 }
 
 /* autocomplete */
 
 #popup_autocomplete {
   -moz-appearance: none;
   background-color: rgba(207,207,207,0.9);
 }
@@ -292,23 +291,23 @@ richlistitem[type="documenttab"][selecte
   direction: ltr !important;
 }
 
 .ac-result-type-bookmark {
    list-style-image: url("chrome://browser/skin/images/page-starred.png");
    width: 16px;
    height: 16px;
  }
- 
+
 .ac-result-type-tag {
    list-style-image: url("chrome://browser/skin/images/tag.png");
    width: 16px;
    height: 16px;
  }
- 
+
 .ac-comment {
   font-size: 1.15em;
 }
 
 .ac-extra > .ac-comment {
   font-size: inherit;
 }