mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-23 13:04:28 +00:00
Bug 780345. Use a heuristic to reduce the scroll-port height by the height of fixed-position headers and footers when scrolling the viewport vertically by pages. r=tnikkel
--HG-- extra : rebase_source : 0f6d4a64b2f3832deb2af1f9ae0d332db042e127
This commit is contained in:
parent
d2d218e577
commit
9adec2a25b
@ -2556,15 +2556,62 @@ nsGfxScrollFrameInner::GetLineScrollAmount() const
|
||||
return nsSize(fontHeight, fontHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
static nsSize
|
||||
GetScrollPortSizeExcludingHeadersAndFooters(nsIFrame* aViewportFrame,
|
||||
const nsRect& aScrollPort)
|
||||
{
|
||||
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 = NS_MAX(headerBottom, r.height);
|
||||
}
|
||||
if (r.YMost() == aScrollPort.height) {
|
||||
footerTop = NS_MIN(footerTop, r.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nsSize(aScrollPort.width, footerTop - headerBottom);
|
||||
}
|
||||
|
||||
nsSize
|
||||
nsGfxScrollFrameInner::GetPageScrollAmount() const
|
||||
{
|
||||
nsSize lineScrollAmount = GetLineScrollAmount();
|
||||
nsSize effectiveScrollPortSize;
|
||||
if (mIsRoot) {
|
||||
// Reduce effective scrollport height by the height of any fixed-pos
|
||||
// headers or footers
|
||||
nsIFrame* root = mOuter->PresContext()->PresShell()->GetRootFrame();
|
||||
effectiveScrollPortSize =
|
||||
GetScrollPortSizeExcludingHeadersAndFooters(root, mScrollPort);
|
||||
} else {
|
||||
effectiveScrollPortSize = mScrollPort.Size();
|
||||
}
|
||||
// The page increment is the size of the page, minus the smaller of
|
||||
// 10% of the size or 2 lines.
|
||||
return nsSize(
|
||||
mScrollPort.width - NS_MIN(mScrollPort.width/10, 2*lineScrollAmount.width),
|
||||
mScrollPort.height - NS_MIN(mScrollPort.height/10, 2*lineScrollAmount.height));
|
||||
effectiveScrollPortSize.width -
|
||||
NS_MIN(effectiveScrollPortSize.width/10, 2*lineScrollAmount.width),
|
||||
effectiveScrollPortSize.height -
|
||||
NS_MIN(effectiveScrollPortSize.height/10, 2*lineScrollAmount.height));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,6 +65,8 @@ MOCHITEST_FILES = \
|
||||
test_invalidate_during_plugin_paint.html \
|
||||
test_movement_by_characters.html \
|
||||
test_movement_by_words.html \
|
||||
test_page_scroll_with_fixed_pos.html \
|
||||
page_scroll_with_fixed_pos_window.html \
|
||||
test_plugin_clipping.xhtml \
|
||||
test_plugin_clipping2.xhtml \
|
||||
test_plugin_clipping_transformed.xhtml \
|
||||
|
81
layout/generic/test/page_scroll_with_fixed_pos_window.html
Normal file
81
layout/generic/test/page_scroll_with_fixed_pos_window.html
Normal file
@ -0,0 +1,81 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Scrolling by pages with fixed-pos headers and footers</title>
|
||||
<style>
|
||||
.fp { 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="fp" style="top:50%; height:7px; background:cyan;"></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>
|
||||
<pre id="test">
|
||||
<script class="testbody">
|
||||
var SimpleTest = window.opener.SimpleTest;
|
||||
var SpecialPowers = window.opener.SpecialPowers;
|
||||
var is = window.opener.is;
|
||||
|
||||
function showFixedPosElements(show) {
|
||||
var elements = document.getElementsByClassName("fp");
|
||||
for (var i = 0; i < elements.length; ++i) {
|
||||
elements[i].style.display = show ? '' : 'none';
|
||||
}
|
||||
}
|
||||
|
||||
var nextCont;
|
||||
function didScroll() {
|
||||
var c = nextCont;
|
||||
nextCont = null;
|
||||
if (c) {
|
||||
c();
|
||||
}
|
||||
}
|
||||
|
||||
function scrollDownOnePageWithContinuation(cont) {
|
||||
document.documentElement.scrollTop = 0;
|
||||
nextCont = cont;
|
||||
window.scrollByPages(1);
|
||||
}
|
||||
|
||||
function test() {
|
||||
var smoothScrollPref = "general.smoothScroll";
|
||||
SpecialPowers.setBoolPref(smoothScrollPref, false);
|
||||
|
||||
showFixedPosElements(false);
|
||||
scrollDownOnePageWithContinuation(function() {
|
||||
var fullPageScrollDown = document.documentElement.scrollTop;
|
||||
|
||||
showFixedPosElements(true);
|
||||
scrollDownOnePageWithContinuation(function() {
|
||||
var fullPageScrollDownWithHeaderAndFooter = document.documentElement.scrollTop;
|
||||
is(fullPageScrollDownWithHeaderAndFooter, fullPageScrollDown - (10 + 13),
|
||||
"Reduce scroll distance by size of small header and footer");
|
||||
|
||||
document.getElementById("bottom").style.height = (window.innerHeight - 20) + "px";
|
||||
scrollDownOnePageWithContinuation(function() {
|
||||
is(document.documentElement.scrollTop, fullPageScrollDown - 10,
|
||||
"Ignore really big elements when reducing scroll size");
|
||||
document.getElementById("bottom").style.height = "13px";
|
||||
|
||||
document.getElementById("top").style.width = "100px";
|
||||
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();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
16
layout/generic/test/test_page_scroll_with_fixed_pos.html
Normal file
16
layout/generic/test/test_page_scroll_with_fixed_pos.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Scrolling by pages with fixed-pos headers and footers</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<script class="testbody">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
window.open("./page_scroll_with_fixed_pos_window.html", "", "width=600,height=600");
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user