Make it possible to query scrollbar pseudo-style without having a scrollbar
https://bugs.webkit.org/show_bug.cgi?id=203174
Reviewed by Tim Horton.
A future patch needs the ability to query scrollbar pseudo-style without having
a scrollbar, and it was ugly to pass a live RenderScrollbar into CSS style resolution
functions. Instead, pass in a pure-data object that has information about the scrollbar.
* css/ElementRuleCollector.cpp:
(WebCore::ElementRuleCollector::ruleMatches):
* css/SelectorChecker.h:
* css/SelectorCheckerTestFunctions.h:
(WebCore::scrollbarMatchesEnabledPseudoClass):
(WebCore::scrollbarMatchesDisabledPseudoClass):
(WebCore::scrollbarMatchesHoverPseudoClass):
(WebCore::scrollbarMatchesActivePseudoClass):
(WebCore::scrollbarMatchesHorizontalPseudoClass):
(WebCore::scrollbarMatchesVerticalPseudoClass):
(WebCore::scrollbarMatchesDecrementPseudoClass):
(WebCore::scrollbarMatchesIncrementPseudoClass):
(WebCore::scrollbarMatchesStartPseudoClass):
(WebCore::scrollbarMatchesEndPseudoClass):
(WebCore::scrollbarMatchesDoubleButtonPseudoClass):
(WebCore::scrollbarMatchesSingleButtonPseudoClass):
(WebCore::scrollbarMatchesNoButtonPseudoClass):
(WebCore::scrollbarMatchesCornerPresentPseudoClass):
* css/StyleResolver.h:
(WebCore::PseudoStyleRequest::PseudoStyleRequest):
* rendering/RenderScrollbar.cpp:
(WebCore::RenderScrollbar::getScrollbarPseudoStyle):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251319 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index d5bf3a4..c4d1b64 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,37 @@
+2019-10-18 Simon Fraser <simon.fraser@apple.com>
+
+ Make it possible to query scrollbar pseudo-style without having a scrollbar
+ https://bugs.webkit.org/show_bug.cgi?id=203174
+
+ Reviewed by Tim Horton.
+
+ A future patch needs the ability to query scrollbar pseudo-style without having
+ a scrollbar, and it was ugly to pass a live RenderScrollbar into CSS style resolution
+ functions. Instead, pass in a pure-data object that has information about the scrollbar.
+
+ * css/ElementRuleCollector.cpp:
+ (WebCore::ElementRuleCollector::ruleMatches):
+ * css/SelectorChecker.h:
+ * css/SelectorCheckerTestFunctions.h:
+ (WebCore::scrollbarMatchesEnabledPseudoClass):
+ (WebCore::scrollbarMatchesDisabledPseudoClass):
+ (WebCore::scrollbarMatchesHoverPseudoClass):
+ (WebCore::scrollbarMatchesActivePseudoClass):
+ (WebCore::scrollbarMatchesHorizontalPseudoClass):
+ (WebCore::scrollbarMatchesVerticalPseudoClass):
+ (WebCore::scrollbarMatchesDecrementPseudoClass):
+ (WebCore::scrollbarMatchesIncrementPseudoClass):
+ (WebCore::scrollbarMatchesStartPseudoClass):
+ (WebCore::scrollbarMatchesEndPseudoClass):
+ (WebCore::scrollbarMatchesDoubleButtonPseudoClass):
+ (WebCore::scrollbarMatchesSingleButtonPseudoClass):
+ (WebCore::scrollbarMatchesNoButtonPseudoClass):
+ (WebCore::scrollbarMatchesCornerPresentPseudoClass):
+ * css/StyleResolver.h:
+ (WebCore::PseudoStyleRequest::PseudoStyleRequest):
+ * rendering/RenderScrollbar.cpp:
+ (WebCore::RenderScrollbar::getScrollbarPseudoStyle):
+
2019-10-18 Said Abou-Hallawa <sabouhallawa@apple.com>
[SVG2]: Remove the SVGExternalResourcesRequired interface
diff --git a/Source/WebCore/css/ElementRuleCollector.cpp b/Source/WebCore/css/ElementRuleCollector.cpp
index 8e03009..a2a59d2 100644
--- a/Source/WebCore/css/ElementRuleCollector.cpp
+++ b/Source/WebCore/css/ElementRuleCollector.cpp
@@ -481,8 +481,7 @@
SelectorChecker::CheckingContext context(m_mode);
context.pseudoId = m_pseudoStyleRequest.pseudoId;
- context.scrollbar = m_pseudoStyleRequest.scrollbar;
- context.scrollbarPart = m_pseudoStyleRequest.scrollbarPart;
+ context.scrollbarState = m_pseudoStyleRequest.scrollbarState;
context.isMatchingHostPseudoClass = m_isMatchingHostPseudoClass;
context.shadowHostInPartRuleScope = m_shadowHostInPartRuleScope.get();
diff --git a/Source/WebCore/css/SelectorChecker.h b/Source/WebCore/css/SelectorChecker.h
index 22ceb07..ce31016 100644
--- a/Source/WebCore/css/SelectorChecker.h
+++ b/Source/WebCore/css/SelectorChecker.h
@@ -38,6 +38,16 @@
class RenderScrollbar;
class RenderStyle;
+struct StyleScrollbarState {
+ ScrollbarPart scrollbarPart { NoPart };
+ ScrollbarPart hoveredPart { NoPart };
+ ScrollbarPart pressedPart { NoPart };
+ ScrollbarOrientation orientation { VerticalScrollbar };
+ ScrollbarButtonsPlacement buttonsPlacement { ScrollbarButtonsNone };
+ bool enabled { false };
+ bool scrollCornerIsVisible { false };
+};
+
class SelectorChecker {
WTF_MAKE_NONCOPYABLE(SelectorChecker);
enum class Match { SelectorMatches, SelectorFailsLocally, SelectorFailsAllSiblings, SelectorFailsCompletely };
@@ -80,8 +90,7 @@
const SelectorChecker::Mode resolvingMode;
PseudoId pseudoId { PseudoId::None };
- RenderScrollbar* scrollbar { nullptr };
- ScrollbarPart scrollbarPart { NoPart };
+ Optional<StyleScrollbarState> scrollbarState;
const ContainerNode* scope { nullptr };
bool isMatchingHostPseudoClass { false };
const Element* shadowHostInPartRuleScope { nullptr };
diff --git a/Source/WebCore/css/SelectorCheckerTestFunctions.h b/Source/WebCore/css/SelectorCheckerTestFunctions.h
index 8fa80cc..d592866 100644
--- a/Source/WebCore/css/SelectorCheckerTestFunctions.h
+++ b/Source/WebCore/css/SelectorCheckerTestFunctions.h
@@ -32,9 +32,7 @@
#include "HTMLIFrameElement.h"
#include "HTMLInputElement.h"
#include "HTMLOptionElement.h"
-#include "RenderScrollbar.h"
-#include "ScrollableArea.h"
-#include "ScrollbarTheme.h"
+#include "SelectorChecker.h"
#include <wtf/Compiler.h>
#if ENABLE(ATTACHMENT_ELEMENT)
@@ -249,105 +247,122 @@
ALWAYS_INLINE bool scrollbarMatchesEnabledPseudoClass(const SelectorChecker::CheckingContext& context)
{
- return context.scrollbar && context.scrollbar->enabled();
+ return context.scrollbarState && context.scrollbarState->enabled;
}
ALWAYS_INLINE bool scrollbarMatchesDisabledPseudoClass(const SelectorChecker::CheckingContext& context)
{
- return context.scrollbar && !context.scrollbar->enabled();
+ return context.scrollbarState && !context.scrollbarState->enabled;
}
ALWAYS_INLINE bool scrollbarMatchesHoverPseudoClass(const SelectorChecker::CheckingContext& context)
{
- if (!context.scrollbar)
+ if (!context.scrollbarState)
return false;
- ScrollbarPart hoveredPart = context.scrollbar->hoveredPart();
- if (context.scrollbarPart == ScrollbarBGPart)
+ auto scrollbarPart = context.scrollbarState->scrollbarPart;
+ auto hoveredPart = context.scrollbarState->hoveredPart;
+ if (scrollbarPart == ScrollbarBGPart)
return hoveredPart != NoPart;
- if (context.scrollbarPart == TrackBGPart)
+ if (scrollbarPart == TrackBGPart)
return hoveredPart == BackTrackPart || hoveredPart == ForwardTrackPart || hoveredPart == ThumbPart;
- return context.scrollbarPart == hoveredPart;
+ return scrollbarPart == hoveredPart;
}
ALWAYS_INLINE bool scrollbarMatchesActivePseudoClass(const SelectorChecker::CheckingContext& context)
{
- if (!context.scrollbar)
+ if (!context.scrollbarState)
return false;
- ScrollbarPart pressedPart = context.scrollbar->pressedPart();
- if (context.scrollbarPart == ScrollbarBGPart)
+ auto scrollbarPart = context.scrollbarState->scrollbarPart;
+ auto pressedPart = context.scrollbarState->pressedPart;
+ if (scrollbarPart == ScrollbarBGPart)
return pressedPart != NoPart;
- if (context.scrollbarPart == TrackBGPart)
+ if (scrollbarPart == TrackBGPart)
return pressedPart == BackTrackPart || pressedPart == ForwardTrackPart || pressedPart == ThumbPart;
- return context.scrollbarPart == pressedPart;
+ return scrollbarPart == pressedPart;
}
ALWAYS_INLINE bool scrollbarMatchesHorizontalPseudoClass(const SelectorChecker::CheckingContext& context)
{
- return context.scrollbar && context.scrollbar->orientation() == HorizontalScrollbar;
+ return context.scrollbarState && context.scrollbarState->orientation == HorizontalScrollbar;
}
ALWAYS_INLINE bool scrollbarMatchesVerticalPseudoClass(const SelectorChecker::CheckingContext& context)
{
- return context.scrollbar && context.scrollbar->orientation() == VerticalScrollbar;
+ return context.scrollbarState && context.scrollbarState->orientation == VerticalScrollbar;
}
ALWAYS_INLINE bool scrollbarMatchesDecrementPseudoClass(const SelectorChecker::CheckingContext& context)
{
- return context.scrollbarPart == BackButtonStartPart || context.scrollbarPart == BackButtonEndPart || context.scrollbarPart == BackTrackPart;
+ if (!context.scrollbarState)
+ return false;
+ auto scrollbarPart = context.scrollbarState->scrollbarPart;
+ return scrollbarPart == BackButtonStartPart || scrollbarPart == BackButtonEndPart || scrollbarPart == BackTrackPart;
}
ALWAYS_INLINE bool scrollbarMatchesIncrementPseudoClass(const SelectorChecker::CheckingContext& context)
{
- return context.scrollbarPart == ForwardButtonStartPart || context.scrollbarPart == ForwardButtonEndPart || context.scrollbarPart == ForwardTrackPart;
+ if (!context.scrollbarState)
+ return false;
+ auto scrollbarPart = context.scrollbarState->scrollbarPart;
+ return scrollbarPart == ForwardButtonStartPart || scrollbarPart == ForwardButtonEndPart || scrollbarPart == ForwardTrackPart;
}
ALWAYS_INLINE bool scrollbarMatchesStartPseudoClass(const SelectorChecker::CheckingContext& context)
{
- return context.scrollbarPart == BackButtonStartPart || context.scrollbarPart == ForwardButtonStartPart || context.scrollbarPart == BackTrackPart;
+ if (!context.scrollbarState)
+ return false;
+ auto scrollbarPart = context.scrollbarState->scrollbarPart;
+ return scrollbarPart == BackButtonStartPart || scrollbarPart == ForwardButtonStartPart || scrollbarPart == BackTrackPart;
}
ALWAYS_INLINE bool scrollbarMatchesEndPseudoClass(const SelectorChecker::CheckingContext& context)
{
- return context.scrollbarPart == BackButtonEndPart || context.scrollbarPart == ForwardButtonEndPart || context.scrollbarPart == ForwardTrackPart;
+ if (!context.scrollbarState)
+ return false;
+ auto scrollbarPart = context.scrollbarState->scrollbarPart;
+ return scrollbarPart == BackButtonEndPart || scrollbarPart == ForwardButtonEndPart || scrollbarPart == ForwardTrackPart;
}
ALWAYS_INLINE bool scrollbarMatchesDoubleButtonPseudoClass(const SelectorChecker::CheckingContext& context)
{
- if (!context.scrollbar)
+ if (!context.scrollbarState)
return false;
- ScrollbarButtonsPlacement buttonsPlacement = context.scrollbar->theme().buttonsPlacement();
- if (context.scrollbarPart == BackButtonStartPart || context.scrollbarPart == ForwardButtonStartPart || context.scrollbarPart == BackTrackPart)
+ auto scrollbarPart = context.scrollbarState->scrollbarPart;
+ auto buttonsPlacement = context.scrollbarState->buttonsPlacement;
+ if (scrollbarPart == BackButtonStartPart || scrollbarPart == ForwardButtonStartPart || scrollbarPart == BackTrackPart)
return buttonsPlacement == ScrollbarButtonsDoubleStart || buttonsPlacement == ScrollbarButtonsDoubleBoth;
- if (context.scrollbarPart == BackButtonEndPart || context.scrollbarPart == ForwardButtonEndPart || context.scrollbarPart == ForwardTrackPart)
+ if (scrollbarPart == BackButtonEndPart || scrollbarPart == ForwardButtonEndPart || scrollbarPart == ForwardTrackPart)
return buttonsPlacement == ScrollbarButtonsDoubleEnd || buttonsPlacement == ScrollbarButtonsDoubleBoth;
return false;
}
ALWAYS_INLINE bool scrollbarMatchesSingleButtonPseudoClass(const SelectorChecker::CheckingContext& context)
{
- if (!context.scrollbar)
+ if (!context.scrollbarState)
return false;
- ScrollbarButtonsPlacement buttonsPlacement = context.scrollbar->theme().buttonsPlacement();
- if (context.scrollbarPart == BackButtonStartPart || context.scrollbarPart == ForwardButtonEndPart || context.scrollbarPart == BackTrackPart || context.scrollbarPart == ForwardTrackPart)
+ auto scrollbarPart = context.scrollbarState->scrollbarPart;
+ auto buttonsPlacement = context.scrollbarState->buttonsPlacement;
+ if (scrollbarPart == BackButtonStartPart || scrollbarPart == ForwardButtonEndPart || scrollbarPart == BackTrackPart || scrollbarPart == ForwardTrackPart)
return buttonsPlacement == ScrollbarButtonsSingle;
return false;
}
ALWAYS_INLINE bool scrollbarMatchesNoButtonPseudoClass(const SelectorChecker::CheckingContext& context)
{
- if (!context.scrollbar)
+ if (!context.scrollbarState)
return false;
- ScrollbarButtonsPlacement buttonsPlacement = context.scrollbar->theme().buttonsPlacement();
- if (context.scrollbarPart == BackTrackPart)
+ auto scrollbarPart = context.scrollbarState->scrollbarPart;
+ auto buttonsPlacement = context.scrollbarState->buttonsPlacement;
+ if (scrollbarPart == BackTrackPart)
return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleEnd;
- if (context.scrollbarPart == ForwardTrackPart)
+ if (scrollbarPart == ForwardTrackPart)
return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleStart;
return false;
}
ALWAYS_INLINE bool scrollbarMatchesCornerPresentPseudoClass(const SelectorChecker::CheckingContext& context)
{
- return context.scrollbar && context.scrollbar->scrollableArea().isScrollCornerVisible();
+ return context.scrollbarState && context.scrollbarState->scrollCornerIsVisible;
}
#if ENABLE(FULLSCREEN_API)
diff --git a/Source/WebCore/css/StyleResolver.h b/Source/WebCore/css/StyleResolver.h
index e0c318e..52941ba 100644
--- a/Source/WebCore/css/StyleResolver.h
+++ b/Source/WebCore/css/StyleResolver.h
@@ -101,16 +101,14 @@
class PseudoStyleRequest {
public:
- PseudoStyleRequest(PseudoId pseudoId, RenderScrollbar* scrollbar = nullptr, ScrollbarPart scrollbarPart = NoPart)
+ PseudoStyleRequest(PseudoId pseudoId, Optional<StyleScrollbarState> scrollbarState = WTF::nullopt)
: pseudoId(pseudoId)
- , scrollbarPart(scrollbarPart)
- , scrollbar(scrollbar)
+ , scrollbarState(scrollbarState)
{
}
PseudoId pseudoId;
- ScrollbarPart scrollbarPart;
- RenderScrollbar* scrollbar;
+ Optional<StyleScrollbarState> scrollbarState;
};
struct ElementStyle {
diff --git a/Source/WebCore/rendering/RenderScrollbar.cpp b/Source/WebCore/rendering/RenderScrollbar.cpp
index 422ba92..2bee864 100644
--- a/Source/WebCore/rendering/RenderScrollbar.cpp
+++ b/Source/WebCore/rendering/RenderScrollbar.cpp
@@ -139,9 +139,18 @@
std::unique_ptr<RenderStyle> RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart partType, PseudoId pseudoId)
{
if (!owningRenderer())
- return 0;
+ return nullptr;
- std::unique_ptr<RenderStyle> result = owningRenderer()->getUncachedPseudoStyle(PseudoStyleRequest(pseudoId, this, partType), &owningRenderer()->style());
+ StyleScrollbarState scrollbarState;
+ scrollbarState.scrollbarPart = partType;
+ scrollbarState.hoveredPart = hoveredPart();
+ scrollbarState.pressedPart = pressedPart();
+ scrollbarState.orientation = orientation();
+ scrollbarState.buttonsPlacement = theme().buttonsPlacement();
+ scrollbarState.enabled = enabled();
+ scrollbarState.scrollCornerIsVisible = scrollableArea().isScrollCornerVisible();
+
+ std::unique_ptr<RenderStyle> result = owningRenderer()->getUncachedPseudoStyle(PseudoStyleRequest(pseudoId, scrollbarState), &owningRenderer()->style());
// Scrollbars for root frames should always have background color
// unless explicitly specified as transparent. So we force it.
// This is because WebKit assumes scrollbar to be always painted and missing background