Bug 810981 - Part 3 - Recalculate zoom level before restoring to a different screen orientation. r=kats
authorJan Henning <jh+bugzilla@buttercookie.de>
Wed, 18 May 2016 22:53:34 +0200
changeset 340533 b37f2c10a77781e648367c21a66ff7e2e81cd848
parent 340532 b92caaa61e809cc93e560c1fb9416e86446ed939
child 340534 8682f94befeb413bafc9e434d3cb387b1ce567d5
push id1183
push userraliiev@mozilla.com
push dateMon, 05 Sep 2016 20:01:49 +0000
treeherdermozilla-release@3148731bed45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs810981
milestone49.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 810981 - Part 3 - Recalculate zoom level before restoring to a different screen orientation. r=kats On pages that aren't "width=device-width" or similar, Gecko adjusts the resolution when the display dimensions change, e.g. because the device has been rotated. The session store needs to do something similar when restoring a page if the device orientation has changed since the moment the tab state was captured. Therefore, we now include the width of the browser window in the saved zoom data and use it to scale the zoom level as necessary when restoring a tab. MozReview-Commit-ID: LBbEquO1bZ9
mobile/android/components/SessionStore.js
--- a/mobile/android/components/SessionStore.js
+++ b/mobile/android/components/SessionStore.js
@@ -699,22 +699,49 @@ SessionStore.prototype = {
     // Save the current document resolution.
     let zoom = { value: 1 };
     content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(
       Ci.nsIDOMWindowUtils).getResolution(zoom);
     scrolldata.zoom = {};
     scrolldata.zoom.resolution = zoom.value;
     log("onTabScroll() zoom level: " + zoom.value);
 
+    // Save some data that'll help in adjusting the zoom level
+    // when restoring in a different screen orientation.
+    let viewportInfo = this._getViewportInfo(aWindow.outerWidth, aWindow.outerHeight, content);
+    scrolldata.zoom.autoSize = viewportInfo.autoSize;
+    log("onTabScroll() autoSize: " + scrolldata.zoom.autoSize);
+    scrolldata.zoom.windowWidth = aWindow.outerWidth;
+    log("onTabScroll() windowWidth: " + scrolldata.zoom.windowWidth);
+
     // Save zoom and scroll data.
     data.scrolldata = scrolldata;
     log("onTabScroll() ran for tab " + aWindow.BrowserApp.getTabForBrowser(aBrowser).id);
     this.saveStateDelayed();
   },
 
+  _getViewportInfo: function ss_getViewportInfo(aDisplayWidth, aDisplayHeight, aWindow) {
+    let viewportInfo = {};
+    let defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom ={},
+        width = {}, height = {}, autoSize = {};
+    aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(
+      Ci.nsIDOMWindowUtils).getViewportInfo(aDisplayWidth, aDisplayHeight,
+        defaultZoom, allowZoom, minZoom, maxZoom, width, height, autoSize);
+
+    viewportInfo.defaultZoom = defaultZoom.value;
+    viewportInfo.allowZoom = allowZoom.value;
+    viewportInfo.minZoom = maxZoom.value;
+    viewportInfo.maxZoom = maxZoom.value;
+    viewportInfo.width = width.value;
+    viewportInfo.height = height.value;
+    viewportInfo.autoSize = autoSize.value;
+
+    return viewportInfo;
+  },
+
   saveStateDelayed: function ss_saveStateDelayed() {
     if (!this._saveTimer) {
       // Interval until the next disk operation is allowed
       let minimalDelay = this._lastSaveTime + this._interval - Date.now();
 
       // If we have to wait, set a timer, otherwise saveState directly
       let delay = Math.max(minimalDelay, 2000);
       if (delay > 0) {
@@ -1309,25 +1336,46 @@ SessionStore.prototype = {
   },
 
   /**
   * Restores the zoom level of the window. This needs to be called before
   * first paint/load (whichever comes first) to take any effect.
   */
   _restoreZoom: function ss_restoreZoom(aScrollData, aBrowser) {
     if (aScrollData && aScrollData.zoom) {
-      log("_restoreZoom(), resolution: " + aScrollData.zoom.resolution);
+      let recalculatedZoom = this._recalculateZoom(aScrollData.zoom);
+      log("_restoreZoom(), resolution: " + recalculatedZoom);
+
       let utils = aBrowser.contentWindow.QueryInterface(
         Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
       // Restore zoom level.
-      utils.setRestoreResolution(aScrollData.zoom.resolution);
+      utils.setRestoreResolution(recalculatedZoom);
     }
   },
 
   /**
+  * Recalculates the zoom level to account for a changed display width,
+  * e.g. because the device was rotated.
+  */
+  _recalculateZoom: function ss_recalculateZoom(aZoomData) {
+    let browserWin = Services.wm.getMostRecentWindow("navigator:browser");
+
+    // Pages with "width=device-width" won't need any zoom level scaling.
+    if (!aZoomData.autoSize) {
+      let oldWidth = aZoomData.windowWidth;
+      let newWidth = browserWin.outerWidth;
+      if (oldWidth != newWidth && oldWidth > 0 && newWidth > 0) {
+        log("_recalculateZoom(), old resolution: " + aZoomData.resolution);
+        return newWidth / oldWidth * aZoomData.resolution;
+      }
+    }
+    return aZoomData.resolution;
+  },
+
+  /**
   * Takes serialized scroll positions and restores them into the given browser.
   */
   _restoreScrollPosition: function ss_restoreScrollPosition(aScrollData, aBrowser) {
     if (aScrollData) {
       log("_restoreScrollPosition()");
       ScrollPosition.restoreTree(aBrowser.contentWindow, aScrollData);
     }
   },