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 143857 606d259eafe96e174a24405d0155aa23eac0a0e5
parent 143856 d5c5d4cb5fa6257179699e470f023a4d335d8eb5
child 143858 349208bd639773779a13401833b92cf2cbf441b2
push id25142
push userryanvm@gmail.com
push dateThu, 22 Aug 2013 19:34:20 +0000
treeherdermozilla-central@1b26ad79d831 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfoster
bugs903178
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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;