Title: [295448] trunk
Revision
295448
Author
[email protected]
Date
2022-06-10 01:04:47 -0700 (Fri, 10 Jun 2022)

Log Message

REGRESSION: CSS scroll-behavior: smooth with overflow: hidden breaks JS scrollTo/scrollLeft/scrollTop
https://bugs.webkit.org/show_bug.cgi?id=238497
<rdar://90990040>

Reviewed by Simon Fraser.

Add scrollable area to frame view's list of scrollable areas if necessary in scrollToOffset.
This is necessary as Document::runScrollSteps() looks through the list of scrollable areas
to service animations on the scrollable area. It is necessary to add the scrollable area
in scrollToOffset as for a scrollable area that is not user scrollable (such as a scrollable
area with overflow: hidden) it would not be added, so the animation would not occur.

* LayoutTests/fast/scrolling/smooth-scroll-with-overflow-hidden-expected.txt: Added.
* LayoutTests/fast/scrolling/smooth-scroll-with-overflow-hidden.html: Added.
* Source/WebCore/page/scrolling/ScrollingCoordinator.cpp:
(WebCore::ScrollingCoordinator::absoluteEventTrackingRegionsForFrame const):
* Source/WebCore/platform/ScrollableArea.h:
(WebCore::ScrollableArea::isVisibleToHitTesting const):
* Source/WebCore/rendering/RenderLayerScrollableArea.cpp:
(WebCore::RenderLayerScrollableArea::clear):
(WebCore::RenderLayerScrollableArea::scrollToOffset):
(WebCore::RenderLayerScrollableArea::isVisibleToHitTesting const):
(WebCore::RenderLayerScrollableArea::updateScrollableAreaSet):
(WebCore::RenderLayerScrollableArea::registerScrollableArea):
* Source/WebCore/rendering/RenderLayerScrollableArea.h:

Canonical link: https://commits.webkit.org/251454@main

Modified Paths

Added Paths

Diff

Added: trunk/LayoutTests/fast/scrolling/mac/smooth-scroll-with-overflow-hidden-expected.txt (0 => 295448)


--- trunk/LayoutTests/fast/scrolling/mac/smooth-scroll-with-overflow-hidden-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/smooth-scroll-with-overflow-hidden-expected.txt	2022-06-10 08:04:47 UTC (rev 295448)
@@ -0,0 +1,5 @@
+PASS scrollContainer.scrollLeft is 500
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/scrolling/mac/smooth-scroll-with-overflow-hidden.html (0 => 295448)


--- trunk/LayoutTests/fast/scrolling/mac/smooth-scroll-with-overflow-hidden.html	                        (rev 0)
+++ trunk/LayoutTests/fast/scrolling/mac/smooth-scroll-with-overflow-hidden.html	2022-06-10 08:04:47 UTC (rev 295448)
@@ -0,0 +1,54 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .scroll-container {
+            height: 250px;
+            width: 300px;
+            border: 1px solid black;
+            overflow-y: scroll;
+            overflow: hidden;
+        }
+        
+        .contents {
+            height: 100%;
+            width: 400%;
+            background-image: repeating-linear-gradient(to right, white, silver 250px);
+        }
+    </style>
+    <script src=""
+    <script src=""
+    <script>
+        jsTestIsAsync = true;
+
+        async function runTest()
+        {
+            scrollContainer = document.querySelector('.scroll-container');
+
+            eventSender.monitorWheelEvents();
+            
+            scrollContainer.scrollTo({
+                top: 0,
+                left: 500,
+                behavior: 'smooth'
+            });
+            
+            await UIHelper.waitForScrollCompletion();
+            
+            shouldBe('scrollContainer.scrollLeft', '500');
+            finishJSTest();
+        }
+    
+        window.addEventListener('load', () => {
+            setTimeout(runTest, 0);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="scroll-container">
+        <div class="contents"></div>
+    </div>
+    <div id="console"></div>
+    <script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/page/FocusController.cpp (295447 => 295448)


--- trunk/Source/WebCore/page/FocusController.cpp	2022-06-10 06:29:03 UTC (rev 295447)
+++ trunk/Source/WebCore/page/FocusController.cpp	2022-06-10 08:04:47 UTC (rev 295448)
@@ -963,7 +963,9 @@
             continue;
 
         for (auto& scrollableArea : *scrollableAreas) {
-            ASSERT(scrollableArea->scrollbarsCanBeActive() || m_page.shouldSuppressScrollbarAnimations());
+            if (!scrollableArea->scrollbarsCanBeActive())
+                continue;
+            ASSERT(m_page.shouldSuppressScrollbarAnimations());
 
             contentAreaDidShowOrHide(scrollableArea, contentIsVisible);
         }

Modified: trunk/Source/WebCore/page/FrameView.cpp (295447 => 295448)


--- trunk/Source/WebCore/page/FrameView.cpp	2022-06-10 06:29:03 UTC (rev 295447)
+++ trunk/Source/WebCore/page/FrameView.cpp	2022-06-10 08:04:47 UTC (rev 295448)
@@ -5842,6 +5842,15 @@
         return scrollingObject->style().overscrollBehaviorY();
     return OverscrollBehavior::Auto;
 }
+
+bool FrameView::isVisibleToHitTesting() const
+{
+    bool isVisibleToHitTest = true;
+    if (HTMLFrameOwnerElement* owner = frame().ownerElement())
+        isVisibleToHitTest = owner->renderer() && owner->renderer()->visibleToHitTesting();
+    return isVisibleToHitTest;
+}
+
 } // namespace WebCore
 
 #undef PAGE_ID

