Skip to content

Commit

Permalink
Use a light scrollbar for transparent web views in dark mode.
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=191559
rdar://problem/46000489

Reviewed by Dean Jackson.

Source/WebCore:

Test: css-dark-mode/supported-color-schemes-scrollbar.html

* css/CSSProperties.json: Marked supported-color-schemes as a custom Value.
* css/StyleBuilderCustom.h:
(WebCore::StyleBuilderCustom::applyValueSupportedColorSchemes):
* editing/cocoa/WebContentReaderCocoa.mm: Use FrameView's useDarkAppearance().
(WebCore::createFragment):
* inspector/InspectorOverlay.cpp:
(WebCore::InspectorOverlay::paint): Use FrameView's useDarkAppearance().
* page/FrameView.cpp:
(WebCore::FrameView::recalculateScrollbarOverlayStyle): Use a light scrollbar for
transparent web views in dark mode.
(WebCore::FrameView::rendererForSupportedColorSchemes const): Added.
Return the body for document element renderer.
(WebCore::FrameView::useDarkAppearance const): Use rendererForSupportedColorSchemes.
(WebCore::FrameView::styleColorOptions const): Added. Ditto.
* page/FrameView.h:
* rendering/style/RenderStyle.cpp:
(WebCore::rareInheritedDataChangeRequiresRepaint): Drive-by fix. Added supportedColorSchemes.
* rendering/style/RenderStyle.h:
(WebCore::RenderStyle::setHasExplicitlySetSupportedColorSchemes): Added.
(WebCore::RenderStyle::hasExplicitlySetSupportedColorSchemes const): Added.
(WebCore::RenderStyle::NonInheritedFlags::operator== const): Added supportedColorSchemes.
* svg/graphics/SVGImage.cpp:
(WebCore::SVGImage::draw): Use FrameView's useDarkAppearance().
* testing/Internals.cpp:
(WebCore::Internals::setViewIsTransparent): Added.
(WebCore::Internals::scrollbarOverlayStyle const): Added.
* testing/Internals.h:
* testing/Internals.idl: Added setViewIsTransparent and scrollbarOverlayStyle.

Source/WebKit:

* WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.cpp:
(WebKit::InjectedBundleRangeHandle::renderedImage): Use FrameView's useDarkAppaearance().
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::drawRect): Ditto.

LayoutTests:

* css-dark-mode/supported-color-schemes-scrollbar-expected.txt: Added.
* css-dark-mode/supported-color-schemes-scrollbar.html: Added.


Canonical link: https://commits.webkit.org/206359@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238155 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
xeenon committed Nov 14, 2018
1 parent fc5f982 commit f64f580
Show file tree
Hide file tree
Showing 19 changed files with 253 additions and 12 deletions.
11 changes: 11 additions & 0 deletions LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
2018-11-13 Timothy Hatcher <timothy@apple.com>

Use a light scrollbar for transparent web views in dark mode.
https://bugs.webkit.org/show_bug.cgi?id=191559
rdar://problem/46000489

Reviewed by Dean Jackson.

* css-dark-mode/supported-color-schemes-scrollbar-expected.txt: Added.
* css-dark-mode/supported-color-schemes-scrollbar.html: Added.

2018-11-13 Ross Kirsling <ross.kirsling@sony.com>

[WinCairo] Unreviewed layout test gardening.
Expand Down
@@ -0,0 +1,11 @@

PASS Set dark appearance
PASS Set view to transparent
PASS Body Element supported color scheme is light and dark
PASS Document Element supported color scheme is auto
PASS Scrollbar overlay style is light
PASS Set prefers-color-schemes: light on the document element
PASS Body Element supported color scheme is light and dark
PASS Document Element supported color scheme is light
PASS Scrollbar overlay style is default

66 changes: 66 additions & 0 deletions LayoutTests/css-dark-mode/supported-color-schemes-scrollbar.html
@@ -0,0 +1,66 @@
<!DOCTYPE html>

<!-- webkit-test-runner [ experimental:DarkModeCSSEnabled=true ] -->

<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>

<style>
body {
supported-color-schemes: light dark;
}
</style>

<body></body>

<script>
function test_prop(element, prop, expected) {
assert_equals(window.getComputedStyle(element).getPropertyValue(prop), expected);
}

test(function() {
if (!window.internals)
return;
internals.settings.setUseDarkAppearance(true);
}, "Set dark appearance");

test(function() {
if (!window.internals)
return;
internals.setViewIsTransparent(true);
}, "Set view to transparent");

test(function() {
test_prop(document.body, "supported-color-schemes", "light dark");
}, "Body Element supported color scheme is light and dark");

test(function() {
test_prop(document.documentElement, "supported-color-schemes", "auto");
}, "Document Element supported color scheme is auto");

test(function() {
if (!window.internals)
return;
assert_equals(internals.scrollbarOverlayStyle(), "light");
}, "Scrollbar overlay style is light");

test(function() {
let styleElement = document.createElement("style");
styleElement.textContent = ":root { supported-color-schemes: light }";
document.head.appendChild(styleElement);
}, "Set prefers-color-schemes: light on the document element");

test(function() {
test_prop(document.body, "supported-color-schemes", "light dark");
}, "Body Element supported color scheme is light and dark");

test(function() {
test_prop(document.documentElement, "supported-color-schemes", "light");
}, "Document Element supported color scheme is light");

test(function() {
if (!window.internals)
return;
assert_equals(internals.scrollbarOverlayStyle(), "default");
}, "Scrollbar overlay style is default");
</script>
39 changes: 39 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,42 @@
2018-11-13 Timothy Hatcher <timothy@apple.com>

Use a light scrollbar for transparent web views in dark mode.
https://bugs.webkit.org/show_bug.cgi?id=191559
rdar://problem/46000489

Reviewed by Dean Jackson.

Test: css-dark-mode/supported-color-schemes-scrollbar.html

* css/CSSProperties.json: Marked supported-color-schemes as a custom Value.
* css/StyleBuilderCustom.h:
(WebCore::StyleBuilderCustom::applyValueSupportedColorSchemes):
* editing/cocoa/WebContentReaderCocoa.mm: Use FrameView's useDarkAppearance().
(WebCore::createFragment):
* inspector/InspectorOverlay.cpp:
(WebCore::InspectorOverlay::paint): Use FrameView's useDarkAppearance().
* page/FrameView.cpp:
(WebCore::FrameView::recalculateScrollbarOverlayStyle): Use a light scrollbar for
transparent web views in dark mode.
(WebCore::FrameView::rendererForSupportedColorSchemes const): Added.
Return the body for document element renderer.
(WebCore::FrameView::useDarkAppearance const): Use rendererForSupportedColorSchemes.
(WebCore::FrameView::styleColorOptions const): Added. Ditto.
* page/FrameView.h:
* rendering/style/RenderStyle.cpp:
(WebCore::rareInheritedDataChangeRequiresRepaint): Drive-by fix. Added supportedColorSchemes.
* rendering/style/RenderStyle.h:
(WebCore::RenderStyle::setHasExplicitlySetSupportedColorSchemes): Added.
(WebCore::RenderStyle::hasExplicitlySetSupportedColorSchemes const): Added.
(WebCore::RenderStyle::NonInheritedFlags::operator== const): Added supportedColorSchemes.
* svg/graphics/SVGImage.cpp:
(WebCore::SVGImage::draw): Use FrameView's useDarkAppearance().
* testing/Internals.cpp:
(WebCore::Internals::setViewIsTransparent): Added.
(WebCore::Internals::scrollbarOverlayStyle const): Added.
* testing/Internals.h:
* testing/Internals.idl: Added setViewIsTransparent and scrollbarOverlayStyle.

2018-11-13 Ross Kirsling <ross.kirsling@sony.com>

