[iOS WK2] Support hiding iframe scrollbars via ::-webkit-scrollbar style
https://bugs.webkit.org/show_bug.cgi?id=203178

Reviewed by Dean Jackson.
Source/WebCore:

::-webkit-scrollbar {
    display: none;
}
is supported for overflow:scroll, but not for iframes. To make the latter work,
two fixes were necessary.

First, FrameView had to implement horizontalScrollbarHiddenByStyle()/verticalScrollbarHiddenByStyle().
This is a little tricky on iOS because we never create RenderScrollbars, so we have to consult
pseudo-styles directly; a bit of refactoring makes that cleaner.

Second, ScrollableAreaParameters was failing to check horizontalScrollbarHiddenByStyle/verticalScrollbarHiddenByStyle
in operator==, meaning that these data often didn't make it to the UI process.

Test: fast/scrolling/ios/scrollbar-hiding-iframes.html

* page/FrameView.cpp:
(WebCore::FrameView::rootElementForCustomScrollbarPartStyle const):
(WebCore::FrameView::createScrollbar):
(WebCore::FrameView::styleHidesScrollbarWithOrientation const):
(WebCore::FrameView::horizontalScrollbarHiddenByStyle const):
(WebCore::FrameView::verticalScrollbarHiddenByStyle const):
(WebCore::FrameView::updateScrollCorner):
* page/FrameView.h:
* page/scrolling/ScrollingCoordinatorTypes.h:
(WebCore::ScrollableAreaParameters::operator== const):
* platform/Scrollbar.h:
(WebCore::Scrollbar::isHiddenByStyle const):
* rendering/RenderLayer.cpp:
(WebCore::scrollbarHiddenByStyle):
* rendering/RenderScrollbar.cpp:
(WebCore::RenderScrollbar::getScrollbarPseudoStyle const):
(WebCore::RenderScrollbar::isHiddenByStyle const):
(WebCore::RenderScrollbar::getScrollbarPseudoStyle): Deleted.
* rendering/RenderScrollbar.h:

LayoutTests:

Tests that dumps the scrolling tree.

* fast/scrolling/ios/scrollbar-hiding-iframes-expected.txt: Added.
* fast/scrolling/ios/scrollbar-hiding-iframes.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251369 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 3317cf8..45f3a44 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2019-10-21  Simon Fraser  <simon.fraser@apple.com>
+
+        [iOS WK2] Support hiding iframe scrollbars via ::-webkit-scrollbar style
+        https://bugs.webkit.org/show_bug.cgi?id=203178
+
+        Reviewed by Dean Jackson.
+
+        Tests that dumps the scrolling tree.
+
+        * fast/scrolling/ios/scrollbar-hiding-iframes-expected.txt: Added.
+        * fast/scrolling/ios/scrollbar-hiding-iframes.html: Added.
+
 2019-10-21  youenn fablet  <youenn@apple.com>
 
         Share code between AudioDestinationIOS and AudioDestinationMac
diff --git a/LayoutTests/fast/scrolling/ios/scrollbar-hiding-expected.txt b/LayoutTests/fast/scrolling/ios/scrollbar-hiding-expected.txt
index aad95c4..6c97784 100644
--- a/LayoutTests/fast/scrolling/ios/scrollbar-hiding-expected.txt
+++ b/LayoutTests/fast/scrolling/ios/scrollbar-hiding-expected.txt
@@ -18,7 +18,9 @@
       (horizontal scroll elasticity 1)
       (vertical scroll elasticity 1)
       (horizontal scrollbar mode 0)
-      (vertical scrollbar mode 0))
+      (vertical scrollbar mode 0)
+      (horizontal scrollbar hidden by style 1)
+      (vertical scrollbar hidden by style 1))
     (layout viewport (0,0) width=800 height=600)
     (min layoutViewport origin (0,0))
     (max layoutViewport origin (0,0))
@@ -33,18 +35,8 @@
         (horizontal scrollbar mode 0)
         (vertical scrollbar mode 0)
         (has enabled horizontal scrollbar 1)
