зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1316101 - Avoid excessive clamping in StickyScrollContainer::GetScrollRanges(). r=mstange
Excessive clamping can cause incorrect behaviour in the presence of negative margins. MozReview-Commit-ID: AkQEqcQpAxx --HG-- extra : rebase_source : 33cde31c15608792299a1dbef475e0fe0936270d
This commit is contained in:
Родитель
ed42034845
Коммит
cdbef9ee0c
|
@ -283,16 +283,7 @@ StickyScrollContainer::GetScrollRanges(nsIFrame* aFrame, nsRect* aOuter,
|
|||
aOuter->SetRect(nscoord_MIN/2, nscoord_MIN/2, nscoord_MAX, nscoord_MAX);
|
||||
aInner->SetRect(nscoord_MIN/2, nscoord_MIN/2, nscoord_MAX, nscoord_MAX);
|
||||
|
||||
// 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());
|
||||
const nsPoint normalPosition = firstCont->GetNormalPosition();
|
||||
|
||||
// Bottom and top
|
||||
if (stick.YMost() != nscoord_MAX/2) {
|
||||
|
@ -315,6 +306,17 @@ StickyScrollContainer::GetScrollRanges(nsIFrame* aFrame, nsRect* aOuter,
|
|||
aInner->SetRightEdge(normalPosition.x - stick.x);
|
||||
aOuter->SetRightEdge(contain.XMost() - stick.x);
|
||||
}
|
||||
|
||||
// Make sure |inner| does not extend outside of |outer|. (The consumers of
|
||||
// the Layers API, to which this information is propagated, expect this
|
||||
// invariant to hold.) The calculated value of |inner| can sometimes extend
|
||||
// outside of |outer|, for example due to margin collapsing, since
|
||||
// GetNormalPosition() returns the actual position after margin collapsing,
|
||||
// while |contain| is calculated based on the frame's GetUsedMargin() which
|
||||
// is pre-collapsing.
|
||||
// Note that this doesn't necessarily solve all problems stemming from
|
||||
// comparing pre- and post-collapsing margins (TODO: find a proper solution).
|
||||
*aInner = aInner->Intersect(*aOuter);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -26,6 +26,7 @@ skip-if(!asyncPan) == split-layers-multi-scrolling-1.html split-layers-multi-scr
|
|||
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) == sticky-pos-scrollable-3.html sticky-pos-scrollable-3-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
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<style>
|
||||
#header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
}
|
||||
#header > div {
|
||||
border: solid blue 2px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
</style>
|
||||
<div id="section">
|
||||
<div id="header">
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
</html>
|
|
@ -0,0 +1,33 @@
|
|||
<!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>
|
||||
html {
|
||||
overflow: hidden;
|
||||
}
|
||||
#section {
|
||||
padding-top: 1px;
|
||||
}
|
||||
#header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
#header > div {
|
||||
margin-top: -50px;
|
||||
border: solid blue 2px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
#spacer {
|
||||
height: 1500px;
|
||||
}
|
||||
</style>
|
||||
<div id="section">
|
||||
<div id="header">
|
||||
<div></div>
|
||||
</div>
|
||||
<div id="spacer"></div>
|
||||
</div>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче