Bug 903178 - Start screen should scroll vertically when in portrait mode r=sfoster
authorRodrigo Silveira <rsilveira@mozilla.com>
Mon, 29 Jul 2013 11:01:36 -0700
changeset 143747 606d259eafe96e174a24405d0155aa23eac0a0e5
parent 143746 d5c5d4cb5fa6257179699e470f023a4d335d8eb5
child 143748 349208bd639773779a13401833b92cf2cbf441b2
push id2308
push userrsilveira@mozilla.com
push dateThu, 22 Aug 2013 01:59:35 +0000
treeherderfx-team@606d259eafe9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfoster
bugs903178
milestone26.0a1
Bug 903178 - Start screen should scroll vertically when in portrait mode r=sfoster
browser/metro/base/content/bindings/grid.xml
browser/metro/base/content/startui/BookmarksView.js
browser/metro/base/content/startui/HistoryView.js
browser/metro/base/content/startui/RemoteTabsView.js
browser/metro/base/content/startui/StartUI.js
browser/metro/base/content/startui/TopSitesView.js
browser/metro/modules/View.jsm
browser/metro/theme/browser.css
browser/metro/theme/defines.inc
browser/metro/theme/platform.css
browser/metro/theme/tiles.css
--- a/browser/metro/base/content/bindings/grid.xml
+++ b/browser/metro/base/content/bindings/grid.xml
@@ -458,31 +458,36 @@
             if (this._scheduledArrangeItemsTimerId) {
               clearTimeout(this._scheduledArrangeItemsTimerId);
               delete this._scheduledArrangeItemsTimerId;
             }
             this._scheduledArrangeItemsTries = 0;
 
             // clear explicit width and columns before calculating from avail. height again
             let gridStyle = this._grid.style;
-            gridStyle.removeProperty('min-width');
-            gridStyle.removeProperty('-moz-column-count');
-
-            // We favor overflowing horizontally, not vertically (rows then colums)
-            // rows attribute = max rows
-            let maxRowCount = Math.min(this.getAttribute("rows") || Infinity, Math.floor(containerDims.height / itemDims.height));
-            this._rowCount = Math.min(this.itemCount, maxRowCount);
+            gridStyle.removeProperty("min-width");
+            gridStyle.removeProperty("-moz-column-count");
 
-            // columns attribute = min cols
-            this._columnCount = this.itemCount ?
-                  Math.max(
-                      // at least 1 column when there are items
-                      this.getAttribute("columns") || 1,
-                      Math.ceil(this.itemCount / this._rowCount)
-                  ) : this.getAttribute("columns") || 0;
+            if (this.hasAttribute("vertical")) {
+              this._columnCount = Math.floor(containerDims.width / itemDims.width) || 1;
+              this._rowCount = Math.floor(this.itemCount / this._columnCount);
+            } else {
+              // We favor overflowing horizontally, not vertically (rows then colums)
+              // rows attribute = max rows
+              let maxRowCount = Math.min(this.getAttribute("rows") || Infinity, Math.floor(containerDims.height / itemDims.height));
+              this._rowCount = Math.min(this.itemCount, maxRowCount);
+
+              // columns attribute = min cols
+              this._columnCount = this.itemCount ?
+                    Math.max(
+                        // at least 1 column when there are items
+                        this.getAttribute("columns") || 1,
+                        Math.ceil(this.itemCount / this._rowCount)
+                    ) : this.getAttribute("columns") || 0;
+            }
 
             // width is typically auto, cap max columns by truncating items collection
             // or, setting max-width style property with overflow hidden
             // '0' is an invalid value, just leave the property unset when 0 columns
             if (this._columnCount) {
               gridStyle.MozColumnCount = this._columnCount;
             }
             this._fireEvent("arranged");
--- a/browser/metro/base/content/startui/BookmarksView.js
+++ b/browser/metro/base/content/startui/BookmarksView.js
@@ -318,20 +318,16 @@ let BookmarksStartView = {
     this._view.getBookmarks();
   },
 
   uninit: function uninit() {
     if (this._view) {
       this._view.destruct();
     }
   },