-        (has enabled vertical scrollbar 1)))
-    (overflow scrolling node
-      (scrollable area size width=200 height=100)
-      (total content size width=400 height=200)
-      (last committed scroll position (0,0))
-      (scrollable area parameters 
-        (horizontal scroll elasticity 1)
-        (vertical scroll elasticity 1)
-        (horizontal scrollbar mode 0)
-        (vertical scrollbar mode 0)
-        (has enabled horizontal scrollbar 1)
         (has enabled vertical scrollbar 1)
+        (horizontal scrollbar hidden by style 1)
         (vertical scrollbar hidden by style 1)))
     (overflow scrolling node
       (scrollable area size width=200 height=100)
@@ -69,5 +61,15 @@
         (vertical scrollbar mode 0)
         (has enabled horizontal scrollbar 1)
         (has enabled vertical scrollbar 1)
-        (horizontal scrollbar hidden by style 1)
-        (vertical scrollbar hidden by style 1)))))
+        (vertical scrollbar hidden by style 1)))
+    (overflow scrolling node
+      (scrollable area size width=200 height=100)
+      (total content size width=400 height=200)
+      (last committed scroll position (0,0))
+      (scrollable area parameters 
+        (horizontal scroll elasticity 1)
+        (vertical scroll elasticity 1)
+        (horizontal scrollbar mode 0)
+        (vertical scrollbar mode 0)
+        (has enabled horizontal scrollbar 1)
+        (has enabled vertical scrollbar 1)))))
diff --git a/LayoutTests/fast/scrolling/ios/scrollbar-hiding-iframes-expected.txt b/LayoutTests/fast/scrolling/ios/scrollbar-hiding-iframes-expected.txt
new file mode 100644
index 0000000..3882bcf
--- /dev/null
+++ b/LayoutTests/fast/scrolling/ios/scrollbar-hiding-iframes-expected.txt
@@ -0,0 +1,89 @@
+Both Visible
+
+ 
+Horizontal visible
+
+
+Vertical visible
+
+ 
+None visible
+
+
+
+(scrolling tree
+  (frame scrolling node
+    (scrollable area size width=800 height=600)
+    (total content size width=800 height=600)
+    (last committed scroll position (0,0))
+    (scrollable area parameters 
+      (horizontal scroll elasticity 1)
+      (vertical scroll elasticity 1)
+      (horizontal scrollbar mode 0)
+      (vertical scrollbar mode 0)
+      (horizontal scrollbar hidden by style 1)
+      (vertical scrollbar hidden by style 1))
+    (layout viewport (0,0) width=800 height=600)
+    (min layoutViewport origin (0,0))
+    (max layoutViewport origin (0,0))
+    (behavior for fixed 0)
+    (frame hosting node
+      (frame scrolling node
+        (scrollable area size width=300 height=150)
+        (total content size width=1008 height=1016)
+        (last committed scroll position (0,0))
+        (scrollable area parameters 
+          (horizontal scroll elasticity 1)
+          (vertical scroll elasticity 1)
+          (horizontal scrollbar mode 0)
+          (vertical scrollbar mode 0))
+        (layout viewport (0,0) width=300 height=150)
+        (min layoutViewport origin (0,0))
+        (max layoutViewport origin (708,866))
+        (behavior for fixed 0)))
+    (frame hosting node
+      (frame scrolling node
+        (scrollable area size width=300 height=150)
+        (total content size width=1008 height=1016)
+        (last committed scroll position (0,0))
+        (scrollable area parameters 
+          (horizontal scroll elasticity 1)
+          (vertical scroll elasticity 1)
+          (horizontal scrollbar mode 0)
+          (vertical scrollbar mode 0)
+          (vertical scrollbar hidden by style 1))
+        (layout viewport (0,0) width=300 height=150)
+        (min layoutViewport origin (0,0))
+        (max layoutViewport origin (708,866))
+        (behavior for fixed 0)))
+    (frame hosting node
+      (frame scrolling node
+        (scrollable area size width=300 height=150)
+        (total content size width=1008 height=1016)
+        (last committed scroll position (0,0))
+        (scrollable area parameters 
+          (horizontal scroll elasticity 1)
+          (vertical scroll elasticity 1)
+          (horizontal scrollbar mode 0)
+          (vertical scrollbar mode 0)
+          (horizontal scrollbar hidden by style 1))
+        (layout viewport (0,0) width=300 height=150)
+        (min layoutViewport origin (0,0))
+        (max layoutViewport origin (708,866))
+        (behavior for fixed 0)))
+    (frame hosting node
+      (frame scrolling node
+        (scrollable area size width=300 height=150)
+        (total content size width=1008 height=1016)
+        (last committed scroll position (0,0))
+        (scrollable area parameters 
+          (horizontal scroll elasticity 1)
+          (vertical scroll elasticity 1)
+          (horizontal scrollbar mode 0)
+          (vertical scrollbar mode 0)
+          (horizontal scrollbar hidden by style 1)
+          (vertical scrollbar hidden by style 1))
+        (layout viewport (0,0) width=300 height=150)
+        (min layoutViewport origin (0,0))
+        (max layoutViewport origin (708,866))
+        (behavior for fixed 0)))))
diff --git a/LayoutTests/fast/scrolling/ios/scrollbar-hiding-iframes.html b/LayoutTests/fast/scrolling/ios/scrollbar-hiding-iframes.html
new file mode 100644
index 0000000..8e33aa9
--- /dev/null
+++ b/LayoutTests/fast/scrolling/ios/scrollbar-hiding-iframes.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncFrameScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        ::-webkit-scrollbar {
+            width: 16px;
+            height: 16px;
+            background-color: silver;
+        }
+
+        ::-webkit-scrollbar-track {
+            -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
+            border-radius: 10px;
+        }
+
+        ::-webkit-scrollbar-thumb {
+            border-radius: 10px;
+            -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
+        }
+
+        .container {
+            display: inline-block;
+        }
+
+        .overflowing {
+            margin: 20px;
+            height: 100px;
+            width: 200px;
+            border: 1px solid black;
+            overflow: scroll;
+            -webkit-overflow-scrolling: touch;
+        }
+
+        .contents {
+            width: 200%;
+            height: 200%;
+        }
+
+        ::-webkit-scrollbar {
+            display: none;
+        }
+
+        .vertical::-webkit-scrollbar:vertical {
+            display: block;
+        }
+
+        .horizontal::-webkit-scrollbar:horizontal {
+            display: block;
+        }
+    </style>
+    <script src="../../../resources/ui-helper.js"></script>
+    <script>
+        if (window.testRunner) {
+            testRunner.waitUntilDone();
+            testRunner.dumpAsText();
+        }
+
+        function getScrollingTreeUIScript(x, y)
+        {
+            return `(function() {
+                return uiController.scrollingTreeAsText;
+            })();`;
+        }
+
+        async function doTest()
+        {
+            if (!testRunner.runUIScript)
+                return
+            
+            document.getElementById('scrolling-tree').textContent = await UIHelper.getScrollingTree();
+            testRunner.notifyDone();
+        }
+        
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <div class="container">
+        <h2>Both Visible</h2>
+        <iframe srcdoc="
+        <style>
+        ::-webkit-scrollbar {
+        display: block;
+        background-color: gray;
+        }
+        </style>
+        <body>
+        <div style='width: 1000px; height: 1000px'>Content</div>
+        <body>"></iframe>
+    </div>
+    <div class="container">
+        <h2>Horizontal visible</h2>
+        <iframe srcdoc="
+        <style>
+        ::-webkit-scrollbar {
+        display: block;
+        background-color: gray;
+        }
+
+        ::-webkit-scrollbar:vertical {
+        display: none;
+        }
+        </style>
+        <body>
+        <div style='width: 1000px; height: 1000px'>Content</div>
+        <body>"></iframe>
+    </div>
+    <div class="container">
+        <h2>Vertical visible</h2>
+        <iframe srcdoc="
+        <style>
+        ::-webkit-scrollbar {
+        display: block;
+        background-color: gray;
+        }
+
+        ::-webkit-scrollbar:horizontal {
+        display: none;
+        }
+        </style>
+        <body>
+        <div style='width: 1000px; height: 1000px'>Content</div>
+        <body>"></iframe>
+    </div>
+    <div class="container">
+        <h2>None visible</h2>
+        <iframe srcdoc="
+        <style>
+        ::-webkit-scrollbar {
+        display: none
+        }
+        </style>
+        <body>
+        <div style='width: 1000px; height: 1000px'>Content</div>
+        <body>"></iframe>
+    </div>
+<pre id="scrolling-tree"></pre>
+</body>
+</html>
diff --git a/LayoutTests/fast/scrolling/ios/scrollbar-hiding.html b/LayoutTests/fast/scrolling/ios/scrollbar-hiding.html
index 6cb26d2..8ce2443 100644
--- a/LayoutTests/fast/scrolling/ios/scrollbar-hiding.html
+++ b/LayoutTests/fast/scrolling/ios/scrollbar-hiding.html
@@ -48,28 +48,20 @@
             display: block;
         }
     </style>
