Commit c48045bd authored by Chris Harrelson's avatar Chris Harrelson Committed by Commit Bot

When performing subtree layout, perform scroll anchoring notifications on ancestors.

Previously, we would fail to call NotifyBeforeLayout for all such ancestors
that are scrollers, causing subtree layouts to completely fail to maintain
a scroll anchor for such ancestors.

Bug: 920289

Change-Id: I899634949739f5d4f3af1f282b598cbc4ef0e3e4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1902767
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
Reviewed-by: default avatarNick Burris <nburris@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#713561}
parent 44b5f447
......@@ -609,6 +609,17 @@ void LocalFrameView::PerformPreLayoutTasks() {
void LocalFrameView::LayoutFromRootObject(LayoutObject& root) {
LayoutState layout_state(root);
// Since we are starting layout from an arbitrary node, we need to notify all
// possible scroll anchors above us, as they aren't notified during layout.
for (auto* ancestor = root.Container(); ancestor;
ancestor = ancestor->Container()) {
if (ancestor->HasOverflowClip() && ancestor->IsLayoutBlock()) {
auto* scrollable_area =
ToLayoutBoxModelObject(ancestor)->GetScrollableArea();
DCHECK(scrollable_area);
scrollable_area->GetScrollAnchor()->NotifyBeforeLayout();
}
}
root.UpdateLayout();
}
......
<!DOCTYPE html>
<head>
<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring/">
<script src="/common/reftest-wait.js"></script>
</head>
<style>
#outer {
overflow: hidden;
width: 500px;
height: 500px;
}
#inner {
overflow: auto;
position: relative;
width: 500px;
height: 2000px;
}
p {
font: 48pt monospace;
}
</style>
</head>
<body>
<div id="outer">
<div id="inner">
<p>Anchor</p>
</div>
</div>
<script>
const outer = document.querySelector("#outer");
const inner = document.querySelector("#inner");
onload = () => {
requestAnimationFrame(() => {
requestAnimationFrame(() => {
outer.scrollTo(0, 70);
document.documentElement.removeAttribute("class");
});
});
};
</script>
<!DOCTYPE html>
<head>
<title>Test that subtree layout with nested overflow preserves scroll anchoring.</title>
<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org">
<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring/">
<link rel="match" href="nested-overflow-subtree-layout-ref.html">
<script src="/common/reftest-wait.js"></script>
</head>
<style>
#outer {
overflow: hidden;
width: 500px;
height: 500px;
}
#inner {
overflow: auto;
position: relative;
width: 500px;
height: 2000px;
}
p {
font: 48pt monospace;
}
</style>
</head>
<body>
<div id="outer">
<div id="inner">
<p>Anchor</p>
</div>
</div>
<script>
const outer = document.querySelector("#outer");
const inner = document.querySelector("#inner");
onload = () => {
requestAnimationFrame(() => {
requestAnimationFrame(() => {
outer.scrollTo(0, 70);
requestAnimationFrame(() => {
const elem = document.createElement("p");
elem.textContent = "FAIL";
inner.insertBefore(elem, inner.firstChild);
document.documentElement.removeAttribute("class");
});
});
});
};
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment