fune/testing/web-platform/tests/css/css-scroll-anchoring/adjustments-in-scroll-event-handler.tentative.html
Hiroyuki Ikezoe 6cf6f73da0 Bug 1833758 - Add a pref not to reset max consecutive adjustment count during running APZ async scroll. r=emilio
With this pref we can avoid bug 1561450 without disabling any scroll adjustments
in scroll event handlers because in the specific case of the bug the scroll
adjustment in question is zero length such as

```
  element.style.display = "block";
  element.offsetTop // flush layout
  element.style.display = "none";
```

so it can be caught by our existing consecutive adjustment heuristic. Thus with
the default layout.css.scroll-anchoring.max-consecutive-adjustments value, as of
now it's 10, the case of bug 1561450 will stop firing scroll events after
5 (= 10/2) additional scroll event observations.

Differential Revision: https://phabricator.services.mozilla.com/D178898
2023-05-29 22:40:16 +00:00

53 lines
1.7 KiB
HTML

<!DOCTYPE html>
<meta name="viewport" content="width=device-width">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="author" title="Mozilla" href="https://mozilla.org">
<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring/">
<style>
body { margin: 0 }
.content {
height: 200px;
background: lightblue;
}
.spacer {
height: 300vh;
}
</style>
<div class="content"></div>
<div class="content" style="background: green"></div>
<div class="spacer"></div>
<script>
const anchor = document.querySelectorAll(".content")[1];
const t = async_test("Scroll adjustments happen even if it's triggered from scroll event listeners");
window.addEventListener("scroll", t.step_func(function() {
// Forcibly flush layout, this will flush the pending the node insertion.
let scrollPosition = window.scrollY;
requestAnimationFrame(t.step_func(function() {
requestAnimationFrame(t.step_func(function() {
assert_equals(window.scrollY, 400);
t.done();
}));
}));
}), { once: true });
window.onload = t.step_func(function() {
requestAnimationFrame(t.step_func(function() {
// Scroll to the anchor node in a requestAnimationFrame callback so that
// it queues a scroll event which will be fired in the next event loop.
anchor.scrollIntoView({ behavior: "instant" });
// Then in a setTimeout callback insert an element just right before the
// anchor node, it will run before firing the scroll event.
t.step_timeout(function() {
const content = document.createElement("div");
content.classList.add("content");
content.style.background = "red";
anchor.before(content);
}, 0);
}));
});
</script>