Bug 785588. Perform asynchronous scroll operations before firing requestAnimationFrame callbacks. r=tnikkel
authorRobert O'Callahan <robert@ocallahan.org>
Wed, 05 Sep 2012 22:29:15 +1200
changeset 104283 0b354d6a9c9085f2daef62c0633c6d3826bd8b9b
parent 104282 00d23ffe3105df7305452844baf1704ec8dbb331
child 104284 df1a1a1cfaf49840942f554500873c4befe6d071
push id23417
push userryanvm@gmail.com
push dateThu, 06 Sep 2012 02:27:31 +0000
treeherdermozilla-central@501f4e46a88c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs785588
milestone18.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 785588. Perform asynchronous scroll operations before firing requestAnimationFrame callbacks. r=tnikkel
layout/base/tests/Makefile.in
layout/base/tests/test_scroll_event_ordering.html
layout/generic/nsGfxScrollFrame.cpp
--- a/layout/base/tests/Makefile.in
+++ b/layout/base/tests/Makefile.in
@@ -128,16 +128,17 @@ MOCHITEST_FILES =	\
 		test_bug588174.html \
 		test_bug607529.html \
 		file_bug607529.html \
 		test_bug667512.html \
 		test_bug677878.html \
 		test_bug696020.html \
  		test_event_target_radius.html \
 		test_mozPaintCount.html \
+		test_scroll_event_ordering.html \
 		test_scroll_selection_into_view.html \
 		test_bug583889.html \
 		bug583889_inner1.html \
 		bug583889_inner2.html \
 		test_bug582771.html \
 		test_bug603550.html \
 		test_bug629838.html \
 		test_bug646757.html \
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/test_scroll_event_ordering.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=785588
+-->
+<head>
+  <title>Test for Bug 785588 --- ordering of scroll-related events</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=785588">Mozilla Bug 785588</a>
+<div id="content">
+  <div id="d" style="border:2px solid black; width:100px; height:100px; overflow:auto">
+    <div id="inner" style="height:200px;">Hello</div>
+  </div>
+</div>
+<pre id="test">
+<script>
+SimpleTest.waitForExplicitFinish();
+
+var smoothScrollPref = "general.smoothScroll";
+SpecialPowers.setBoolPref(smoothScrollPref, false);
+
+var d = document.getElementById("d");
+d.scrollTop = 0;
+var inner = document.getElementById("inner");
+
+var state = "initial";
+
+function onFrame() {
+  is(state, "initial", "Must be in initial state");
+  ok(d.scrollTop > 0, "Must have scrolled by some amount (got " + d.scrollTop + ")");
+  state = "didOnFrame";
+}
+
+function onScroll() {
+  is(state, "didOnFrame", "Must have got requestAnimationFrame callback already");
+  ok(d.scrollTop > 0, "Must have scrolled by some amount (got " + d.scrollTop + ")");
+  SpecialPowers.clearUserPref(smoothScrollPref);
+  SimpleTest.finish();
+}
+
+function doTest() {
+  window.getSelection().collapse(inner.firstChild, 0);
+  window.mozRequestAnimationFrame(onFrame);
+  d.onscroll = onScroll;
+  sendKey("DOWN");
+}
+
+SimpleTest.waitForFocus(doTest);
+</script>
+</pre>
+</body>
+</html>
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -1372,17 +1372,17 @@ public:
   /*
    * Set a refresh observer for smooth scroll iterations (and start observing).
    * Should be used at most once during the lifetime of this object.
    * Return value: true on success, false otherwise.
    */
   bool SetRefreshObserver(nsGfxScrollFrameInner *aCallee) {
     NS_ASSERTION(aCallee && !mCallee, "AsyncScroll::SetRefreshObserver - Invalid usage.");
 
-    if (!RefreshDriver(aCallee)->AddRefreshObserver(this, Flush_Display)) {
+    if (!RefreshDriver(aCallee)->AddRefreshObserver(this, Flush_Style)) {
       return false;
     }
 
     mCallee = aCallee;
     return true;
   }
 
   virtual void WillRefresh(mozilla::TimeStamp aTime) {
@@ -1400,17 +1400,17 @@ private:
 
   /* 
    * The refresh driver doesn't hold a reference to its observers,
    *   so releasing this object can (and is) used to remove the observer on DTOR.
    * Currently, this object is released once the scrolling ends.
    */
   void RemoveObserver() {
     if (mCallee) {
-      RefreshDriver(mCallee)->RemoveRefreshObserver(this, Flush_Display);
+      RefreshDriver(mCallee)->RemoveRefreshObserver(this, Flush_Style);
     }
   }
 };
 
 nsPoint
 nsGfxScrollFrameInner::AsyncScroll::PositionAt(TimeStamp aTime) {
   double progressX = mTimingFunctionX.GetSplineValue(ProgressAt(aTime));
   double progressY = mTimingFunctionY.GetSplineValue(ProgressAt(aTime));