mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 830479. Account for multiple fixed elements acting as headers and footers when doing full page scrolling. r=roc
This commit is contained in:
parent
f42b71d1b6
commit
db9d763d93
@ -2350,34 +2350,73 @@ nsGfxScrollFrameInner::GetLineScrollAmount() const
|
||||
* Compute the scrollport size excluding any fixed-pos headers and
|
||||
* footers. A header or footer is an box that spans that entire width
|
||||
* of the viewport and touches the top (or bottom, respectively) of the
|
||||
* viewport. Headers and footers that cover more than a quarter of the
|
||||
* the viewport are ignored since they probably aren't true headers and
|
||||
* footers and we don't want to restrict scrolling too much in such cases.
|
||||
* This is a bit conservative --- some pages use elements as headers or
|
||||
* footers that don't span the entire width of the viewport --- but it
|
||||
* should be a good start.
|
||||
* viewport. We also want to consider fixed elements that stack or overlap
|
||||
* to effectively create a larger header or footer. Headers and footers that
|
||||
* cover more than a third of the the viewport are ignored since they
|
||||
* probably aren't true headers and footers and we don't want to restrict
|
||||
* scrolling too much in such cases. This is a bit conservative --- some
|
||||
* pages use elements as headers or footers that don't span the entire width
|
||||
* of the viewport --- but it should be a good start.
|
||||
*/
|
||||
struct TopAndBottom
|
||||
{
|
||||
TopAndBottom(nscoord aTop, nscoord aBottom) : top(aTop), bottom(aBottom) {}
|
||||
|
||||
nscoord top, bottom;
|
||||
};
|
||||
struct TopComparator
|
||||
{
|
||||
bool Equals(const TopAndBottom& A, const TopAndBottom& B) const {
|
||||
return A.top == B.top;
|
||||
}
|
||||
bool LessThan(const TopAndBottom& A, const TopAndBottom& B) const {
|
||||
return A.top < B.top;
|
||||
}
|
||||
};
|
||||
struct ReverseBottomComparator
|
||||
{
|
||||
bool Equals(const TopAndBottom& A, const TopAndBottom& B) const {
|
||||
return A.bottom == B.bottom;
|
||||
}
|
||||
bool LessThan(const TopAndBottom& A, const TopAndBottom& B) const {
|
||||
return A.bottom > B.bottom;
|
||||
}
|
||||
};
|
||||
static nsSize
|
||||
GetScrollPortSizeExcludingHeadersAndFooters(nsIFrame* aViewportFrame,
|
||||
const nsRect& aScrollPort)
|
||||
{
|
||||
nsTArray<TopAndBottom> list;
|
||||
nsFrameList fixedFrames = aViewportFrame->GetChildList(nsIFrame::kFixedList);
|
||||
nscoord headerBottom = 0;
|
||||
nscoord footerTop = aScrollPort.height;
|
||||
for (nsFrameList::Enumerator iterator(fixedFrames); !iterator.AtEnd();
|
||||
iterator.Next()) {
|
||||
nsIFrame* f = iterator.get();
|
||||
nsRect r = f->GetRect().Intersect(aScrollPort);
|
||||
if (r.x == 0 && r.width == aScrollPort.width &&
|
||||
r.height <= aScrollPort.height/3) {
|
||||
if (r.y == 0) {
|
||||
headerBottom = std::max(headerBottom, r.height);
|
||||
}
|
||||
if (r.YMost() == aScrollPort.height) {
|
||||
footerTop = std::min(footerTop, r.y);
|
||||
}
|
||||
list.AppendElement(TopAndBottom(r.y, r.YMost()));
|
||||
}
|
||||
}
|
||||
|
||||
list.Sort(TopComparator());
|
||||
nscoord headerBottom = 0;
|
||||
for (int32_t i = 0; i < list.Length(); ++i) {
|
||||
if (list[i].top <= headerBottom) {
|
||||
headerBottom = std::max(headerBottom, list[i].bottom);
|
||||
}
|
||||
}
|
||||
|
||||
list.Sort(ReverseBottomComparator());
|
||||
nscoord footerTop = aScrollPort.height;
|
||||
for (int32_t i = 0; i < list.Length(); ++i) {
|
||||
if (list[i].bottom >= footerTop) {
|
||||
footerTop = std::min(footerTop, list[i].top);
|
||||
}
|
||||
}
|
||||
|
||||
headerBottom = std::min(aScrollPort.height/3, headerBottom);
|
||||
footerTop = std::max(aScrollPort.height - aScrollPort.height/3, footerTop);
|
||||
|
||||
return nsSize(aScrollPort.width, footerTop - headerBottom);
|
||||
}
|
||||
|
||||
|
@ -4,11 +4,14 @@
|
||||
<title>Scrolling by pages with fixed-pos headers and footers</title>
|
||||
<style>
|
||||
.fp { position:fixed; left:0; width:100%; }
|
||||
.fp2 { position:fixed; left:0; width:100%; }
|
||||
</style>
|
||||
</head>
|
||||
<body onscroll="didScroll()" onload="test()">
|
||||
<div class="fp" id="top" style="top:0; height:10px; background:yellow;"></div>
|
||||
<div class="fp2" id="top2" style="top:10px; height:11px; background:blue;"></div>
|
||||
<div class="fp" style="top:50%; height:7px; background:cyan;"></div>
|
||||
<div class="fp2" id="bottom2" style="bottom:9px; height:12px; background:red;"></div>
|
||||
<div class="fp" id="bottom" style="bottom:0; height:13px; background:yellow;"></div>
|
||||
<p id="target">Something to click on to get focus
|
||||
<div style="height:3000px;"></div>
|
||||
@ -18,12 +21,18 @@ var SimpleTest = window.opener.SimpleTest;
|
||||
var SpecialPowers = window.opener.SpecialPowers;
|
||||
var is = window.opener.is;
|
||||
|
||||
function showFixedPosElements(show) {
|
||||
var elements = document.getElementsByClassName("fp");
|
||||
function showElements(show, classname) {
|
||||
var elements = document.getElementsByClassName(classname);
|
||||
for (var i = 0; i < elements.length; ++i) {
|
||||
elements[i].style.display = show ? '' : 'none';
|
||||
}
|
||||
}
|
||||
function showFixedPosElements(show) {
|
||||
showElements(show, "fp");
|
||||
}
|
||||
function showFixedPosElements2(show) {
|
||||
showElements(show, "fp2");
|
||||
}
|
||||
|
||||
var nextCont;
|
||||
function didScroll() {
|
||||
@ -45,6 +54,7 @@ function test() {
|
||||
SpecialPowers.setBoolPref(smoothScrollPref, false);
|
||||
|
||||
showFixedPosElements(false);
|
||||
showFixedPosElements2(false);
|
||||
scrollDownOnePageWithContinuation(function() {
|
||||
var fullPageScrollDown = document.documentElement.scrollTop;
|
||||
|
||||
@ -64,12 +74,19 @@ function test() {
|
||||
scrollDownOnePageWithContinuation(function() {
|
||||
is(document.documentElement.scrollTop, fullPageScrollDown - 13,
|
||||
"Ignore elements that don't span the entire viewport side");
|
||||
|
||||
// Scroll back up so test results are visible
|
||||
document.documentElement.scrollTop = 0;
|
||||
SpecialPowers.clearUserPref(smoothScrollPref);
|
||||
SimpleTest.finish();
|
||||
window.close();
|
||||
document.getElementById("top").style.width = "100%";
|
||||
|
||||
showFixedPosElements2(true);
|
||||
scrollDownOnePageWithContinuation(function() {
|
||||
is(document.documentElement.scrollTop, fullPageScrollDown - (10 + 11 + 9 + 12),
|
||||
"Combine multiple overlapping elements");
|
||||
|
||||
// Scroll back up so test results are visible
|
||||
document.documentElement.scrollTop = 0;
|
||||
SpecialPowers.clearUserPref(smoothScrollPref);
|
||||
SimpleTest.finish();
|
||||
window.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user