Bug 1466224 - Follow out-of-flow frames to their placeholders in GetAsyncScrollableAncestorFrame(). r=tnikkel

This ensures that the notion of a scroll frame's scrollable ancestor used in
SetZeroMarginDisplayPortOnAsyncScrollableAncestor() to activate ancestors
when activating a scroll frame, matches what the actual ancestor is
according to display list building logic.

This avoids us taking the buggy "activate a scroll parent after the fact"
codepath (AutoCurrentActiveScrolledRootSetter::InsertScrollFrame()), which
can result in a display list with incorrect ASRs, in at least some cases.

Differential Revision: https://phabricator.services.mozilla.com/D100303
This commit is contained in:
Botond Ballo 2020-12-22 04:00:51 +00:00
parent 5a90b263f7
commit 06fad2134b
5 changed files with 54 additions and 8 deletions

View File

@ -959,7 +959,7 @@ void DisplayPortUtils::SetZeroMarginDisplayPortOnAsyncScrollableAncestors(
nsIFrame* aFrame) {
nsIFrame* frame = aFrame;
while (frame) {
frame = nsLayoutUtils::GetCrossDocParentFrame(frame);
frame = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(frame);
if (!frame) {
break;
}

View File

@ -1422,10 +1422,18 @@ static nsIFrame* GetNearestScrollableOrOverflowClipFrame(
aFrame,
"GetNearestScrollableOrOverflowClipFrame expects a non-null frame");
for (nsIFrame* f = aFrame; f;
f = (aFlags & nsLayoutUtils::SCROLLABLE_SAME_DOC)
? f->GetParent()
: nsLayoutUtils::GetCrossDocParentFrame(f)) {
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::GetCrossDocParentFrame(aFrame);
};
for (nsIFrame* f = aFrame; f; f = GetNextFrame(f)) {
if (aClipFrameCheck && aClipFrameCheck(f)) {
return f;
}
@ -2790,7 +2798,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);
}
@ -4130,7 +4139,8 @@ nsIFrame* nsLayoutUtils::GetParentOrPlaceholderFor(const nsIFrame* aFrame) {
return aFrame->GetParent();
}
nsIFrame* nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(nsIFrame* aFrame) {
nsIFrame* nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(
const nsIFrame* aFrame) {
nsIFrame* f = GetParentOrPlaceholderFor(aFrame);
if (f) return f;
return GetCrossDocParentFrame(aFrame);

View File

@ -567,6 +567,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
@ -1352,7 +1360,7 @@ class nsLayoutUtils {
* If aFrame is an out of flow frame, return its placeholder, otherwise
* return its (possibly cross-doc) parent.
*/
static nsIFrame* GetParentOrPlaceholderForCrossDoc(nsIFrame* aFrame);
static nsIFrame* GetParentOrPlaceholderForCrossDoc(const nsIFrame* aFrame);
/**
* Returns the frame that would act as the parent of aFrame when

View File

@ -0,0 +1,27 @@
<script>
window.requestIdleCallback(function() {
document.documentElement.style.display="none";
document.documentElement.getBoundingClientRect();
document.documentElement.style.display="";
});
</script>
<style>
#a {
display: table-caption;
}
:not(altGlyphDef) {
text-indent: 1vw;
overflow-x: scroll;
}
#b {
bottom: 0em;
font: small/7% cursive;
transform: translate3d(0px, 1px, -1px);
max-height: 3mm;
filter: brightness(0);
}
</style>
<button id="a">
<dialog id="b" open="">
<h5>&

View File

@ -697,6 +697,7 @@ load 1460158-2.html
load 1460158-3.html
load 1461039.html
load 1461979-1.html
asserts(0-1) load 1466224.html # assertion is bug 1683800
load 1467239.html
load 1472403.html
load 1474768.html