-
-  show: function show() {
-    this._grid.arrangeItems();
-  }
 };
 
 /**
  * Observes bookmark changes and keeps a linked BookmarksView updated.
  *
  * @param aView An instance of BookmarksView.
  */
 function BookmarkChangeListener(aView) {
--- a/browser/metro/base/content/startui/HistoryView.js
+++ b/browser/metro/base/content/startui/HistoryView.js
@@ -297,20 +297,16 @@ HistoryView.prototype = Util.extend(Obje
     throw Cr.NS_ERROR_NO_INTERFACE;
   }
 });
 
 let HistoryStartView = {
   _view: null,
   get _grid() { return document.getElementById("start-history-grid"); },
 
-  show: function show() {
-    this._grid.arrangeItems();
-  },
-
   init: function init() {
     this._view = new HistoryView(this._grid, StartUI.maxResultsPerSection, true);
     this._view.populateGrid();
   },
 
   uninit: function uninit() {
     if (this._view) {
       this._view.destruct();
--- a/browser/metro/base/content/startui/RemoteTabsView.js
+++ b/browser/metro/base/content/startui/RemoteTabsView.js
@@ -93,16 +93,17 @@ RemoteTabsView.prototype = Util.extend(O
         //  need to readd logic to reset seenURLs for each client.
 
         let item = this._set.appendItem((title || url), url);
         item.setAttribute("iconURI", Weave.Utils.getIcon(icon));
 
       }, this);
     }
     this.setUIAccessVisible(show);
+    this._set.arrangeItems();
   },
 
   destruct: function destruct() {
     Services.obs.removeObserver(this, "metro_viewstate_changed");
     Weave.Svc.Obs.remove("weave:engine:sync:finish", this);
     Weave.Svc.Obs.remove("weave:service:logout:start-over", this);
   },
 
@@ -122,13 +123,9 @@ let RemoteTabsStartView = {
     this._view = new RemoteTabsView(this._grid, uiList);
   },
 
   uninit: function uninit() {
     if (this._view) {
       this._view.destruct();
     }
   },
-
-  show: function show() {
-    this._grid.arrangeItems();
-  }
 };
--- a/browser/metro/base/content/startui/StartUI.js
+++ b/browser/metro/base/content/startui/StartUI.js
@@ -1,20 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 Cu.import("resource://gre/modules/Services.jsm");
 
-// When setting the max-height of the start tab contents, this is the buffer we subtract
-// for the nav bar plus white space above it.
-const kBottomContentMargin = 50;
-
 var StartUI = {
   get startUI() { return document.getElementById("start-container"); },
 
   get maxResultsPerSection() {
     return Services.prefs.getIntPref("browser.display.startUI.maxresults");
   },
 
   get chromeWin() {
@@ -25,47 +21,39 @@ var StartUI = {
   init: function init() {
     this.startUI.addEventListener("click", this, false);
     this.startUI.addEventListener("MozMousePixelScroll", this, false);
 
     // Update the input type on our local broadcaster
     document.getElementById("bcast_preciseInput").setAttribute("input",
       this.chromeWin.InputSourceHelper.isPrecise ? "precise" : "imprecise");
 
-    this._updateStartHeight();
     this._adjustDOMforViewState();
 
     TopSitesStartView.init();
     BookmarksStartView.init();
     HistoryStartView.init();
     RemoteTabsStartView.init();
 
-    TopSitesStartView.show();
-    BookmarksStartView.show();
-    HistoryStartView.show();
-    RemoteTabsStartView.show();
-
-    this.chromeWin.document.getElementById("browsers").addEventListener("SizeChanged", this, true);
     this.chromeWin.addEventListener("MozPrecisePointer", this, true);
     this.chromeWin.addEventListener("MozImprecisePointer", this, true);
     Services.obs.addObserver(this, "metro_viewstate_changed", false);
   },
 
   uninit: function() {
     if (TopSitesStartView)
       TopSitesStartView.uninit();
     if (BookmarksStartView)
       BookmarksStartView.uninit();
     if (HistoryStartView)
       HistoryStartView.uninit();
     if (RemoteTabsStartView)
       RemoteTabsStartView.uninit();
 
     if (this.chromeWin) {
-      this.chromeWin.document.getElementById("browsers").removeEventListener("SizeChanged", this, true);
       this.chromeWin.removeEventListener("MozPrecisePointer", this, true);
       this.chromeWin.removeEventListener("MozImprecisePointer", this, true);
     }
     Services.obs.removeObserver(this, "metro_viewstate_changed");
   },
 
   goToURI: function (aURI) {
     this.chromeWin.BrowserUI.goToURI(aURI);
@@ -103,36 +91,29 @@ var StartUI = {
         break;
       case "MozImprecisePointer":
         document.getElementById("bcast_preciseInput").setAttribute("input", "imprecise");
         break;
       case "click":
         this.onClick(aEvent);
         break;
       case "MozMousePixelScroll":
-        if (this.startUI.getAttribute("viewstate") == "snapped") {
+        let viewstate = this.startUI.getAttribute("viewstate");
+        if (viewstate === "snapped" || viewstate === "portrait") {
           window.scrollBy(0, aEvent.detail);
         } else {
           window.scrollBy(aEvent.detail, 0);
         }
 
         aEvent.preventDefault();
         aEvent.stopPropagation();
         break;
-      case "SizeChanged":
-        this._updateStartHeight();
-        break;
     }
   },
 
-  _updateStartHeight: function () {
-    document.getElementById("start-container").style.maxHeight =
-      (this.chromeWin.ContentAreaObserver.contentHeight - kBottomContentMargin) + "px";
-  },
-
   _adjustDOMforViewState: function() {
     if (this.chromeWin.MetroUtils.immersive) {
       let currViewState = "";
       switch (this.chromeWin.MetroUtils.snappedState) {
         case Ci.nsIWinMetroUtils.fullScreenLandscape:
           currViewState = "landscape";
           break;
         case Ci.nsIWinMetroUtils.fullScreenPortrait:
--- a/browser/metro/base/content/startui/TopSitesView.js
+++ b/browser/metro/base/content/startui/TopSitesView.js
@@ -306,13 +306,9 @@ let TopSitesStartView = {
     }
   },
 
   uninit: function uninit() {
     if (this._view) {
       this._view.destruct();
     }
   },
-
-  show: function show() {
-    this._grid.arrangeItems();
-  }
 };
--- a/browser/metro/modules/View.jsm
+++ b/browser/metro/modules/View.jsm
@@ -24,19 +24,28 @@ function makeURI(aURL, aOriginCharset, a
 // View prototype for shared functionality
 
 function View() {
 }
 
 View.prototype = {
   _adjustDOMforViewState: function _adjustDOMforViewState(aState) {
     if (this._set) {
-        if (undefined == aState)
-          aState = this._set.getAttribute("viewstate");
+      if (undefined == aState)
+        aState = this._set.getAttribute("viewstate");
+
       this._set.setAttribute("suppressonselect", (aState == "snapped"));
+
+      if (aState == "portrait") {
+        this._set.setAttribute("vertical", true);
+      } else {
+        this._set.removeAttribute("vertical");
+      }
+
+      this._set.arrangeItems();
     }
   },
 
   onViewStateChange: function (aState) {
     this._adjustDOMforViewState(aState);
   },
 
   _updateFavicon: function pv__updateFavicon(aItem, aUri) {
--- a/browser/metro/theme/browser.css
+++ b/browser/metro/theme/browser.css
@@ -185,37 +185,42 @@ documenttab[selected] .documenttab-selec
   padding: 18px 25px 30px;
 }
 
 /* Start UI ----------------------------------------------------------------- */
 
 #startui-page {
   overflow-x: scroll;
   overflow-y: hidden;
+  height: 100%;
 }
 
 #startui-body {
   height: 100%;
+  margin: 0;
 }
 
 #start-container {
   display: -moz-box;
   min-width: @grid_double_column_width@;
+  height: 100%;
+  width: 100%;
 }
 
 #start-topsites {
   /* allot space for 3 tile columns for the topsites grid */
   min-width: calc(3 * @grid_double_column_width@);
 }
 
 #content-viewport[startpage] browser {
   padding-bottom: @toolbar_height@;
 }
 
-#start-container[viewstate="snapped"] {
+#start-container[viewstate="snapped"],
+#start-container[viewstate="portrait"] {
   -moz-box-orient: vertical;
 }
 
 /*Formatting for the limited horizontal space of snapped*/
 #start-autocomplete[viewstate="snapped"] .richgrid-item-content {
   -moz-box-orient: horizontal;
 }
 
