Re-clamp the last scroll offset before updating new scroll offsets.

When we update new relative scroll offsets in an APZC, we use the last scroll
offset. Thus if the last scroll offset is out of bounds, relative scroll offset
updates will result wrong scroll destinations.

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

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1779404
gecko-commit: 4ff9f4b0a7af3d72fc1e81fa8ec8eeeaff8ddd51
gecko-reviewers: botond
diff --git a/css/css-scroll-anchoring/after-scrollable-range-shrinkage-002.html b/css/css-scroll-anchoring/after-scrollable-range-shrinkage-002.html
new file mode 100644
index 0000000..d6399c5
--- /dev/null
+++ b/css/css-scroll-anchoring/after-scrollable-range-shrinkage-002.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<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/">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1779404">
+<div style="height: 500vh;"></div>
+<div id="anchor" style="height: 10px; background-color: blue;"></div>
+<div style="height: 200vh;"></div>
+<script>
+promise_test(async t => {
+  assert_equals(window.scrollY, 0);
+
+  let anchorRect = anchor.getBoundingClientRect();
+  // Scroll to the anchor node.
+  window.scrollBy(0, anchorRect.y);
+  assert_equals(window.scrollY, anchorRect.y);
+
+  await new Promise(resolve => requestAnimationFrame(resolve));
+  await new Promise(resolve => t.step_timeout(resolve, 0));
+
+  // Shrink the first element so that scroll anchoring happens.
+  document.querySelectorAll("div")[0].style.height = "100vh";
+
+  await new Promise(resolve => requestAnimationFrame(resolve));
+  await new Promise(resolve => requestAnimationFrame(resolve));
+
+  const scrollAnchorPosition = window.scrollY;
+
+  // Scroll back to (0, 0) to calculate the expected scroll anchor element
+  // position.
+  window.scrollTo(0, 0);
+  anchorRect = anchor.getBoundingClientRect();
+  assert_equals(scrollAnchorPosition, anchorRect.y);
+}, "Scroll anchoring properly works after scrollable range shrinkage");
+</script>
+</html>