+    <script src="../../../resources/ui-helper.js"></script>
     <script>
         if (window.testRunner) {
             testRunner.waitUntilDone();
             testRunner.dumpAsText();
         }
 
-        function getScrollingTreeUIScript(x, y)
-        {
-            return `(function() {
-                return uiController.scrollingTreeAsText;
-            })();`;
-        }
-
-        function doTest()
+        async function doTest()
         {
             if (!testRunner.runUIScript)
                 return
 
-            testRunner.runUIScript(getScrollingTreeUIScript(), function(scrollingTree) {
-                document.getElementById('scrolling-tree').textContent = scrollingTree;
-                testRunner.notifyDone();
-            });
+            document.getElementById('scrolling-tree').textContent = await UIHelper.getScrollingTree();
+            testRunner.notifyDone();
         }
         
         window.addEventListener('load', doTest, false);
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 975c2bb..1a52c1d 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,45 @@
+2019-10-21  Simon Fraser  <simon.fraser@apple.com>
+
+        [iOS WK2] Support hiding iframe scrollbars via ::-webkit-scrollbar style
+        https://bugs.webkit.org/show_bug.cgi?id=203178
+
+        Reviewed by Dean Jackson.
+        
+        ::-webkit-scrollbar {
+            display: none;
+        }
+        is supported for overflow:scroll, but not for iframes. To make the latter work,
+        two fixes were necessary.
+        
+        First, FrameView had to implement horizontalScrollbarHiddenByStyle()/verticalScrollbarHiddenByStyle().
+        This is a little tricky on iOS because we never create RenderScrollbars, so we have to consult
+        pseudo-styles directly; a bit of refactoring makes that cleaner.
+        
+        Second, ScrollableAreaParameters was failing to check horizontalScrollbarHiddenByStyle/verticalScrollbarHiddenByStyle
+        in operator==, meaning that these data often didn't make it to the UI process.
+
+        Test: fast/scrolling/ios/scrollbar-hiding-iframes.html
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::rootElementForCustomScrollbarPartStyle const):
+        (WebCore::FrameView::createScrollbar):
+        (WebCore::FrameView::styleHidesScrollbarWithOrientation const):
+        (WebCore::FrameView::horizontalScrollbarHiddenByStyle const):
+        (WebCore::FrameView::verticalScrollbarHiddenByStyle const):
+        (WebCore::FrameView::updateScrollCorner):
+        * page/FrameView.h:
+        * page/scrolling/ScrollingCoordinatorTypes.h:
+        (WebCore::ScrollableAreaParameters::operator== const):
+        * platform/Scrollbar.h:
+        (WebCore::Scrollbar::isHiddenByStyle const):
+        * rendering/RenderLayer.cpp:
+        (WebCore::scrollbarHiddenByStyle):
+        * rendering/RenderScrollbar.cpp:
+        (WebCore::RenderScrollbar::getScrollbarPseudoStyle const):
+        (WebCore::RenderScrollbar::isHiddenByStyle const):
+        (WebCore::RenderScrollbar::getScrollbarPseudoStyle): Deleted.
+        * rendering/RenderScrollbar.h:
+
 2019-10-21  youenn fablet  <youenn@apple.com>
 
         Share code between AudioDestinationIOS and AudioDestinationMac
