- 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;