зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1379458) for causing reftest failures on nsDisplayList.cpp CLOSED TREE
Backed out changeset 1d37427ef6f2 (bug 1379458) Backed out changeset 54494d5e152c (bug 1379458) Backed out changeset e1347c761038 (bug 1379458)
This commit is contained in:
Родитель
ced6135bf5
Коммит
d82d2ab676
|
@ -1,88 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>APZ overscroll handoff for fixed elements</title>
|
||||
<script type="application/javascript" src="apz_test_utils.js"></script>
|
||||
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
|
||||
<script src="/tests/SimpleTest/paint_listener.js"></script>
|
||||
<meta name="viewport" content="width=device-width"/>
|
||||
<style>
|
||||
html, body {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#main {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#spacer {
|
||||
height: 5000px;
|
||||
}
|
||||
|
||||
#fixed {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
background: red;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#long {
|
||||
height: 250px;
|
||||
width: 50%;
|
||||
position: absolute;
|
||||
background: green;
|
||||
top: 0;
|
||||
left: 25%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
<div id="spacer">
|
||||
</div>
|
||||
<div id="fixed">
|
||||
<div id="long">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="application/javascript">
|
||||
|
||||
async function test() {
|
||||
// Scroll to the bottom of the fixed position element that should not
|
||||
// allow overscroll handoff.
|
||||
fixed.scrollTop = fixed.scrollHeight;
|
||||
|
||||
// After scrolling to bottom tick the refresh driver.
|
||||
await promiseFrame();
|
||||
|
||||
info("Start: fixed=" + fixed.scrollTop + " main=" + main.scrollTop);
|
||||
|
||||
// Async scroll the fixed element by 200 pixels using the mouse-wheel.
|
||||
// This should not handoff the overscroll.
|
||||
await promiseMoveMouseAndScrollWheelOver(fixed, 50, 50, false, 200);
|
||||
|
||||
// Make sure scrolling that has happened is propagated to the main thread.
|
||||
await promiseApzFlushedRepaints();
|
||||
|
||||
// Try another gesture to ensure the overscroll handoff runs.
|
||||
await promiseMoveMouseAndScrollWheelOver(fixed, 50, 50, false, 200);
|
||||
await promiseApzFlushedRepaints();
|
||||
|
||||
info("After scroll: fixed=" + fixed.scrollTop + " main=" + main.scrollTop);
|
||||
|
||||
// Ensure that the main element has not scrolled.
|
||||
is(main.scrollTop, 0, "The overscroll should not handoff");
|
||||
}
|
||||
|
||||
waitUntilApzStable()
|
||||
.then(test)
|
||||
.then(subtestDone, subtestFailed);
|
||||
|
||||
</script>
|
||||
</html>
|
|
@ -1,65 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<head>
|
||||
<title>APZ overscroll handoff for fixed elements</title>
|
||||
<script type="application/javascript" src="apz_test_utils.js"></script>
|
||||
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
|
||||
<script src="/tests/SimpleTest/paint_listener.js"></script>
|
||||
<meta name="viewport" content="width=device-width"/>
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0;
|
||||
}
|
||||
html {
|
||||
overflow: auto;
|
||||
background: blue;
|
||||
}
|
||||
.spacer {
|
||||
height: 2000px;
|
||||
}
|
||||
#fixed {
|
||||
position: fixed;
|
||||
overflow: auto;
|
||||
background: red;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<div id="fixed">
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
<script type="application/javascript">
|
||||
|
||||
async function test() {
|
||||
// Scroll to the bottom of the fixed position element that should
|
||||
// allow overscroll handoff.
|
||||
fixed.scrollTop = fixed.scrollHeight;
|
||||
|
||||
// After scrolling to bottom tick the refresh driver.
|
||||
await promiseFrame();
|
||||
|
||||
info("Start: fixed=" + fixed.scrollTop + " window=" + window.scrollY);
|
||||
|
||||
// Async scroll the fixed element by 200 pixels using the mouse-wheel.
|
||||
// This should handoff the overscroll to the window.
|
||||
await promiseMoveMouseAndScrollWheelOver(fixed, 50, 50, false, 200);
|
||||
|
||||
// Make sure scrolling that has happened is propagated to the main thread.
|
||||
await promiseApzFlushedRepaints();
|
||||
|
||||
// Try another gesture to ensure the overscroll handoff runs.
|
||||
await promiseMoveMouseAndScrollWheelOver(fixed, 50, 50, false, 200);
|
||||
await promiseApzFlushedRepaints();
|
||||
|
||||
// Ensure that the window has scrolled.
|
||||
isnot(window.scrollY, 0, "The overscroll should not handoff");
|
||||
}
|
||||
|
||||
waitUntilApzStable()
|
||||
.then(test)
|
||||
.then(subtestDone, subtestFailed);
|
||||
|
||||
</script>
|
|
@ -1,77 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<head>
|
||||
<title>APZ overscroll handoff for fixed elements</title>
|
||||
<script type="application/javascript" src="apz_test_utils.js"></script>
|
||||
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
|
||||
<script src="/tests/SimpleTest/paint_listener.js"></script>
|
||||
<meta name="viewport" content="width=device-width"/>
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0;
|
||||
}
|
||||
#scrolled {
|
||||
overflow: auto;
|
||||
background: blue;
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
}
|
||||
.spacer {
|
||||
height: 2000px;
|
||||
}
|
||||
#fixed {
|
||||
position: fixed;
|
||||
background: red;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
#subframe {
|
||||
overflow: auto;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<div id="scrolled">
|
||||
<div id="fixed">
|
||||
<div id="subframe">
|
||||
<div id="firstspacer" class="spacer"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="secondspacer" class="spacer"></div>
|
||||
</div>
|
||||
<script type="application/javascript">
|
||||
|
||||
async function test() {
|
||||
// Scroll to the bottom of the fixed position element that should not
|
||||
// allow overscroll handoff.
|
||||
subframe.scrollTop = subframe.scrollHeight;
|
||||
|
||||
// After scrolling to bottom tick the refresh driver.
|
||||
await promiseFrame();
|
||||
|
||||
info("Before scroll: subframe=" + subframe.scrollTop + " scrolled=" +
|
||||
scrolled.scrollTop);
|
||||
|
||||
// Async scroll the fixed element by 200 pixels using the mouse-wheel.
|
||||
// This should not handoff the overscroll.
|
||||
await promiseMoveMouseAndScrollWheelOver(subframe, 50, 50, false, 200);
|
||||
|
||||
// Make sure scrolling that has happened is propagated to the main thread.
|
||||
await promiseApzFlushedRepaints();
|
||||
|
||||
// Try another gesture to ensure the overscroll handoff runs.
|
||||
await promiseMoveMouseAndScrollWheelOver(subframe, 50, 50, false, 200);
|
||||
await promiseApzFlushedRepaints();
|
||||
|
||||
info("After scroll: subframe=" + subframe.scrollTop + " scrolled=" +
|
||||
scrolled.scrollTop);
|
||||
|
||||
// Ensure that the scrolled element has not scrolled.
|
||||
is(scrolled.scrollTop, 0, "scrolled: The overscroll should not handoff");
|
||||
}
|
||||
|
||||
waitUntilApzStable()
|
||||
.then(test)
|
||||
.then(subtestDone, subtestFailed);
|
||||
|
||||
</script>
|
|
@ -1,79 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<head>
|
||||
<title>APZ overscroll handoff for fixed elements</title>
|
||||
<script type="application/javascript" src="apz_test_utils.js"></script>
|
||||
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
|
||||
<script src="/tests/SimpleTest/paint_listener.js"></script>
|
||||
<meta name="viewport" content="width=device-width"/>
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0;
|
||||
}
|
||||
#scrolled {
|
||||
overflow: auto;
|
||||
background: blue;
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
}
|
||||
.spacer {
|
||||
height: 2000px;
|
||||
}
|
||||
#fixed {
|
||||
position: fixed;
|
||||
background: red;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
#subframe {
|
||||
overflow: auto;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<div id="scrolled">
|
||||
<div id="fixed">
|
||||
<div>
|
||||
<div id="subframe">
|
||||
<div id="firstspacer" class="spacer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="secondspacer" class="spacer"></div>
|
||||
</div>
|
||||
<script type="application/javascript">
|
||||
|
||||
async function test() {
|
||||
// Scroll to the bottom of the fixed position element that should not
|
||||
// allow overscroll handoff.
|
||||
subframe.scrollTop = subframe.scrollHeight;
|
||||
|
||||
// After scrolling to bottom tick the refresh driver.
|
||||
await promiseFrame();
|
||||
|
||||
info("Before scroll: subframe=" + subframe.scrollTop + " scrolled=" +
|
||||
scrolled.scrollTop);
|
||||
|
||||
// Async scroll the fixed element by 200 pixels using the mouse-wheel.
|
||||
// This should not handoff the overscroll.
|
||||
await promiseMoveMouseAndScrollWheelOver(subframe, 50, 50, false, 200);
|
||||
|
||||
// Make sure scrolling that has happened is propagated to the main thread.
|
||||
await promiseApzFlushedRepaints();
|
||||
|
||||
// Try another gesture to ensure the overscroll handoff runs.
|
||||
await promiseMoveMouseAndScrollWheelOver(subframe, 50, 50, false, 200);
|
||||
await promiseApzFlushedRepaints();
|
||||
|
||||
info("After scroll: subframe=" + subframe.scrollTop + " scrolled=" +
|
||||
scrolled.scrollTop);
|
||||
|
||||
// Ensure that the scrolled element has not scrolled.
|
||||
is(scrolled.scrollTop, 0, "scrolled: The overscroll should not handoff");
|
||||
}
|
||||
|
||||
waitUntilApzStable()
|
||||
.then(test)
|
||||
.then(subtestDone, subtestFailed);
|
||||
|
||||
</script>
|
|
@ -1,88 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>APZ overscroll handoff for sticky elements</title>
|
||||
<script type="application/javascript" src="apz_test_utils.js"></script>
|
||||
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
|
||||
<script src="/tests/SimpleTest/paint_listener.js"></script>
|
||||
<meta name="viewport" content="width=device-width"/>
|
||||
<style>
|
||||
html, body {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#main {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#spacer {
|
||||
height: 5000px;
|
||||
}
|
||||
|
||||
#sticky {
|
||||
position: sticky;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
background: red;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#long {
|
||||
height: 250px;
|
||||
width: 50%;
|
||||
position: absolute;
|
||||
background: green;
|
||||
top: 0;
|
||||
left: 25%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
<div id="sticky">
|
||||
<div id="long">
|
||||
</div>
|
||||
</div>
|
||||
<div id="spacer">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="application/javascript">
|
||||
|
||||
async function test() {
|
||||
// Scroll to the bottom of the sticky position element that should not
|
||||
// allow overscroll handoff.
|
||||
sticky.scrollTop = sticky.scrollHeight;
|
||||
|
||||
// After scrolling to bottom tick the refresh driver.
|
||||
await promiseFrame();
|
||||
|
||||
info("Start: sticky=" + sticky.scrollTop + " main=" + main.scrollTop);
|
||||
|
||||
let transformEnd = promiseTransformEnd();
|
||||
|
||||
// Async scroll the sticky element by 200 pixels using the mouse-wheel.
|
||||
// This should handoff the overscroll to the parent element.
|
||||
await promiseMoveMouseAndScrollWheelOver(sticky, 25, 25, false, 200);
|
||||
|
||||
// Wait for the trasform triggered by the gesture to complete.
|
||||
await transformEnd;
|
||||
await promiseApzFlushedRepaints();
|
||||
|
||||
info("After scroll: sticky=" + sticky.scrollTop + " main=" + main.scrollTop);
|
||||
|
||||
// Ensure that the main element has scrolled.
|
||||
isnot(main.scrollTop, 0, "The overscroll should handoff");
|
||||
}
|
||||
|
||||
waitUntilApzStable()
|
||||
.then(test)
|
||||
.then(subtestDone, subtestFailed);
|
||||
|
||||
</script>
|
||||
</html>
|
|
@ -76,9 +76,6 @@
|
|||
[test_group_overrides.html]
|
||||
skip-if =
|
||||
toolkit == 'android' # wheel events not supported on mobile
|
||||
[test_group_overscroll_handoff.html]
|
||||
skip-if =
|
||||
toolkit == 'android' # wheel events not supported on mobile
|
||||
[test_group_hittest-1.html]
|
||||
skip-if =
|
||||
toolkit == 'android' # mouse events not supported on mobile
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Tests for overscroll handoff</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="apz_test_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript">
|
||||
|
||||
var prefs = [
|
||||
// turn off smooth scrolling so that we don't have to wait for
|
||||
// APZ animations to finish before sampling the scroll offset
|
||||
["general.smoothScroll", false],
|
||||
["apz.test.mac.synth_wheel_input", true],
|
||||
// ensure that any mouse movement will trigger a new wheel transaction,
|
||||
// because in this test we move the mouse a bunch and want to recalculate
|
||||
// the target APZC after each such movement.
|
||||
["mousewheel.transaction.ignoremovedelay", 0],
|
||||
["mousewheel.transaction.timeout", 0],
|
||||
];
|
||||
|
||||
var subtests = [
|
||||
{"file": "helper_position_fixed_scroll_handoff-1.html", prefs},
|
||||
{"file": "helper_position_fixed_scroll_handoff-2.html", prefs},
|
||||
{"file": "helper_position_fixed_scroll_handoff-3.html", prefs},
|
||||
{"file": "helper_position_fixed_scroll_handoff-4.html", prefs},
|
||||
{"file": "helper_position_sticky_scroll_handoff.html", prefs},
|
||||
{"file": "helper_wheelevents_handoff_on_iframe.html", "prefs": prefs},
|
||||
{"file": "helper_wheelevents_handoff_on_non_scrollable_iframe.html", "prefs": prefs},
|
||||
];
|
||||
|
||||
if (isApzEnabled()) {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
window.onload = function() {
|
||||
runSubtestsSeriallyInFreshWindows(subtests)
|
||||
.then(SimpleTest.finish, SimpleTest.finishWithFailure);
|
||||
};
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -53,6 +53,8 @@ var subtests = [
|
|||
{"file": "helper_scroll_inactive_zindex.html", "prefs": prefs},
|
||||
{"file": "helper_scroll_over_scrollbar.html", "prefs": scrollbar_prefs},
|
||||
{"file": "helper_scroll_tables_perspective.html", "prefs": prefs},
|
||||
{"file": "helper_wheelevents_handoff_on_iframe.html", "prefs": prefs},
|
||||
{"file": "helper_wheelevents_handoff_on_non_scrollable_iframe.html", "prefs": prefs},
|
||||
{"file": "helper_relative_scroll_smoothness.html?input-type=wheel&scroll-method=scrollBy", prefs: smoothness_prefs },
|
||||
{"file": "helper_relative_scroll_smoothness.html?input-type=wheel&scroll-method=scrollTo", prefs: smoothness_prefs },
|
||||
{"file": "helper_relative_scroll_smoothness.html?input-type=wheel&scroll-method=scrollTop", prefs: smoothness_prefs },
|
||||
|
|
|
@ -1452,6 +1452,11 @@ static nsIFrame* GetNearestScrollableOrOverflowClipFrame(
|
|||
"GetNearestScrollableOrOverflowClipFrame expects a non-null frame");
|
||||
|
||||
auto GetNextFrame = [aFlags](const nsIFrame* aFrame) -> nsIFrame* {
|
||||
if (aFlags & nsLayoutUtils::SCROLLABLE_FOLLOW_OOF_TO_PLACEHOLDER) {
|
||||
return (aFlags & nsLayoutUtils::SCROLLABLE_SAME_DOC)
|
||||
? nsLayoutUtils::GetParentOrPlaceholderFor(aFrame)
|
||||
: nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(aFrame);
|
||||
}
|
||||
return (aFlags & nsLayoutUtils::SCROLLABLE_SAME_DOC)
|
||||
? aFrame->GetParent()
|
||||
: nsLayoutUtils::GetCrossDocParentFrameInProcess(aFrame);
|
||||
|
@ -2888,7 +2893,8 @@ nsIScrollableFrame* nsLayoutUtils::GetAsyncScrollableAncestorFrame(
|
|||
nsIFrame* aTarget) {
|
||||
uint32_t flags = nsLayoutUtils::SCROLLABLE_ALWAYS_MATCH_ROOT |
|
||||
nsLayoutUtils::SCROLLABLE_ONLY_ASYNC_SCROLLABLE |
|
||||
nsLayoutUtils::SCROLLABLE_FIXEDPOS_FINDS_ROOT;
|
||||
nsLayoutUtils::SCROLLABLE_FIXEDPOS_FINDS_ROOT |
|
||||
nsLayoutUtils::SCROLLABLE_FOLLOW_OOF_TO_PLACEHOLDER;
|
||||
return nsLayoutUtils::GetNearestScrollableFrame(aTarget, flags);
|
||||
}
|
||||
|
||||
|
@ -3312,9 +3318,6 @@ void nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||
autoRecording;
|
||||
|
||||
ViewID id = ScrollableLayerGuid::NULL_SCROLL_ID;
|
||||
nsDisplayListBuilder::AutoCurrentActiveScrolledRootSetter asrSetter(
|
||||
builder);
|
||||
|
||||
if (presShell->GetDocument() &&
|
||||
presShell->GetDocument()->IsRootDisplayDocument() &&
|
||||
!presShell->GetRootScrollFrame()) {
|
||||
|
@ -3347,7 +3350,7 @@ void nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||
}
|
||||
}
|
||||
|
||||
asrSetter.SetCurrentScrollParentId(id);
|
||||
nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter(builder, id);
|
||||
|
||||
builder->SetVisibleRect(visibleRect);
|
||||
builder->SetIsBuilding(true);
|
||||
|
|
|
@ -623,6 +623,14 @@ class nsLayoutUtils {
|
|||
* would be undesirable as a 'position:sticky' container for content).
|
||||
*/
|
||||
SCROLLABLE_STOP_AT_PAGE = 0x20,
|
||||
/**
|
||||
* If the SCROLLABLE_FOLLOW_OOF_TO_PLACEHOLDER flag is set, we navigate
|
||||
* from out-of-flow frames to their placeholder frame rather than their
|
||||
* parent frame.
|
||||
* Note, fixed-pos frames are out-of-flow frames, but
|
||||
* SCROLLABLE_FIXEDPOS_FINDS_ROOT takes precedence over this.
|
||||
*/
|
||||
SCROLLABLE_FOLLOW_OOF_TO_PLACEHOLDER = 0x40
|
||||
};
|
||||
/**
|
||||
* GetNearestScrollableFrame locates the first ancestor of aFrame
|
||||
|
|
|
@ -4166,8 +4166,18 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
|
||||
{
|
||||
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
|
||||
// Note that setting the current scroll parent id here means that positioned
|
||||
// children of this scroll info layer will pick up the scroll info layer as
|
||||
// their scroll handoff parent. This is intentional because that is what
|
||||
// happens for positioned children of scroll layers, and we want to maintain
|
||||
// consistent behaviour between scroll layers and scroll info layers.
|
||||
nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter(
|
||||
aBuilder,
|
||||
couldBuildLayer && mScrolledFrame->GetContent()
|
||||
? nsLayoutUtils::FindOrCreateIDFor(mScrolledFrame->GetContent())
|
||||
: aBuilder->GetCurrentScrollParentId());
|
||||
|
||||
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
|
||||
// If we're building an async zoom container, clip the contents inside
|
||||
// to the layout viewport (scrollPortClip). The composition bounds clip
|
||||
// (clipRect) will be applied to the zoom container itself in
|
||||
|
@ -4300,13 +4310,13 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
if (aBuilder->IsPaintingToWindow()) {
|
||||
mIsParentToActiveScrollFrames =
|
||||
ShouldActivateAllScrollFrames()
|
||||
? asrSetter.GetContainsNonMinimalDisplayPort()
|
||||
: asrSetter.ShouldForceLayerForScrollParent();
|
||||
? idSetter.GetContainsNonMinimalDisplayPort()
|
||||
: idSetter.ShouldForceLayerForScrollParent();
|
||||
}
|
||||
if (asrSetter.ShouldForceLayerForScrollParent()) {
|
||||
if (idSetter.ShouldForceLayerForScrollParent()) {
|
||||
// Note that forcing layerization of scroll parents follows the scroll
|
||||
// handoff chain which is subject to the out-of-flow-frames caveat noted
|
||||
// above (where the asrSetter variable is created).
|
||||
// above (where the idSetter variable is created).
|
||||
MOZ_ASSERT(couldBuildLayer && mScrolledFrame->GetContent() &&
|
||||
aBuilder->IsPaintingToWindow());
|
||||
if (!mWillBuildScrollableLayer) {
|
||||
|
|
|
@ -464,6 +464,14 @@ void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
visible, dirty);
|
||||
|
||||
if (subdocRootFrame) {
|
||||
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
|
||||
nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter(
|
||||
aBuilder,
|
||||
ignoreViewportScrolling && rootScrollFrame &&
|
||||
rootScrollFrame->GetContent()
|
||||
? nsLayoutUtils::FindOrCreateIDFor(rootScrollFrame->GetContent())
|
||||
: aBuilder->GetCurrentScrollParentId());
|
||||
|
||||
bool hasDocumentLevelListenersForApzAwareEvents =
|
||||
gfxPlatform::AsyncPanZoomEnabled() &&
|
||||
nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(presShell);
|
||||
|
|
|
@ -394,10 +394,6 @@ void nsDisplayListBuilder::AutoCurrentActiveScrolledRootSetter::
|
|||
// Set the builder's mCurrentActiveScrolledRoot.
|
||||
mBuilder->mCurrentActiveScrolledRoot = aActiveScrolledRoot;
|
||||
|
||||
// Update the current scroll parent id to match the new
|
||||
// active scrolled root.
|
||||
UpdateCurrentScrollParentId();
|
||||
|
||||
// We also need to adjust the builder's mCurrentContainerASR.
|
||||
// mCurrentContainerASR needs to be an ASR that all the container's
|
||||
// contents have finite bounds with respect to. If aActiveScrolledRoot
|
||||
|
|
|
@ -1101,41 +1101,25 @@ class nsDisplayListBuilder {
|
|||
};
|
||||
|
||||
/**
|
||||
* Used to update the current active scrolled root on the display list
|
||||
* builder, and to create new active scrolled roots.
|
||||
* A helper class to temporarily set the value of mCurrentScrollParentId.
|
||||
*/
|
||||
class AutoCurrentActiveScrolledRootSetter {
|
||||
class AutoCurrentScrollParentIdSetter {
|
||||
public:
|
||||
explicit AutoCurrentActiveScrolledRootSetter(nsDisplayListBuilder* aBuilder)
|
||||
AutoCurrentScrollParentIdSetter(nsDisplayListBuilder* aBuilder,
|
||||
ViewID aScrollId)
|
||||
: mBuilder(aBuilder),
|
||||
mSavedActiveScrolledRoot(aBuilder->mCurrentActiveScrolledRoot),
|
||||
mContentClipASR(aBuilder->ClipState().GetContentClipASR()),
|
||||
mDescendantsStartIndex(aBuilder->mActiveScrolledRoots.Length()),
|
||||
mUsed(false),
|
||||
mOldScrollParentId(aBuilder->mCurrentScrollParentId),
|
||||
mOldValue(aBuilder->mCurrentScrollParentId),
|
||||
mOldForceLayer(aBuilder->mForceLayerForScrollParent),
|
||||
mOldContainsNonMinimalDisplayPort(
|
||||
mBuilder->mContainsNonMinimalDisplayPort),
|
||||
mCanBeScrollParent(true) {
|
||||
UpdateCurrentScrollParentId();
|
||||
}
|
||||
|
||||
void SetCurrentScrollParentId(ViewID aScrollId) {
|
||||
// If this AutoCurrentActiveScrolledRootSetter has the same aScrollId as
|
||||
// the previous one on the stack, then that means the scrollframe that
|
||||
mBuilder->mContainsNonMinimalDisplayPort) {
|
||||
// If this AutoCurrentScrollParentIdSetter has the same scrollId as the
|
||||
// previous one on the stack, then that means the scrollframe that
|
||||
// created this isn't actually scrollable and cannot participate in
|
||||
// scroll handoff. We set mCanBeScrollParent to false to indicate this.
|
||||
mCanBeScrollParent = (mOldScrollParentId != aScrollId);
|
||||
mBuilder->mCurrentScrollParentId = aScrollId;
|
||||
mBuilder->mForceLayerForScrollParent = false;
|
||||
mBuilder->mContainsNonMinimalDisplayPort = false;
|
||||
}
|
||||
|
||||
void UpdateCurrentScrollParentId() {
|
||||
ViewID scrollId = mBuilder->mCurrentActiveScrolledRoot
|
||||
? mBuilder->mCurrentActiveScrolledRoot->GetViewId()
|
||||
: layers::ScrollableLayerGuid::NULL_SCROLL_ID;
|
||||
SetCurrentScrollParentId(scrollId);
|
||||
mCanBeScrollParent = (mOldValue != aScrollId);
|
||||
aBuilder->mCurrentScrollParentId = aScrollId;
|
||||
aBuilder->mForceLayerForScrollParent = false;
|
||||
aBuilder->mContainsNonMinimalDisplayPort = false;
|
||||
}
|
||||
|
||||
bool ShouldForceLayerForScrollParent() const {
|
||||
|
@ -1150,9 +1134,8 @@ class nsDisplayListBuilder {
|
|||
return mCanBeScrollParent && mBuilder->mContainsNonMinimalDisplayPort;
|
||||
}
|
||||
|
||||
~AutoCurrentActiveScrolledRootSetter() {
|
||||
mBuilder->mCurrentActiveScrolledRoot = mSavedActiveScrolledRoot;
|
||||
mBuilder->mCurrentScrollParentId = mOldScrollParentId;
|
||||
~AutoCurrentScrollParentIdSetter() {
|
||||
mBuilder->mCurrentScrollParentId = mOldValue;
|
||||
if (mCanBeScrollParent) {
|
||||
// If this flag is set, caller code is responsible for having dealt
|
||||
// with the current value of mBuilder->mForceLayerForScrollParent, so
|
||||
|
@ -1168,6 +1151,31 @@ class nsDisplayListBuilder {
|
|||
mOldContainsNonMinimalDisplayPort;
|
||||
}
|
||||
|
||||
private:
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
ViewID mOldValue;
|
||||
bool mOldForceLayer;
|
||||
bool mOldContainsNonMinimalDisplayPort;
|
||||
bool mCanBeScrollParent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to update the current active scrolled root on the display list
|
||||
* builder, and to create new active scrolled roots.
|
||||
*/
|
||||
class AutoCurrentActiveScrolledRootSetter {
|
||||
public:
|
||||
explicit AutoCurrentActiveScrolledRootSetter(nsDisplayListBuilder* aBuilder)
|
||||
: mBuilder(aBuilder),
|
||||
mSavedActiveScrolledRoot(aBuilder->mCurrentActiveScrolledRoot),
|
||||
mContentClipASR(aBuilder->ClipState().GetContentClipASR()),
|
||||
mDescendantsStartIndex(aBuilder->mActiveScrolledRoots.Length()),
|
||||
mUsed(false) {}
|
||||
|
||||
~AutoCurrentActiveScrolledRootSetter() {
|
||||
mBuilder->mCurrentActiveScrolledRoot = mSavedActiveScrolledRoot;
|
||||
}
|
||||
|
||||
void SetCurrentActiveScrolledRoot(
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot);
|
||||
|
||||
|
@ -1177,7 +1185,6 @@ class nsDisplayListBuilder {
|
|||
mBuilder->mCurrentActiveScrolledRoot, aScrollableFrame);
|
||||
mBuilder->mCurrentActiveScrolledRoot = asr;
|
||||
mUsed = true;
|
||||
UpdateCurrentScrollParentId();
|
||||
}
|
||||
|
||||
void InsertScrollFrame(nsIScrollableFrame* aScrollableFrame);
|
||||
|
@ -1208,10 +1215,6 @@ class nsDisplayListBuilder {
|
|||
* class.
|
||||
*/
|
||||
bool mUsed;
|
||||
ViewID mOldScrollParentId;
|
||||
bool mOldForceLayer;
|
||||
bool mOldContainsNonMinimalDisplayPort;
|
||||
bool mCanBeScrollParent;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче