diff --git a/blink/renderer/core/frame/visual_viewport.cc b/blink/renderer/core/frame/visual_viewport.cc index 3760e68221f..19f4f404c0d 100644 --- a/blink/renderer/core/frame/visual_viewport.cc +++ b/blink/renderer/core/frame/visual_viewport.cc @@ -1163,4 +1163,9 @@ void VisualViewport::Paint(GraphicsContext& context) const { } } +void VisualViewport::UsedColorSchemeChanged() { + // The scrollbar overlay color theme depends on the used color scheme. + RecalculateScrollbarOverlayColorTheme(); +} + } // namespace blink diff --git a/blink/renderer/core/frame/visual_viewport.h b/blink/renderer/core/frame/visual_viewport.h index 21c2617b760..63afef552ce 100644 --- a/blink/renderer/core/frame/visual_viewport.h +++ b/blink/renderer/core/frame/visual_viewport.h @@ -279,6 +279,8 @@ class CORE_EXPORT VisualViewport : public GarbageCollected, void Paint(GraphicsContext&) const; + void UsedColorSchemeChanged(); + private: bool DidSetScaleOrLocation(float scale, bool is_pinch_gesture_active, diff --git a/blink/renderer/core/frame/visual_viewport_test.cc b/blink/renderer/core/frame/visual_viewport_test.cc index dadbb0d8169..e9f1814c366 100644 --- a/blink/renderer/core/frame/visual_viewport_test.cc +++ b/blink/renderer/core/frame/visual_viewport_test.cc @@ -2800,5 +2800,32 @@ TEST_P(VisualViewportTest, ScrollbarGeometryOnSizeChange) { EXPECT_EQ(gfx::Size(7, 113), vertical_scrollbar->bounds()); } +TEST_F(VisualViewportSimTest, PreferredOverlayScrollbarColorTheme) { + ColorSchemeHelper color_scheme_helper(*(WebView().GetPage())); + color_scheme_helper.SetPreferredColorScheme( + mojom::blink::PreferredColorScheme::kDark); + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete(R"HTML( + + + + )HTML"); + Compositor().BeginFrame(); + + const VisualViewport& visual_viewport = + WebView().GetPage()->GetVisualViewport(); + EXPECT_EQ(ScrollbarOverlayColorTheme::kScrollbarOverlayColorThemeLight, + visual_viewport.GetScrollbarOverlayColorTheme()); + + color_scheme_helper.SetPreferredColorScheme( + mojom::blink::PreferredColorScheme::kLight); + Compositor().BeginFrame(); + EXPECT_EQ(ScrollbarOverlayColorTheme::kScrollbarOverlayColorThemeDark, + visual_viewport.GetScrollbarOverlayColorTheme()); +} + } // namespace } // namespace blink diff --git a/blink/renderer/core/layout/layout_view.cc b/blink/renderer/core/layout/layout_view.cc index 8aa15ecb3be..39b50fc8ffe 100644 --- a/blink/renderer/core/layout/layout_view.cc +++ b/blink/renderer/core/layout/layout_view.cc @@ -35,6 +35,7 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/core/frame/visual_viewport.h" #include "third_party/blink/renderer/core/html/html_iframe_element.h" #include "third_party/blink/renderer/core/html/plugin_document.h" #include "third_party/blink/renderer/core/input/event_handler.h" @@ -890,6 +891,23 @@ void LayoutView::UpdateFromStyle() { SetHasBoxDecorationBackground(true); } +void LayoutView::StyleDidChange(StyleDifference diff, + const ComputedStyle* old_style) { + NOT_DESTROYED(); + LayoutBlockFlow::StyleDidChange(diff, old_style); + + LocalFrame& frame = GetFrameView()->GetFrame(); + if (frame.IsMainFrame()) { + // |VisualViewport::UsedColorScheme| depends on the LayoutView's used + // color scheme. + if (!old_style || + old_style->UsedColorScheme() != + frame.GetPage()->GetVisualViewport().UsedColorScheme()) { + frame.GetPage()->GetVisualViewport().UsedColorSchemeChanged(); + } + } +} + RecalcLayoutOverflowResult LayoutView::RecalcLayoutOverflow() { NOT_DESTROYED(); if (!NeedsLayoutOverflowRecalc()) diff --git a/blink/renderer/core/layout/layout_view.h b/blink/renderer/core/layout/layout_view.h index de147c83c8d..a1f530e657e 100644 --- a/blink/renderer/core/layout/layout_view.h +++ b/blink/renderer/core/layout/layout_view.h @@ -362,6 +362,9 @@ class CORE_EXPORT LayoutView : public LayoutBlockFlow { TrackedDescendantsMap& SvgTextDescendantsMap(); + protected: + void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override; + private: bool CanHaveChildren() const override; diff --git a/blink/renderer/core/page/page.cc b/blink/renderer/core/page/page.cc index 146e9a5b35d..f10c971767d 100644 --- a/blink/renderer/core/page/page.cc +++ b/blink/renderer/core/page/page.cc @@ -366,7 +366,7 @@ SpatialNavigationController& Page::GetSpatialNavigationController() { } void Page::PlatformColorsChanged() { - for (const Page* page : AllPages()) + for (const Page* page : AllPages()) { for (Frame* frame = page->MainFrame(); frame; frame = frame->Tree().TraverseNext()) { if (auto* local_frame = DynamicTo(frame)) { @@ -375,6 +375,7 @@ void Page::PlatformColorsChanged() { view->InvalidatePaintForViewAndDescendants(); } } + } } void Page::ColorSchemeChanged() { diff --git a/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/blink/renderer/core/paint/paint_layer_scrollable_area.cc index b9fd1b772b4..540fd36d009 100644 --- a/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/blink/renderer/core/paint/paint_layer_scrollable_area.cc @@ -1223,21 +1223,9 @@ void PaintLayerScrollableArea::UpdateAfterStyleChange( UpdateResizerStyle(old_style); - // Whenever background changes on the scrollable element, the scroll bar - // overlay style might need to be changed to have contrast against the - // background. - // Skip the need scrollbar check, because we dont know do we need a scrollbar - // when this method get called. - Color old_background; - if (old_style) { - old_background = - old_style->VisitedDependentColor(GetCSSPropertyBackgroundColor()); - } - Color new_background = GetLayoutBox()->StyleRef().VisitedDependentColor( - GetCSSPropertyBackgroundColor()); - - if (new_background != old_background) - RecalculateScrollbarOverlayColorTheme(new_background); + // The scrollbar overlay color theme depends on styles such as the background + // color and the used color scheme. + RecalculateScrollbarOverlayColorTheme(); if (NeedsScrollbarReconstruction()) { RemoveScrollbarsForReconstruction(); diff --git a/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc b/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc index 65a74e5615e..7670eebc854 100644 --- a/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc +++ b/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc @@ -18,6 +18,7 @@ #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/scroll/scroll_types.h" #include "third_party/blink/renderer/core/scroll/scrollbar_theme.h" +#include "third_party/blink/renderer/core/testing/color_scheme_helper.h" #include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h" using testing::_; @@ -397,6 +398,91 @@ TEST_P(PaintLayerScrollableAreaTest, OverlayScrollbarColorThemeUpdated) { black_layer->GetScrollableArea()->GetScrollbarOverlayColorTheme()); } +TEST_P(PaintLayerScrollableAreaTest, + RecalculatesScrollbarOverlayIfBackgroundChanges) { + SetBodyInnerHTML(R"HTML( + +
+
+
+ )HTML"); + PaintLayer* scroll_paint_layer = GetPaintLayerByElementId("scroller"); + EXPECT_EQ( + ScrollbarOverlayColorTheme::kScrollbarOverlayColorThemeDark, + scroll_paint_layer->GetScrollableArea()->GetScrollbarOverlayColorTheme()); + + GetElementById("scroller") + ->setAttribute(html_names::kStyleAttr, "background: rgb(34, 85, 51);"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_EQ( + ScrollbarOverlayColorTheme::kScrollbarOverlayColorThemeLight, + scroll_paint_layer->GetScrollableArea()->GetScrollbarOverlayColorTheme()); + + GetElementById("scroller") + ->setAttribute(html_names::kStyleAttr, "background: rgb(236, 143, 185);"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_EQ( + ScrollbarOverlayColorTheme::kScrollbarOverlayColorThemeDark, + scroll_paint_layer->GetScrollableArea()->GetScrollbarOverlayColorTheme()); +} + +// The scrollbar overlay color theme should follow the used color scheme when a +// background color is not available on the scroller itself. +TEST_P(PaintLayerScrollableAreaTest, PreferredOverlayScrollbarColorTheme) { + ColorSchemeHelper color_scheme_helper(GetDocument()); + color_scheme_helper.SetPreferredColorScheme( + mojom::blink::PreferredColorScheme::kDark); + SetBodyInnerHTML(R"HTML( + + +
+
+
+
+
+
+
+
+
+ )HTML"); + + PaintLayer* none_layer = GetPaintLayerByElementId("none"); + PaintLayer* white_layer = GetPaintLayerByElementId("white"); + PaintLayer* black_layer = GetPaintLayerByElementId("black"); + EXPECT_EQ(ScrollbarOverlayColorTheme::kScrollbarOverlayColorThemeLight, + none_layer->GetScrollableArea()->GetScrollbarOverlayColorTheme()); + EXPECT_EQ(ScrollbarOverlayColorTheme::kScrollbarOverlayColorThemeDark, + white_layer->GetScrollableArea()->GetScrollbarOverlayColorTheme()); + EXPECT_EQ(ScrollbarOverlayColorTheme::kScrollbarOverlayColorThemeLight, + black_layer->GetScrollableArea()->GetScrollbarOverlayColorTheme()); + + color_scheme_helper.SetPreferredColorScheme( + mojom::blink::PreferredColorScheme::kLight); + UpdateAllLifecyclePhasesForTest(); + EXPECT_EQ(ScrollbarOverlayColorTheme::kScrollbarOverlayColorThemeDark, + none_layer->GetScrollableArea()->GetScrollbarOverlayColorTheme()); + EXPECT_EQ(ScrollbarOverlayColorTheme::kScrollbarOverlayColorThemeDark, + white_layer->GetScrollableArea()->GetScrollbarOverlayColorTheme()); + EXPECT_EQ(ScrollbarOverlayColorTheme::kScrollbarOverlayColorThemeLight, + black_layer->GetScrollableArea()->GetScrollbarOverlayColorTheme()); +} + TEST_P(PaintLayerScrollableAreaTest, HideTooltipWhenScrollPositionChanges) { SetBodyInnerHTML(R"HTML(