Bug 1538537 - When suppressing anchoring on an scrollframe, forward to the frame that actually maintains the anchor as needed. r=dholbert
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 19 May 2020 23:57:23 +0000
changeset 530929 bd3a170fc984a92ff6478480b16e3d8ce9cb2f68
parent 530928 a23749aac83b61459a2ec0ef6bcdf6be396dc7b4
child 530930 ad89f466d991715dba86eb61630eee7f9761369c
push id37434
push userabutkovits@mozilla.com
push dateWed, 20 May 2020 10:05:10 +0000
treeherdermozilla-central@005ef1c25992 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1538537
milestone78.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1538537 - When suppressing anchoring on an scrollframe, forward to the frame that actually maintains the anchor as needed. r=dholbert The test-case is position-change-heuristic.html but with body and #space having overflow: hidden, which makes it fail on Nightly. Differential Revision: https://phabricator.services.mozilla.com/D75825
layout/generic/ScrollAnchorContainer.cpp
testing/web-platform/tests/css/css-scroll-anchoring/position-change-heuristic-in-nested-scroll-box.html
--- a/layout/generic/ScrollAnchorContainer.cpp
+++ b/layout/generic/ScrollAnchorContainer.cpp
@@ -361,24 +361,39 @@ void ScrollAnchorContainer::AdjustmentMa
       nsIScriptError::warningFlag, NS_LITERAL_CSTRING("Layout"),
       Frame()->PresContext()->Document(), nsContentUtils::eLAYOUT_PROPERTIES,
       "ScrollAnchoringDisabledInContainer", arguments);
 }
 
 void ScrollAnchorContainer::SuppressAdjustments() {
   ANCHOR_LOG("Received a scroll anchor suppression for %p.\n", this);
   mSuppressAnchorAdjustment = true;
+
+  // Forward to our parent if appropriate, that is, if we don't maintain an
+  // anchor, and we can't maintain one.
+  //
+  // Note that we need to check !CanMaintainAnchor(), instead of just whether
+  // our frame is in the anchor chain of our ancestor as InvalidateAnchor()
+  // does, given some suppression triggers apply even for nodes that are not in
+  // the anchor chain.
+  if (!mAnchorNode && !CanMaintainAnchor()) {
+    if (ScrollAnchorContainer* container = FindFor(Frame())) {
+      ANCHOR_LOG(" > Forwarding to parent anchor\n");
+      container->SuppressAdjustments();
+    }
+  }
 }
 
 void ScrollAnchorContainer::InvalidateAnchor(ScheduleSelection aSchedule) {
   ANCHOR_LOG("Invalidating scroll anchor %p for %p.\n", mAnchorNode, this);
 
   if (mAnchorNode) {
     SetAnchorFlags(mScrollFrame->mScrolledFrame, mAnchorNode, false);
   } else if (mScrollFrame->mScrolledFrame->IsInScrollAnchorChain()) {
+    ANCHOR_LOG(" > Forwarding to parent anchor\n");
     // We don't maintain an anchor, and our scrolled frame is in the anchor
     // chain of an ancestor. Invalidate that anchor.
     //
     // NOTE: Intentionally not forwarding aSchedule: Scheduling is always safe
     // and not doing so is just an optimization.
     FindFor(Frame())->InvalidateAnchor();
   }
   mAnchorNode = nullptr;
copy from testing/web-platform/tests/css/css-scroll-anchoring/position-change-heuristic.html
copy to testing/web-platform/tests/css/css-scroll-anchoring/position-change-heuristic-in-nested-scroll-box.html
--- a/testing/web-platform/tests/css/css-scroll-anchoring/position-change-heuristic.html
+++ b/testing/web-platform/tests/css/css-scroll-anchoring/position-change-heuristic-in-nested-scroll-box.html
@@ -1,32 +1,35 @@
 <!DOCTYPE html>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring/#suppression-triggers">
 <style>
-
 #space {
   height: 4000px;
+  overflow: hidden;
 }
 #header {
   background-color: #F5B335;
   height: 50px;
   width: 100%;
 }
 #content {
   background-color: #D3D3D3;
   height: 400px;
 }
 .scroller {
   overflow: scroll;
   position: relative;
   width: 600px;
   height: 600px;
 }
-
+body {
+  overflow: hidden;
+}
 </style>
 <div id="maybeScroller">
   <div id="space">
     <div id="header"></div>
     <div id="before"></div>
     <div id="content"></div>
   </div>
 </div>