Bug 2065180 - Deal with abspos ASRs correctly when building the top layer. r=tnikkel,layout-reviewers,layout-anchor-positioning-reviewers,dshin
Cleaned-up version of D324081. The assertion in the bug is one symptom; the other is that such a frame doesn't follow its anchor during an async scroll, which the reftest covers. Co-Authored-By: Dão Gottwald <dao@mozilla.com> Differential Revision: https://phabricator.services.mozilla.com/D324111
This commit is contained in:
committed by
ealvarez@mozilla.com
co-authored by
Dão Gottwald
parent
12e70a0e18
commit
313ff79ac3
@@ -1289,6 +1289,40 @@ const ActiveScrolledRoot* DisplayPortUtils::ActivateDisplayportOnASRAncestors(
|
||||
return asr;
|
||||
}
|
||||
|
||||
const ActiveScrolledRoot* DisplayPortUtils::GetASRForAbsPosFrame(
|
||||
nsIFrame* aFrame, const ActiveScrolledRoot* aContainingBlockASR,
|
||||
nsDisplayListBuilder* aBuilder) {
|
||||
MOZ_ASSERT(aFrame->IsAbsolutelyPositioned());
|
||||
if (!aBuilder->IsPaintingToWindow() ||
|
||||
// If we are in view transition capture we get a null asr no matter
|
||||
// what, so don't bother checking for async scrolling with a CSS anchor
|
||||
// pos anchor.
|
||||
aBuilder->IsInViewTransitionCapture() ||
|
||||
// If there is an active view transition in this document it is tricky
|
||||
// to determine what will be an active scroll frame outside of that
|
||||
// frame's BuildDisplayList, so don't bother to async scroll with an
|
||||
// anchor in that case. Bug 2001861 tracks removing this check.
|
||||
aFrame->PresContext()->Document()->GetActiveViewTransition()) {
|
||||
return aContainingBlockASR;
|
||||
}
|
||||
nsIFrame* scrollsWithAnchor =
|
||||
AnchorPositioningUtils::GetAnchorThatFrameScrollsWith(aFrame, aBuilder);
|
||||
if (!scrollsWithAnchor) {
|
||||
return aContainingBlockASR;
|
||||
}
|
||||
if (aBuilder->IsRetainingDisplayList()) {
|
||||
if (aBuilder->IsPartialUpdate()) {
|
||||
aBuilder->SetPartialBuildFailed(true);
|
||||
} else {
|
||||
aBuilder->SetDisablePartialUpdates(true);
|
||||
}
|
||||
}
|
||||
// TODO should we set the scroll parent id too?
|
||||
// https://github.com/w3c/csswg-drafts/issues/12042
|
||||
return ActivateDisplayportOnASRAncestors(
|
||||
scrollsWithAnchor, aFrame->GetParent(), aContainingBlockASR, aBuilder);
|
||||
}
|
||||
|
||||
static bool CheckAxes(ScrollContainerFrame* aScrollFrame, PhysicalAxes aAxes) {
|
||||
if (aAxes == kPhysicalAxesBoth) {
|
||||
return true;
|
||||
|
||||
@@ -406,6 +406,13 @@ class DisplayPortUtils {
|
||||
const ActiveScrolledRoot* aASRofLimitAncestor,
|
||||
nsDisplayListBuilder* aBuilder);
|
||||
|
||||
/**
|
||||
* Returns the ASR that an abspos frame `aFrame` should scroll with.
|
||||
*/
|
||||
static const ActiveScrolledRoot* GetASRForAbsPosFrame(
|
||||
nsIFrame* aFrame, const ActiveScrolledRoot* aContainingBlockASR,
|
||||
nsDisplayListBuilder* aBuilder);
|
||||
|
||||
/**
|
||||
* aFrame is an absolutely positioned frame that is anchor positioned and
|
||||
* compensates for scroll in at least one axis.
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "MobileViewportManager.h"
|
||||
#include "mozilla/AbsoluteContainingBlock.h"
|
||||
#include "mozilla/ComputedStyleInlines.h"
|
||||
#include "mozilla/DisplayPortUtils.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/ProfilerLabels.h"
|
||||
#include "mozilla/ReflowInput.h"
|
||||
@@ -133,8 +134,11 @@ static void BuildDisplayListForTopLayerFrame(nsDisplayListBuilder* aBuilder,
|
||||
// root scroll frame.
|
||||
clipState.SetClipChainForContainingBlockDescendants(
|
||||
savedOutOfFlowData->mCombinedClipChain);
|
||||
|
||||
asrSetter.SetCurrentActiveScrolledRoot(
|
||||
savedOutOfFlowData->mContainingBlockActiveScrolledRoot);
|
||||
DisplayPortUtils::GetASRForAbsPosFrame(
|
||||
aFrame, savedOutOfFlowData->mContainingBlockActiveScrolledRoot,
|
||||
aBuilder));
|
||||
asrSetter.SetCurrentScrollParentId(savedOutOfFlowData->mScrollParentId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4607,30 +4607,6 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
if (savedOutOfFlowData) {
|
||||
aBuilder->SetBuildingInvisibleItems(false);
|
||||
|
||||
nsIFrame* scrollsWithAnchor = nullptr;
|
||||
if (aBuilder->IsPaintingToWindow() &&
|
||||
// If we are in view transition capture we get a null asr no matter
|
||||
// what, so don't bother checking for async scrolling with a CSS anchor
|
||||
// pos anchor.
|
||||
!aBuilder->IsInViewTransitionCapture() &&
|
||||
child->IsAbsolutelyPositioned(disp) &&
|
||||
// If there is an active view transition in this document it is tricky
|
||||
// to determine what will be an active scroll frame outside of that
|
||||
// frame's BuildDisplayList, so don't bother to async scroll with an
|
||||
// anchor in that case. Bug 2001861 tracks removing this check.
|
||||
!PresContext()->Document()->GetActiveViewTransition()) {
|
||||
scrollsWithAnchor = AnchorPositioningUtils::GetAnchorThatFrameScrollsWith(
|
||||
child, aBuilder);
|
||||
|
||||
if (scrollsWithAnchor && aBuilder->IsRetainingDisplayList()) {
|
||||
if (aBuilder->IsPartialUpdate()) {
|
||||
aBuilder->SetPartialBuildFailed(true);
|
||||
} else {
|
||||
aBuilder->SetDisablePartialUpdates(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ActiveScrolledRoot* asr =
|
||||
savedOutOfFlowData->mContainingBlockActiveScrolledRoot;
|
||||
|
||||
@@ -4669,12 +4645,8 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (scrollsWithAnchor) {
|
||||
asr = DisplayPortUtils::ActivateDisplayportOnASRAncestors(
|
||||
scrollsWithAnchor, child->GetParent(), asr, aBuilder);
|
||||
|
||||
// TODO should we set the scroll parent id too?
|
||||
// https://github.com/w3c/csswg-drafts/issues/12042
|
||||
if (child->IsAbsolutelyPositioned(disp)) {
|
||||
asr = DisplayPortUtils::GetASRForAbsPosFrame(child, asr, aBuilder);
|
||||
}
|
||||
|
||||
if (aBuilder->IsInViewTransitionCapture()) {
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<style>
|
||||
.anchor {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: blue;
|
||||
}
|
||||
.anchored {
|
||||
position: absolute;
|
||||
left: 50px;
|
||||
top: 50px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: yellow;
|
||||
}
|
||||
.child {
|
||||
position: absolute;
|
||||
left: 50px;
|
||||
top: 50px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
<div class="anchor"></div>
|
||||
<div class="anchored"></div>
|
||||
<div class="child"></div>
|
||||
</html>
|
||||
@@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html reftest-async-scroll>
|
||||
<style>
|
||||
.scroller {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
overflow: auto;
|
||||
scrollbar-width: none;
|
||||
width: 150px;
|
||||
height: 100px;
|
||||
}
|
||||
.spacer {
|
||||
width: 1px;
|
||||
height: 100px;
|
||||
}
|
||||
.largespacer {
|
||||
width: 1px;
|
||||
height: 500px;
|
||||
}
|
||||
.anchor {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: blue;
|
||||
anchor-name: --my-anchor;
|
||||
}
|
||||
#popover {
|
||||
margin: 0;
|
||||
border: none;
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
position: absolute;
|
||||
position-anchor: --my-anchor;
|
||||
position-visibility: always;
|
||||
left: anchor(right);
|
||||
top: anchor(top);
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: yellow;
|
||||
}
|
||||
#popover > div {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
<div class="scroller"
|
||||
reftest-displayport-x="0" reftest-displayport-y="0"
|
||||
reftest-displayport-w="150" reftest-displayport-h="500"
|
||||
reftest-async-scroll-y="50">
|
||||
<div class="spacer"></div>
|
||||
<div class="anchor"></div>
|
||||
<div class="largespacer"></div>
|
||||
</div>
|
||||
<div id="popover" popover><div></div></div>
|
||||
<script>
|
||||
document.getElementById("popover").showPopover();
|
||||
</script>
|
||||
</html>
|
||||
@@ -202,3 +202,4 @@ defaults
|
||||
== anchor-pos-sticky-3.html anchor-pos-sticky-3-ref.html
|
||||
== anchor-pos-sticky-4.html anchor-pos-sticky-4-ref.html
|
||||
== anchor-pos-one-axis-1.html anchor-pos-one-axis-1-ref.html
|
||||
== anchor-pos-top-layer-1.html anchor-pos-top-layer-1-ref.html
|
||||
|
||||
Reference in New Issue
Block a user