diff --git a/Source/WebCore/page/FrameView.cpp b/Source/WebCore/page/FrameView.cpp
index 015a6d1..20cce99 100644
--- a/Source/WebCore/page/FrameView.cpp
+++ b/Source/WebCore/page/FrameView.cpp
@@ -529,26 +529,37 @@
         setCanHaveScrollbars(true);
 }
 
-Ref<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
+RefPtr<Element> FrameView::rootElementForCustomScrollbarPartStyle(PseudoId partPseudoId) const
 {
     // FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
-    Document* doc = frame().document();
+    auto* document = frame().document();
+    if (!document)
+        return nullptr;
 
     // Try the <body> element first as a scrollbar source.
-    HTMLElement* body = doc ? doc->bodyOrFrameset() : nullptr;
-    if (body && body->renderer() && body->renderer()->style().hasPseudoStyle(PseudoId::Scrollbar))
-        return RenderScrollbar::createCustomScrollbar(*this, orientation, body);
+    auto* body = document->bodyOrFrameset();
+    if (body && body->renderer() && body->renderer()->style().hasPseudoStyle(partPseudoId))
+        return body;
     
     // If the <body> didn't have a custom style, then the root element might.
-    Element* docElement = doc ? doc->documentElement() : nullptr;
-    if (docElement && docElement->renderer() && docElement->renderer()->style().hasPseudoStyle(PseudoId::Scrollbar))
-        return RenderScrollbar::createCustomScrollbar(*this, orientation, docElement);
+    auto* docElement = document->documentElement();
+    if (docElement && docElement->renderer() && docElement->renderer()->style().hasPseudoStyle(partPseudoId))
+        return docElement;
 
+    return nullptr;
+}
+
+Ref<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
+{
+    if (auto element = rootElementForCustomScrollbarPartStyle(PseudoId::Scrollbar))
+        return RenderScrollbar::createCustomScrollbar(*this, orientation, element.get());
+    
     // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
+    // FIXME: Seems bad to do this for cross-origin frames.
     RenderWidget* frameRenderer = frame().ownerRenderer();
     if (frameRenderer && frameRenderer->style().hasPseudoStyle(PseudoId::Scrollbar))
         return RenderScrollbar::createCustomScrollbar(*this, orientation, nullptr, &frame());
-    
+
     // Nobody set a custom style, so we just use a native scrollbar.
     return ScrollView::createScrollbar(orientation);
 }