[AppleWin] Unreviewed build fix after r238108.
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/css/CSSProperties.json
Expand Up @@ -5723,6 +5723,7 @@
"codegen-properties": {
"converter": "SupportedColorSchemes",
"comment": "This is the second highest priority property, to ensure that its value can be checked when resolving colors.",
"custom": "Value",
"enable-if": "ENABLE_DARK_MODE_CSS",
"high-priority": true
},
Expand Down
12 changes: 12 additions & 0 deletions Source/WebCore/css/StyleBuilderCustom.h
Expand Up @@ -142,6 +142,10 @@ class StyleBuilderCustom {
static void applyValueAlt(StyleResolver&, CSSValue&);
static void applyValueWillChange(StyleResolver&, CSSValue&);

#if ENABLE(DARK_MODE_CSS)
static void applyValueSupportedColorSchemes(StyleResolver&, CSSValue&);
#endif

static void applyValueStrokeWidth(StyleResolver&, CSSValue&);
static void applyValueStrokeColor(StyleResolver&, CSSValue&);

Expand Down Expand Up @@ -827,6 +831,14 @@ inline void StyleBuilderCustom::applyValueWebkitTextZoom(StyleResolver& styleRes
styleResolver.state().setFontDirty(true);
}

#if ENABLE(DARK_MODE_CSS)
inline void StyleBuilderCustom::applyValueSupportedColorSchemes(StyleResolver& styleResolver, CSSValue& value)
{
styleResolver.style()->setSupportedColorSchemes(StyleBuilderConverter::convertSupportedColorSchemes(styleResolver, value));
styleResolver.style()->setHasExplicitlySetSupportedColorSchemes(true);
}
#endif

template<CSSPropertyID property>
inline void StyleBuilderCustom::applyTextOrBoxShadowValue(StyleResolver& styleResolver, CSSValue& value)
{
Expand Down
3 changes: 1 addition & 2 deletions Source/WebCore/editing/cocoa/WebContentReaderCocoa.mm
Expand Up @@ -135,8 +135,7 @@ static FragmentAndResources createFragment(Frame& frame, NSAttributedString *str

#if PLATFORM(MAC)
auto* view = frame.view();
auto* renderView = view ? view->renderView() : nullptr;
LocalDefaultSystemAppearance localAppearance(renderView ? renderView->useDarkAppearance() : false);
LocalDefaultSystemAppearance localAppearance(view ? view->useDarkAppearance() : false);
#endif

NSArray *subresources = nil;
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/inspector/InspectorOverlay.cpp
Expand Up @@ -184,7 +184,7 @@ void InspectorOverlay::paint(GraphicsContext& context)
FrameView* view = overlayPage()->mainFrame().view();

#if PLATFORM(MAC)
LocalDefaultSystemAppearance localAppearance(view->renderView()->useDarkAppearance());
LocalDefaultSystemAppearance localAppearance(view->useDarkAppearance());
#endif

view->updateLayoutAndStyleIfNeededRecursive();
Expand Down
36 changes: 34 additions & 2 deletions Source/WebCore/page/FrameView.cpp
Expand Up @@ -408,6 +408,8 @@ void FrameView::recalculateScrollbarOverlayStyle()
backgroundColor.getHSL(hue, saturation, lightness);
if (lightness <= .5 && backgroundColor.isVisible())
computedOverlayStyle = ScrollbarOverlayStyleLight;
else if (!backgroundColor.isVisible() && useDarkAppearance())
computedOverlayStyle = ScrollbarOverlayStyleLight;
}

if (oldOverlayStyle != computedOverlayStyle)
Expand Down Expand Up @@ -2046,9 +2048,39 @@ bool FrameView::shouldSetCursor() const
return page && page->isVisible() && page->focusController().isActive();
}

#if ENABLE(DARK_MODE_CSS)
RenderObject* FrameView::rendererForSupportedColorSchemes() const
{
auto* document = frame().document();
auto* documentElement = document ? document->documentElement() : nullptr;
auto* documentElementRenderer = documentElement ? documentElement->renderer() : nullptr;
if (documentElementRenderer && documentElementRenderer->style().hasExplicitlySetSupportedColorSchemes())
return documentElementRenderer;
auto* bodyElement = document ? document->bodyOrFrameset() : nullptr;
return bodyElement ? bodyElement->renderer() : nullptr;
}
#endif

bool FrameView::useDarkAppearance() const
{
return renderView()->useDarkAppearance();
#if ENABLE(DARK_MODE_CSS)
if (auto* renderer = rendererForSupportedColorSchemes())
return renderer->useDarkAppearance();
#endif
if (auto* document = frame().document())
return document->useDarkAppearance(nullptr);
return false;
}

OptionSet<StyleColor::Options> FrameView::styleColorOptions() const
{
#if ENABLE(DARK_MODE_CSS)
if (auto* renderer = rendererForSupportedColorSchemes())
return renderer->styleColorOptions();
#endif
if (auto* document = frame().document())
return document->styleColorOptions(nullptr);
return { };
}

bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
Expand Down Expand Up @@ -3916,7 +3948,7 @@ void FrameView::paintScrollCorner(GraphicsContext& context, const IntRect& corne
#if PLATFORM(MAC)
// If dark appearance is used or the overlay style is light (because of a dark page background), set the dark apppearance.
// Keep this in sync with ScrollAnimatorMac's effectiveAppearanceForScrollerImp:.
bool useDarkAppearance = renderView()->useDarkAppearance() || scrollbarOverlayStyle() == WebCore::ScrollbarOverlayStyleLight;
bool useDarkAppearance = this->useDarkAppearance() || scrollbarOverlayStyle() == WebCore::ScrollbarOverlayStyleLight;
LocalDefaultSystemAppearance localAppearance(useDarkAppearance);
#endif

Expand Down
11 changes: 10 additions & 1 deletion Source/WebCore/page/FrameView.h
Expand Up @@ -35,6 +35,7 @@
#include "PaintPhase.h"
#include "RenderPtr.h"
#include "ScrollView.h"
#include "StyleColor.h"
#include "TiledBacking.h"
#include <memory>
#include <wtf/Forward.h>
Expand Down Expand Up @@ -509,7 +510,8 @@ class FrameView final : public ScrollView {
bool isHandlingWheelEvent() const final;
bool shouldSetCursor() const;

bool useDarkAppearance() const final;
WEBCORE_EXPORT bool useDarkAppearance() const final;
OptionSet<StyleColor::Options> styleColorOptions() const;

// FIXME: Remove this method once plugin loading is decoupled from layout.
void flushAnyPendingPostLayoutTasks();
Expand Down Expand Up @@ -735,6 +737,10 @@ class FrameView final : public ScrollView {
void unobscuredContentSizeChanged() final;
#endif

#if ENABLE(DARK_MODE_CSS)
RenderObject* rendererForSupportedColorSchemes() const;
#endif

bool usesCompositedScrolling() const final;
bool usesAsyncScrolling() const final;
bool usesMockScrollAnimator() const final;
Expand Down Expand Up @@ -826,6 +832,9 @@ class FrameView final : public ScrollView {
bool m_firstLayoutCallbackPending;

bool m_isTransparent;
#if ENABLE(DARK_MODE_CSS)
bool m_usesDarkAppearance { false };
#endif
Color m_baseBackgroundColor;
IntSize m_lastViewportSize;
float m_lastZoomFactor;
Expand Down
6 changes: 5 additions & 1 deletion Source/WebCore/rendering/style/RenderStyle.cpp
Expand Up @@ -955,7 +955,11 @@ static bool rareInheritedDataChangeRequiresRepaint(const StyleRareInheritedData&
return first.userModify != second.userModify
|| first.userSelect != second.userSelect
|| first.appleColorFilter != second.appleColorFilter
|| first.imageRendering != second.imageRendering;
|| first.imageRendering != second.imageRendering
#if ENABLE(DARK_MODE_CSS)
|| first.supportedColorSchemes != second.supportedColorSchemes
#endif
;
}

bool RenderStyle::changeRequiresRepaint(const RenderStyle& other, OptionSet<StyleDifferenceContextSensitiveProperty>& changedContextSensitiveProperties) const
Expand Down
8 changes: 8 additions & 0 deletions Source/WebCore/rendering/style/RenderStyle.h
Expand Up @@ -638,6 +638,8 @@ class RenderStyle {

#if ENABLE(DARK_MODE_CSS)
StyleSupportedColorSchemes supportedColorSchemes() const { return m_rareInheritedData->supportedColorSchemes; }
void setHasExplicitlySetSupportedColorSchemes(bool v) { m_nonInheritedFlags.hasExplicitlySetSupportedColorSchemes = v; }
bool hasExplicitlySetSupportedColorSchemes() const { return m_nonInheritedFlags.hasExplicitlySetSupportedColorSchemes; };
#endif

TextOrientation textOrientation() const { return static_cast<TextOrientation>(m_rareInheritedData->textOrientation); }
Expand Down Expand Up @@ -1782,6 +1784,9 @@ class RenderStyle {
unsigned hasExplicitlySetDirection : 1;
unsigned hasExplicitlySetWritingMode : 1;
unsigned hasExplicitlySetTextAlign : 1;
#if ENABLE(DARK_MODE_CSS)
unsigned hasExplicitlySetSupportedColorSchemes : 1;
#endif
unsigned hasViewportUnits : 1;
unsigned hasExplicitlyInheritedProperties : 1; // Explicitly inherits a non-inherited property.
unsigned isUnique : 1; // Style cannot be shared.
Expand Down Expand Up @@ -1908,6 +1913,9 @@ inline bool RenderStyle::NonInheritedFlags::operator==(const NonInheritedFlags&
&& hasExplicitlySetDirection == other.hasExplicitlySetDirection
&& hasExplicitlySetWritingMode == other.hasExplicitlySetWritingMode
&& hasExplicitlySetTextAlign == other.hasExplicitlySetTextAlign
#if ENABLE(DARK_MODE_CSS)
&& hasExplicitlySetSupportedColorSchemes == other.hasExplicitlySetSupportedColorSchemes
#endif
&& hasViewportUnits == other.hasViewportUnits
&& hasExplicitlyInheritedProperties == other.hasExplicitlyInheritedProperties
&& isUnique == other.isUnique
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/svg/graphics/SVGImage.cpp
Expand Up @@ -325,7 +325,7 @@ ImageDrawResult SVGImage::draw(GraphicsContext& context, const FloatRect& dstRec
}

#if PLATFORM(MAC)
LocalDefaultSystemAppearance localAppearance(view->renderView()->useDarkAppearance());
LocalDefaultSystemAppearance localAppearance(view->useDarkAppearance());
#endif

view->paint(context, intersection(context.clipBounds(), enclosingIntRect(srcRect)));
Expand Down
30 changes: 30 additions & 0 deletions Source/WebCore/testing/Internals.cpp
Expand Up @@ -1673,6 +1673,16 @@ ExceptionOr<Ref<DOMRect>> Internals::visualViewportRect()
return DOMRect::create(frameView.visualViewportRect());
}

ExceptionOr<void> Internals::setViewIsTransparent(bool transparent)
{
Document* document = contextDocument();
if (!document || !document->view())
return Exception { InvalidAccessError };
Color backgroundColor = transparent ? Color::transparent : Color::white;
document->view()->updateBackgroundRecursively(backgroundColor, transparent);
return { };
}

ExceptionOr<void> Internals::setViewBaseBackgroundColor(const String& colorValue)
{
Document* document = contextDocument();
Expand Down Expand Up @@ -2491,6 +2501,26 @@ ExceptionOr<String> Internals::repaintRectsAsText() const
return document->frame()->trackedRepaintRectsAsText();
}

ExceptionOr<String> Internals::scrollbarOverlayStyle() const
{
Document* document = contextDocument();
if (!document || !document->view())
return Exception { InvalidAccessError };

auto& frameView = *document->view();
switch (frameView.scrollbarOverlayStyle()) {
case ScrollbarOverlayStyleDefault:
return "default"_str;
case ScrollbarOverlayStyleDark:
return "dark"_str;
case ScrollbarOverlayStyleLight:
return "light"_str;
}

ASSERT_NOT_REACHED();
return "unknown"_str;
}

ExceptionOr<String> Internals::scrollingStateTreeAsText() const
{
Document* document = contextDocument();
Expand Down

0 comments on commit f64f580

Please sign in to comment.