--- a/browser/metro/theme/defines.inc
+++ b/browser/metro/theme/defines.inc
@@ -39,16 +39,17 @@
 %define grid_row_height 86px
 %define grid_double_row_height 172px
 
 %define compactgrid_column_width 62px
 %define compactgrid_row_height 62px
 
 %define tile_border_color #dbdcde
 %define tile_spacing 12px
+%define tile_side_margin 6px
 
 %define scroller_thickness 4px
 %define scroller_minimum 8px
 
 %define metro_spacing_xsmall 3px
 %define metro_spacing_small 5px
 %define metro_spacing_snormal 10px
 %define metro_spacing_normal 15px
--- a/browser/metro/theme/platform.css
+++ b/browser/metro/theme/platform.css
@@ -619,16 +619,17 @@ arrowbox {
   width: 100%;
 }
 
 .meta-section {
   margin: 0 @metro_spacing_large@;
 }
 
 .meta-section-title {
+  margin: @metro_spacing_normal@ @tile_side_margin@;
   font-size: @metro_font_large@;
   font-weight: 100;
   cursor: default;
 }
 
 .meta-section:not([expanded]) > .meta-section-title.narrow-title:-moz-locale-dir(ltr):after {
   content: ">";
 }
--- a/browser/metro/theme/tiles.css
+++ b/browser/metro/theme/tiles.css
@@ -63,17 +63,17 @@ richgriditem {
   display: block;
   position: absolute;
   /* background-color colors the tile-edge,
      and will normally be overridden with a favicon-based color */
   background-color: #ccc;
   background-origin: padding-box;
   /* content positioning within the grid "cell"
      gives us the gutters/spacing between tiles */
-  top: 2px; right: 6px; bottom: 10px; left: 6px;
+  top: 2px; right: @tile_side_margin@; bottom: 10px; left: @tile_side_margin@;
   border: @metro_border_thin@ solid @tile_border_color@;
   box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1);
   transition: 150ms transform ease-out;
 }
 
 .tile-start-container {
   position: absolute;
   top: 0;