@@ -1409,6 +1420,41 @@
     document->addConsoleMessage(MessageSource::Other, MessageLevel::Debug, builder.toString());
 }
 
+bool FrameView::styleHidesScrollbarWithOrientation(ScrollbarOrientation orientation) const
+{
+    auto element = rootElementForCustomScrollbarPartStyle(PseudoId::Scrollbar);
+    if (!element)
+        return false;
+    auto* renderer = element->renderer();
+    ASSERT(renderer); // rootElementForCustomScrollbarPart assures that it's not null.
+
+    StyleScrollbarState scrollbarState;
+    scrollbarState.scrollbarPart = ScrollbarBGPart;
+    scrollbarState.orientation = orientation;
+    auto scrollbarStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(PseudoId::Scrollbar, scrollbarState), &renderer->style());
+    return scrollbarStyle && scrollbarStyle->display() == DisplayType::None;
+}
+
+bool FrameView::horizontalScrollbarHiddenByStyle() const
+{
+    if (managesScrollbars()) {
+        auto* scrollbar = horizontalScrollbar();
+        return scrollbar && scrollbar->isHiddenByStyle();
+    }
+
+    return styleHidesScrollbarWithOrientation(HorizontalScrollbar);
+}
+
+bool FrameView::verticalScrollbarHiddenByStyle() const
+{
+    if (managesScrollbars()) {
+        auto* scrollbar = verticalScrollbar();
+        return scrollbar && scrollbar->isHiddenByStyle();
+    }
+    
+    return styleHidesScrollbarWithOrientation(VerticalScrollbar);
+}
+
 void FrameView::setCannotBlitToWindow()
 {
     m_cannotBlitToWindow = true;
@@ -3830,6 +3876,7 @@
         
         if (!cornerStyle) {
             // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
+            // FIXME: Seems wrong to do this for cross-origin frames.
             if (RenderWidget* renderer = frame().ownerRenderer())
                 cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(PseudoId::ScrollbarCorner), &renderer->style());
         }
diff --git a/Source/WebCore/page/FrameView.h b/Source/WebCore/page/FrameView.h
index ef51943..413167a 100644
--- a/Source/WebCore/page/FrameView.h
+++ b/Source/WebCore/page/FrameView.h
@@ -749,12 +749,18 @@
     bool usesMockScrollAnimator() const final;
     void logMockScrollAnimatorMessage(const String&) const final;
 
+    bool styleHidesScrollbarWithOrientation(ScrollbarOrientation) const;
+    bool horizontalScrollbarHiddenByStyle() const final;
+    bool verticalScrollbarHiddenByStyle() const final;
+
     // Override scrollbar notifications to update the AXObject cache.
     void didAddScrollbar(Scrollbar*, ScrollbarOrientation) final;
     void willRemoveScrollbar(Scrollbar*, ScrollbarOrientation) final;
 
     IntSize sizeForResizeEvent() const;
     void sendResizeEventIfNeeded();