Modified: trunk/Source/WebCore/page/FrameView.h (295447 => 295448)


--- trunk/Source/WebCore/page/FrameView.h	2022-06-10 06:29:03 UTC (rev 295447)
+++ trunk/Source/WebCore/page/FrameView.h	2022-06-10 08:04:47 UTC (rev 295448)
@@ -117,6 +117,8 @@
     WEBCORE_EXPORT void setCanHaveScrollbars(bool) final;
     WEBCORE_EXPORT void updateCanHaveScrollbars();
 
+    bool isVisibleToHitTesting() const final;
+
     Ref<Scrollbar> createScrollbar(ScrollbarOrientation) final;
 
     bool avoidScrollbarCreation() const final;

Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp (295447 => 295448)


--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp	2022-06-10 06:29:03 UTC (rev 295447)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp	2022-06-10 08:04:47 UTC (rev 295448)
@@ -37,6 +37,7 @@
 #include "PluginViewBase.h"
 #include "Region.h"
 #include "RenderLayerCompositor.h"
+#include "RenderLayerScrollableArea.h"
 #include "RenderView.h"
 #include "ScrollAnimator.h"
 #include "Settings.h"
@@ -125,7 +126,7 @@
     if (auto* scrollableAreas = frameView->scrollableAreas()) {
         for (auto& scrollableArea : *scrollableAreas) {
             // Composited scrollable areas can be scrolled off the main thread.
-            if (scrollableArea->usesAsyncScrolling())
+            if (!scrollableArea->isVisibleToHitTesting() || scrollableArea->usesAsyncScrolling())
                 continue;
 
             bool isInsideFixed;

Modified: trunk/Source/WebCore/platform/ScrollableArea.h (295447 => 295448)


--- trunk/Source/WebCore/platform/ScrollableArea.h	2022-06-10 06:29:03 UTC (rev 295447)
+++ trunk/Source/WebCore/platform/ScrollableArea.h	2022-06-10 08:04:47 UTC (rev 295448)
@@ -288,6 +288,8 @@
         LegacyIOSDocumentVisibleRect = ContentsVisibleRect
 #endif
     };
+    
+    virtual bool isVisibleToHitTesting() const { return false; };
 
     WEBCORE_EXPORT IntRect visibleContentRect(VisibleContentRectBehavior = ContentsVisibleRect) const;
     WEBCORE_EXPORT IntRect visibleContentRectIncludingScrollbars(VisibleContentRectBehavior = ContentsVisibleRect) const;

Modified: trunk/Source/WebCore/rendering/RenderLayerScrollableArea.cpp (295447 => 295448)


--- trunk/Source/WebCore/rendering/RenderLayerScrollableArea.cpp	2022-06-10 06:29:03 UTC (rev 295447)
+++ trunk/Source/WebCore/rendering/RenderLayerScrollableArea.cpp	2022-06-10 08:04:47 UTC (rev 295448)
@@ -84,8 +84,6 @@
 void RenderLayerScrollableArea::clear()
 {
     auto& renderer = m_layer.renderer();
-    ASSERT(m_registeredScrollableArea == renderer.view().frameView().containsScrollableArea(this));
-
     if (m_registeredScrollableArea)
         renderer.view().frameView().removeScrollableArea(this);
 
@@ -281,6 +279,8 @@
         scrollAnimator().cancelAnimations();
         stopAsyncAnimatedScroll();
     }
+    
+    registerScrollableArea();
 
     ScrollOffset clampedScrollOffset = options.clamping == ScrollClamping::Clamped ? clampScrollOffset(scrollOffset) : scrollOffset;
     if (clampedScrollOffset == this->scrollOffset())
@@ -1624,6 +1624,12 @@
 {
     return scrollsOverflow() || usesCompositedScrolling();
 }
+bool RenderLayerScrollableArea::isVisibleToHitTesting() const
+{
+    auto& renderer = m_layer.renderer();
+    FrameView& frameView = renderer.view().frameView();
+    return renderer.visibleToHitTesting() && frameView.isVisibleToHitTesting();
+}
 
 void RenderLayerScrollableArea::updateScrollableAreaSet(bool hasOverflow)
 {
@@ -1637,8 +1643,6 @@
     bool isScrollable = hasOverflow && isVisibleToHitTest;
     bool addedOrRemoved = false;
 
-    ASSERT(m_registeredScrollableArea == frameView.containsScrollableArea(this));
-
     if (isScrollable) {
         if (!m_registeredScrollableArea) {
             addedOrRemoved = frameView.addScrollableArea(this);
@@ -1664,6 +1668,17 @@
 #endif
 }
 
+void RenderLayerScrollableArea::registerScrollableArea()
+{
+    auto& renderer = m_layer.renderer();
+    FrameView& frameView = renderer.view().frameView();
+
+    if (!m_registeredScrollableArea) {
+        frameView.addScrollableArea(this);
+        m_registeredScrollableArea = true;
+    }
+}
+
 void RenderLayerScrollableArea::updateScrollCornerStyle()
 {
     auto& renderer = m_layer.renderer();

Modified: trunk/Source/WebCore/rendering/RenderLayerScrollableArea.h (295447 => 295448)


--- trunk/Source/WebCore/rendering/RenderLayerScrollableArea.h	2022-06-10 06:29:03 UTC (rev 295447)
+++ trunk/Source/WebCore/rendering/RenderLayerScrollableArea.h	2022-06-10 08:04:47 UTC (rev 295448)
@@ -238,6 +238,7 @@
     IntSize scrollbarOffset(const Scrollbar&) const;
 
     std::optional<LayoutRect> updateScrollPosition(const ScrollPositionChangeOptions&, const LayoutRect& revealRect, const LayoutRect& localExposeRect);
+    bool isVisibleToHitTesting() const final;
 
 private:
     bool hasHorizontalOverflow() const;
@@ -264,6 +265,7 @@
     void clearResizer();
 
     void updateScrollbarPresenceAndState(std::optional<bool> hasHorizontalOverflow = std::nullopt, std::optional<bool> hasVerticalOverflow = std::nullopt);
+    void registerScrollableArea();
 
 private:
     bool m_scrollDimensionsDirty { true };

Modified: trunk/Source/WebCore/rendering/RenderListBox.h (295447 => 295448)


--- trunk/Source/WebCore/rendering/RenderListBox.h	2022-06-10 06:29:03 UTC (rev 295447)
+++ trunk/Source/WebCore/rendering/RenderListBox.h	2022-06-10 08:04:47 UTC (rev 295448)
@@ -65,6 +65,8 @@
     bool scrolledToBottom() const final;
     bool scrolledToLeft() const final;
     bool scrolledToRight() const final;
+    
+    bool isVisibleToHitTesting() const final { return visibleToHitTesting(); };
 
 private:
     void willBeDestroyed() override;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to