Bug 940889 - Set the scroll port size along with the CSS viewport to ensure content gets the latest innerWidth. r=Cwiiis a=lsblakk
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 16 Dec 2013 09:53:56 -0500
changeset 175562 155e55d2d1f242d0a759037858d68b4ac841ff2f
parent 175561 7bb1fe039670cad0c79bcb743a65f97beed10e1c
child 175563 d2f01f6e38d810d2c9a608c3af8864812dc22d15
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersCwiiis, lsblakk
bugs940889
milestone28.0a2
Bug 940889 - Set the scroll port size along with the CSS viewport to ensure content gets the latest innerWidth. r=Cwiiis a=lsblakk
mobile/android/chrome/content/browser.js
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -3975,16 +3975,33 @@ Tab.prototype = {
     // the page is zoomed out to show its full width. Note that before
     // we set the viewport width, the "full width" of the page isn't properly
     // defined, so that's why we have to call setBrowserSize twice - once
     // to set the width, and the second time to figure out the height based
     // on the layout at that width.
     let oldBrowserWidth = this.browserWidth;
     this.setBrowserSize(viewportW, viewportH);
 
+    // This change to the zoom accounts for all types of changes I can conceive:
+    // 1. screen size changes, CSS viewport does not (pages with no meta viewport
+    //    or a fixed size viewport)
+    // 2. screen size changes, CSS viewport also does (pages with a device-width
+    //    viewport)
+    // 3. screen size remains constant, but CSS viewport changes (meta viewport
+    //    tag is added or removed)
+    // 4. neither screen size nor CSS viewport changes
+    //
+    // In all of these cases, we maintain how much actual content is visible
+    // within the screen width. Note that "actual content" may be different
+    // with respect to CSS pixels because of the CSS viewport size changing.
+    let zoomScale = (screenW * oldBrowserWidth) / (aOldScreenWidth * viewportW);
+    let zoom = (aInitialLoad && metadata.defaultZoom) ? metadata.defaultZoom : this.clampZoom(this._zoom * zoomScale);
+    this.setResolution(zoom, false);
+    this.setScrollClampingSize(zoom);
+
     // if this page has not been painted yet, then this must be getting run
     // because a meta-viewport element was added (via the DOMMetaAdded handler).
     // in this case, we should not do anything that forces a reflow (see bug 759678)
     // such as requesting the page size or sending a viewport update. this code
     // will get run again in the before-first-paint handler and that point we
     // will run though all of it. the reason we even bother executing up to this
     // point on the DOMMetaAdded handler is so that scripts that use window.innerWidth
     // before they are painted have a correct value (bug 771575).
@@ -4011,39 +4028,30 @@ Tab.prototype = {
         screenH = gScreenHeight;
         this.viewportExcludesVerticalMargins = false;
       }
 
       minScale = screenW / pageWidth;
     }
     minScale = this.clampZoom(minScale);
     viewportH = Math.max(viewportH, screenH / minScale);
+
+    // In general we want to keep calls to setBrowserSize and setScrollClampingSize
+    // together because setBrowserSize could mark the viewport size as dirty, creating
+    // a pending resize event for content. If that resize gets dispatched (which happens
+    // on the next reflow) without setScrollClampingSize having being called, then
+    // content might be exposed to incorrect innerWidth/innerHeight values.
     this.setBrowserSize(viewportW, viewportH);
+    this.setScrollClampingSize(zoom);
 
     // Avoid having the scroll position jump around after device rotation.
     let win = this.browser.contentWindow;
     this.userScrollPos.x = win.scrollX;
     this.userScrollPos.y = win.scrollY;
 
-    // This change to the zoom accounts for all types of changes I can conceive:
-    // 1. screen size changes, CSS viewport does not (pages with no meta viewport
-    //    or a fixed size viewport)
-    // 2. screen size changes, CSS viewport also does (pages with a device-width
-    //    viewport)
-    // 3. screen size remains constant, but CSS viewport changes (meta viewport
-    //    tag is added or removed)
-    // 4. neither screen size nor CSS viewport changes
-    //
-    // In all of these cases, we maintain how much actual content is visible
-    // within the screen width. Note that "actual content" may be different
-    // with respect to CSS pixels because of the CSS viewport size changing.
-    let zoomScale = (screenW * oldBrowserWidth) / (aOldScreenWidth * viewportW);
-    let zoom = (aInitialLoad && metadata.defaultZoom) ? metadata.defaultZoom : this.clampZoom(this._zoom * zoomScale);
-    this.setResolution(zoom, false);
-    this.setScrollClampingSize(zoom);
     this.sendViewportUpdate();
 
     // Store the page size that was used to calculate the viewport so that we
     // can verify it's changed when we consider remeasuring in updateViewportForPageSize
     let viewport = this.getViewport();
     this.lastPageSizeAfterViewportRemeasure = {
       width: viewport.pageRight - viewport.pageLeft,
       height: viewport.pageBottom - viewport.pageTop