gecko-dev/testing/web-platform/tests/css/css-scroll-anchoring/heuristic-with-offset-update.html
Ryan Hunt 5c7254fba8 Bug 1519462 - Coalesce all scroll anchor adjustments to be performed after layout when flushing notifcations. r=dholbert
We currently perform anchor adjustment in three spots:
  1. If the target of RestyleManager::RecomputePosition is in a scroll anchor chain
  2. If the reflow root is in a scroll anchor chain
  3. In nsHTMLScrollFrame::DidReflow, for itself

It looks like it's possible for a scroll anchor container to be adjusted by (1)
and (2 or 3) in the same PresShell flush.

This should be okay, except that we consume mSuppressAnchorAdjustment when
performing an adjustment, and this can lead us to miss the second time that
we perform adjustments in a PresShell flush.

This commit reworks how we run anchor adjustments so that we collect all
scroll anchor containers that should be adjusted, and only perform the
adjustments once.

Differential Revision: https://phabricator.services.mozilla.com/D16407

--HG--
extra : source : cbdbd08379d99f9d55f756c57d728c28331be5da
2019-01-13 00:54:05 -06:00

58 lines
1.8 KiB
HTML

<!DOCTYPE html>
<meta charset="utf-8">
<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring-1/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<html>
<head>
<style type="text/css">
#scroller {
overflow: scroll;
height: 500px;
height: 500px;
}
#before {
height: 200px;
}
#anchor {
position: relative;
width: 200px;
height: 200px;
margin-bottom: 500px;
background-color: blue;
/*
* To trigger the Gecko bug that's being regression-tested here, we
* need 'top' to start out at a non-'auto' value, so that the
* dynamic change can trigger Gecko's "RecomputePosition" fast path
*/
top: 0px;
}
</style>
</head>
<body>
<div id="scroller">
<div id="before">
</div>
<div id="anchor">
</div>
</div>
<script type="text/javascript">
test(() => {
let scroller = document.querySelector('#scroller');
let before = document.querySelector('#before');
let anchor = document.querySelector('#anchor');
// Scroll down to select #anchor as a scroll anchor
scroller.scrollTop = 200;
// Adjust the 'top' of #anchor, which should trigger a suppression
anchor.style.top = '10px';
// Expand #before and make sure we don't apply an adjustment
before.style.height = '300px';
assert_equals(scroller.scrollTop, 200);
}, 'Positioned ancestors with dynamic changes to offsets trigger scroll suppressions.');
</script>
</body>
</html>