Skip to content

Commit 282a5bc

Browse files
committed
Bug 2003593 - Invalidate for anchor changes correctly. r=dshin,layout-anchor-positioning-reviewers,firefox-style-system-reviewers,layout-reviewers
We need to start the reflow from our parent, even if we happen to be a reflow root. Differential Revision: https://phabricator.services.mozilla.com/D274805
1 parent c2271ec commit 282a5bc

File tree

7 files changed

+77
-13
lines changed

7 files changed

+77
-13
lines changed

layout/base/AnchorPositioningUtils.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -951,8 +951,7 @@ static bool TriggerFallbackReflow(PresShell* aPresShell, nsIFrame* aPositioned,
951951
// We want to retry from the first position; remove the last position
952952
// property so all potential positions are re-evaluated.
953953
aPositioned->RemoveProperty(nsIFrame::LastSuccessfulPositionFallback());
954-
aPresShell->FrameNeedsReflow(aPositioned, mozilla::IntrinsicDirty::None,
955-
NS_FRAME_IS_DIRTY);
954+
aPresShell->MarkPositionedFrameForReflow(aPositioned);
956955
return true;
957956
}
958957

layout/base/PresShell.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11575,9 +11575,7 @@ PresShell::AnchorPosUpdateResult PresShell::UpdateAnchorPosLayout() {
1157511575
}
1157611576
if (shouldReflow) {
1157711577
result = AnchorPosUpdateResult::NeedReflow;
11578-
// Abspos frames should not affect ancestor intrinsics.
11579-
FrameNeedsReflow(positioned, IntrinsicDirty::None,
11580-
NS_FRAME_HAS_DIRTY_CHILDREN);
11578+
MarkPositionedFrameForReflow(positioned);
1158111579
}
1158211580
}
1158311581
return result;
@@ -11817,8 +11815,7 @@ void PresShell::UpdateAnchorPosForScroll(
1181711815
accService->NotifyAnchorPositionedScrollUpdate(this, positioned);
1181811816
}
1181911817
#endif
11820-
FrameNeedsReflow(positioned, IntrinsicDirty::None,
11821-
NS_FRAME_HAS_DIRTY_CHILDREN);
11818+
MarkPositionedFrameForReflow(positioned);
1182211819
}
1182311820
}
1182411821
}
@@ -12146,13 +12143,19 @@ size_t PresShell::SizeOfTextRuns(MallocSizeOf aMallocSizeOf) const {
1214612143
/* clear = */ false);
1214712144
}
1214812145