+    
+    RefPtr<Element> rootElementForCustomScrollbarPartStyle(PseudoId) const;
 
     void adjustScrollbarsForLayout(bool firstLayout);
 
diff --git a/Source/WebCore/page/scrolling/ScrollingCoordinatorTypes.h b/Source/WebCore/page/scrolling/ScrollingCoordinatorTypes.h
index 694efde..9b02ff5 100644
--- a/Source/WebCore/page/scrolling/ScrollingCoordinatorTypes.h
+++ b/Source/WebCore/page/scrolling/ScrollingCoordinatorTypes.h
@@ -79,6 +79,8 @@
             && horizontalScrollbarMode == other.horizontalScrollbarMode
             && verticalScrollbarMode == other.verticalScrollbarMode
             && hasEnabledHorizontalScrollbar == other.hasEnabledHorizontalScrollbar
+            && horizontalScrollbarHiddenByStyle == other.horizontalScrollbarHiddenByStyle
+            && verticalScrollbarHiddenByStyle == other.verticalScrollbarHiddenByStyle
             && hasEnabledVerticalScrollbar == other.hasEnabledVerticalScrollbar
             && useDarkAppearanceForScrollbars == other.useDarkAppearanceForScrollbars;
     }
diff --git a/Source/WebCore/platform/Scrollbar.h b/Source/WebCore/platform/Scrollbar.h
index e2a25b7..cb950e2 100644
--- a/Source/WebCore/platform/Scrollbar.h
+++ b/Source/WebCore/platform/Scrollbar.h
@@ -90,6 +90,7 @@
 
     virtual bool isOverlayScrollbar() const;
     bool shouldParticipateInHitTesting();
+    virtual bool isHiddenByStyle() const { return false; }
 
     bool isWindowActive() const;
 
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index a873fd9..c4f06b4 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -3364,12 +3364,7 @@
 
 static bool scrollbarHiddenByStyle(Scrollbar* scrollbar)
 {
-    if (!scrollbar || !scrollbar->isCustomScrollbar())
-        return false;
-
-    std::unique_ptr<RenderStyle> scrollbarStyle = static_cast<RenderScrollbar*>(scrollbar)->getScrollbarPseudoStyle(ScrollbarBGPart, PseudoId::Scrollbar);
-
-    return scrollbarStyle && scrollbarStyle->display() == DisplayType::None;
+    return scrollbar && scrollbar->isHiddenByStyle();
 }
 
 bool RenderLayer::horizontalScrollbarHiddenByStyle() const
diff --git a/Source/WebCore/rendering/RenderScrollbar.cpp b/Source/WebCore/rendering/RenderScrollbar.cpp
index 2bee864..9dc7221 100644
--- a/Source/WebCore/rendering/RenderScrollbar.cpp
+++ b/Source/WebCore/rendering/RenderScrollbar.cpp
@@ -136,7 +136,7 @@
     updateScrollbarPart(TrackBGPart);
 }
 
-std::unique_ptr<RenderStyle> RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart partType, PseudoId pseudoId)
+std::unique_ptr<RenderStyle> RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart partType, PseudoId pseudoId) const
 {
     if (!owningRenderer())
         return nullptr;
@@ -360,4 +360,10 @@
     return partRenderer->style().opacity();
 }
 
+bool RenderScrollbar::isHiddenByStyle() const
+{
+    std::unique_ptr<RenderStyle> partStyle = getScrollbarPseudoStyle(ScrollbarBGPart, pseudoForScrollbarPart(ScrollbarBGPart));
+    return partStyle && partStyle->display() != DisplayType::None;
+}
+
 }
diff --git a/Source/WebCore/rendering/RenderScrollbar.h b/Source/WebCore/rendering/RenderScrollbar.h
index f8cc9be..ea358df 100644
--- a/Source/WebCore/rendering/RenderScrollbar.h
+++ b/Source/WebCore/rendering/RenderScrollbar.h
@@ -55,8 +55,10 @@
     int minimumThumbLength();
 
     float opacity();
+    
+    bool isHiddenByStyle() const final;
 
-    std::unique_ptr<RenderStyle> getScrollbarPseudoStyle(ScrollbarPart, PseudoId);
+    std::unique_ptr<RenderStyle> getScrollbarPseudoStyle(ScrollbarPart, PseudoId) const;
 
 private:
     RenderScrollbar(ScrollableArea&, ScrollbarOrientation, Element*, Frame*);