Bug 1293125 - Work around a layout issue that causes StickyScrollContainer::GetScrollRanges() to compute malformed rects. r=mstange
authorBotond Ballo <botond@mozilla.com>
Fri, 07 Oct 2016 19:31:14 -0400
changeset 318110 99a36fecb7ab1c6dc56647ec17cd0862ff57fe59
parent 318109 0f39b7305d41a70759f6cae8571fba860a0d3b65
child 318111 5cd71fa73ba0b316e3cca927a81802f5e01219c9
push id30830
push usercbook@mozilla.com
push dateMon, 17 Oct 2016 09:19:24 +0000
treeherdermozilla-central@94b0fddf96b4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1293125
milestone52.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 1293125 - Work around a layout issue that causes StickyScrollContainer::GetScrollRanges() to compute malformed rects. r=mstange MozReview-Commit-ID: IClxdc8tfBh
layout/generic/StickyScrollContainer.cpp
layout/reftests/async-scrolling/reftest.list
layout/reftests/async-scrolling/sticky-pos-scrollable-2-ref.html
layout/reftests/async-scrolling/sticky-pos-scrollable-2.html
--- a/layout/generic/StickyScrollContainer.cpp
+++ b/layout/generic/StickyScrollContainer.cpp
@@ -278,17 +278,26 @@ StickyScrollContainer::GetScrollRanges(n
 
   nsRect stick;
   nsRect contain;
   ComputeStickyLimits(firstCont, &stick, &contain);
 
   aOuter->SetRect(nscoord_MIN/2, nscoord_MIN/2, nscoord_MAX, nscoord_MAX);
   aInner->SetRect(nscoord_MIN/2, nscoord_MIN/2, nscoord_MAX, nscoord_MAX);
 
-  const nsPoint normalPosition = firstCont->GetNormalPosition();
+  // Due to margin collapsing, |firstCont->GetNormalPosition()| can sometimes
+  // fall outside of |contain|. (This is because GetNormalPosition() returns
+  // the actual position after margin collapsing, while|contain| is
+  // calculated based on the frame's GetUsedMargin() which is pre-collapsing.)
+  // This can cause |aInner|, as computed below, to not be contained inside
+  // |aOuter|, which confuses the code that consumes these values.
+  // This is hard to fix properly (TODO), but clamping |normalPosition| to
+  // |contain| works around it.
+  const nsPoint normalPosition =
+      contain.ClampPoint(firstCont->GetNormalPosition());
 
   // Bottom and top
   if (stick.YMost() != nscoord_MAX/2) {
     aOuter->SetTopEdge(contain.y - stick.YMost());
     aInner->SetTopEdge(normalPosition.y - stick.YMost());
   }
 
   if (stick.y != nscoord_MIN/2) {
--- a/layout/reftests/async-scrolling/reftest.list
+++ b/layout/reftests/async-scrolling/reftest.list
@@ -20,16 +20,17 @@ skip-if(!asyncPan) == position-fixed-bod
 skip-if(!asyncPan) == position-fixed-cover-1.html position-fixed-cover-1-ref.html
 skip-if(!asyncPan) == position-fixed-cover-2.html position-fixed-cover-2-ref.html
 skip-if(!asyncPan) == position-fixed-cover-3.html position-fixed-cover-3-ref.html
 fuzzy-if(Android,5,4) skip-if(!asyncPan) == position-fixed-transformed-1.html position-fixed-transformed-1-ref.html
 skip-if(!asyncPan) == split-layers-1.html split-layers-1-ref.html
 skip-if(!asyncPan) == split-layers-multi-scrolling-1.html split-layers-multi-scrolling-1-ref.html
 fuzzy-if(skiaContent,2,240000) fuzzy-if(browserIsRemote&&!skiaContent&&(cocoaWidget||winWidget),1,240000) skip-if(!asyncPan) == split-opacity-layers-1.html split-opacity-layers-1-ref.html
 skip-if(!asyncPan) == sticky-pos-scrollable-1.html sticky-pos-scrollable-1-ref.html
+skip-if(!asyncPan) == sticky-pos-scrollable-2.html sticky-pos-scrollable-2-ref.html
 skip-if(!asyncPan) == fixed-pos-scrollable-1.html fixed-pos-scrollable-1-ref.html
 skip-if(!asyncPan) == culling-1.html culling-1-ref.html
 skip-if(!asyncPan) == position-fixed-iframe-1.html position-fixed-iframe-1-ref.html
 skip-if(!asyncPan) == position-fixed-iframe-2.html position-fixed-iframe-2-ref.html
 fuzzy-if(skiaContent,1,11300) skip-if(!asyncPan) == position-fixed-in-scroll-container.html position-fixed-in-scroll-container-ref.html
 skip-if(!asyncPan) == position-fixed-inside-sticky-1.html position-fixed-inside-sticky-1-ref.html
 skip-if(!asyncPan) == position-fixed-inside-sticky-2.html position-fixed-inside-sticky-2-ref.html
 fuzzy(1,60000) skip-if(!asyncPan) == group-opacity-surface-size-1.html group-opacity-surface-size-1-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/async-scrolling/sticky-pos-scrollable-2-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<style>
+body {
+  margin: 0;
+  height: 4000px;
+  overflow: hidden;
+}
+div {
+  background: blue;
+  width: 200px;
+  height: 200px;
+  margin-top: 300px;
+  position: sticky;
+  bottom: 100px;
+}
+</style>
+<div></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/async-scrolling/sticky-pos-scrollable-2.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html reftest-async-scroll
+      reftest-displayport-x="0" reftest-displayport-y="0"
+      reftest-displayport-w="800" reftest-displayport-h="2000"
+      reftest-async-scroll-x="0" reftest-async-scroll-y="100">
+<style>
+body {
+  margin: 0;
+  height: 4000px;
+  overflow: hidden;
+}
+div {
+  background: blue;
+  width: 200px;
+  height: 200px;
+  margin-top: 400px;
+  position: sticky;
+  bottom: 100px;
+}
+</style>
+<div></div>