12149-
void PresShell::MarkFixedFramesForReflow(IntrinsicDirty aIntrinsicDirty) {
12146+
void PresShell::MarkPositionedFrameForReflow(nsIFrame* aFrame) {
12147+
// Abspos frames don't affect intrinsic sizes of ancestors.
12148+
FrameNeedsReflow(aFrame, IntrinsicDirty::None, NS_FRAME_HAS_DIRTY_CHILDREN,
12149+
ReflowRootHandling::PositionOrSizeChange);
12150+
}
12151+
12152+
void PresShell::MarkFixedFramesForReflow() {
1215012153
nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
1215112154
if (rootFrame) {
1215212155
const nsFrameList& childList =
1215312156
rootFrame->GetChildList(FrameChildListID::Fixed);
1215412157
for (nsIFrame* childFrame : childList) {
12155-
FrameNeedsReflow(childFrame, aIntrinsicDirty, NS_FRAME_IS_DIRTY);
12158+
MarkPositionedFrameForReflow(childFrame);
1215612159
}
1215712160
}
1215812161
}
@@ -12230,7 +12233,7 @@ void PresShell::CompleteChangeToVisualViewportSize() {
1223012233
if (ScrollContainerFrame* sf = GetRootScrollContainerFrame()) {
1223112234
sf->MarkScrollbarsDirtyForReflow();
1223212235
}
12233-
MarkFixedFramesForReflow(IntrinsicDirty::None);
12236+
MarkFixedFramesForReflow();
1223412237
}
1223512238

1223612239
MaybeReflowForInflationScreenSizeChange();

layout/base/PresShell.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1544,7 +1544,10 @@ class PresShell final : public nsStubDocumentObserver,
15441544
/**
15451545
* Calls FrameNeedsReflow on all fixed position children of the root frame.
15461546
*/
1547-
void MarkFixedFramesForReflow(IntrinsicDirty aIntrinsicDirty);
1547+
void MarkFixedFramesForReflow();
1548+
// Marks a positioned frame for reflow, assuming that size or position of the
1549+
// frame might change.
1550+
void MarkPositionedFrameForReflow(nsIFrame*);
15481551

15491552
/**
15501553
* Similar to above MarkFixedFramesForReflow, but for sticky position children

layout/base/nsPresContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2948,7 +2948,7 @@ void nsPresContext::UpdateDynamicToolbarOffset(ScreenIntCoord aOffset) {
29482948
// position:fixed or position:sticky element is painted at the correct
29492949
// position on the main-thread.
29502950
if (mDynamicToolbarHeight == 0 || aOffset == -mDynamicToolbarMaxHeight) {
2951-
mPresShell->MarkFixedFramesForReflow(IntrinsicDirty::None);
2951+
mPresShell->MarkFixedFramesForReflow();
29522952
mPresShell->MarkStickyFramesForReflow();
29532953
mPresShell->ScheduleResizeEventIfNeeded(
29542954
PresShell::ResizeEventKind::Regular);

layout/style/nsStyleStruct.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,7 @@ nsChangeHint nsStylePosition::CalcDifference(
12571257
mPositionArea != aNewData.mPositionArea) {
12581258
// We need to reflow in order to update the `AnchorPosReferences`
12591259
// property at minimum.
1260-
hint |= nsChangeHint_NeedReflow;
1260+
hint |= nsChangeHint_NeedReflow | nsChangeHint_ReflowChangesSizeOrPosition;
12611261
}
12621262

12631263
if (mAspectRatio != aNewData.mAspectRatio) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<style>
4+
body { margin: 0 }
5+
.green {
6+
position: absolute;
7+
top: 20px;
8+
left: 100px;
9+
width: 100px;
10+
height: 100px;
11+
background-color: green;
12+
}
13+
</style>
14+
<div class="green"></div>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!DOCTYPE html>
2+
<html class="reftest-wait">
3+
<meta charset="utf-8">
4+
<title>Dynamic changes to anchor-name and reflow roots</title>
5+
<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#anchor-name">
6+
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=2003593">
7+
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
8+
<link rel="author" title="Mozilla" href="https://mozilla.com">
9+
<link rel="match" href="anchor-name-dynamic-reflow-root-ref.html">
10+
<style>
11+
body { margin: 0 }
12+
.tabs {
13+
display: flex;
14+
}
15+
.tab {
16+
height: 20px;
17+
width: 100px;
18+
}
19+
.cur {
20+
anchor-name: --current-tab;
21+
}
22+
.highlight {
23+
position: absolute;
24+
width: anchor-size(width);
25+
left: anchor(left);
26+
right: anchor(right);
27+
height: 100px;
28+
background: green;
29+
top: anchor(bottom);
30+
position-anchor: --current-tab;
31+
transform: scaleY(1); /* This is important to test the bug */
32+
}
33+
</style>
34+
<div class=tabs>
35+
<div id=t1 class="tab cur"></div>
36+
<div id=t2 class="tab"></div>
37+
<div class=highlight></div>
38+
</div>
39+
<script>
40+
document.addEventListener("TestRendered", function() {
41+
t1.classList.remove('cur');
42+
t2.classList.add('cur');
43+
document.documentElement.className = "";
44+
});
45+
</script>

0 commit comments

Comments
 (0)