Bug 1279202 - Make sure that deferring a resize of a document schedules a layout flush, not just a style one. r=dbaron
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 14 Jul 2016 18:39:35 +1200
changeset 305002 8f6e45ae207fcf9365d4af9a78b22edaff6e3985
parent 304945 77bd53db031e18f025a25b95d44bc18db26983bd
child 305003 3ac9e026e72eff099c8deba43370b95907140492
push id30450
push usercbook@mozilla.com
push dateFri, 15 Jul 2016 14:15:45 +0000
treeherdermozilla-central@2f9e69c982f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs1279202
milestone50.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 1279202 - Make sure that deferring a resize of a document schedules a layout flush, not just a style one. r=dbaron
layout/base/tests/mochitest.ini
layout/base/tests/resize_flush_iframe.html
layout/base/tests/test_resize_flush.html
view/nsViewManager.cpp
--- a/layout/base/tests/mochitest.ini
+++ b/layout/base/tests/mochitest.ini
@@ -285,8 +285,11 @@ support-files = bug1226904.html
 [test_bug1278021.html]
 [test_transformed_scrolling_repaints.html]
 skip-if = buildapp == 'b2g'
 [test_transformed_scrolling_repaints_2.html]
 skip-if = buildapp == 'b2g'
 [test_transformed_scrolling_repaints_3.html]
 skip-if = buildapp == 'b2g'
 [test_frame_reconstruction_scroll_restore.html]
+[test_resize_flush.html]
+support-files =
+  resize_flush_iframe.html
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/resize_flush_iframe.html
@@ -0,0 +1,17 @@
+<html>
+<head>
+  <style>
+    body {
+      background-color: red;
+    }
+
+    @media (min-width: 250px) {
+      body {
+        background-color: green;
+      }
+    }
+  </style>
+</head>
+<body>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/test_resize_flush.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1279202
+-->
+<head>
+  <title>Test for Bug 1279202</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="run()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1279202">Mozilla Bug 1279202</a>
+<iframe src="resize_flush_iframe.html" id="iframe" height="200" width="200" style="border:none"></iframe>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 1279202 **/
+
+SimpleTest.waitForExplicitFinish();
+
+function run() {
+
+  var iframe = document.getElementById("iframe");
+  var doc = iframe.contentDocument.documentElement;
+  var win = iframe.contentWindow;
+  var body = iframe.contentDocument.body;
+
+  // Flush any pending layout changes before we start.
+  var width = doc.clientWidth;
+
+  // Resize the iframe
+  iframe.width = '300px';
+
+  // Flush pending style changes, but not layout ones. We do this twice because the first flush
+  // does a partial flush of the resize (setting the size on the pres context) which sets the
+  // need style flush flag again. The second call makes sure mNeedStyleFlush is false.
+  var color = win.getComputedStyle(body).getPropertyValue("background-color");
+  color = win.getComputedStyle(body).getPropertyValue("background-color");
+  is(color, "rgb(0, 128, 0)", "Style flush not completed when resizing an iframe!");
+
+  // Query the size of the inner document and make sure it has had a layout flush.
+  width = doc.clientWidth;
+
+  is(width, 300, "Layout flush not completed when resizing an iframe!");
+  SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
--- a/view/nsViewManager.cpp
+++ b/view/nsViewManager.cpp
@@ -224,17 +224,19 @@ nsViewManager::SetWindowDimensions(nscoo
         mDelayedResize = nsSize(aWidth, aHeight);
         FlushDelayedResize(false);
       }
       mDelayedResize.SizeTo(NSCOORD_NONE, NSCOORD_NONE);
       DoSetWindowDimensions(aWidth, aHeight);
     } else {
       mDelayedResize.SizeTo(aWidth, aHeight);
       if (mPresShell && mPresShell->GetDocument()) {
-        mPresShell->GetDocument()->SetNeedStyleFlush();
+        nsIDocument* doc = mPresShell->GetDocument();
+        doc->SetNeedStyleFlush();
+        doc->SetNeedLayoutFlush();
       }
     }
   }
 }
 
 void
 nsViewManager::FlushDelayedResize(bool aDoReflow)
 {