Skip to content

Commit bde3158

Browse files
committed
LibWeb: Use themed text selection colors
Resolve default selection backgrounds from the page palette instead of a hardcoded blue color when selection is painted in the palette's color scheme or in a normal color-scheme context without document-selected supported schemes. Tint opaque selection backgrounds before painting. This keeps selected images visible through the selection overlay. For explicit mixed-scheme documents and schemes selected by document metadata, keep default selection colors tied to the selected element's color-scheme. Use the platform SelectionText role for default selected text when using the platform selection color. Authored ::selection colors still take precedence, and ordinary CSS system colors remain resolved from the element color-scheme. Update selection baselines for the themed colors and add coverage for custom image selection backgrounds, default link selection, HighlightText color-scheme resolution, mixed-scheme default selection, document-selected schemes, forced preferred color schemes, and resetting forced preferred color schemes back to auto.
1 parent 1677cea commit bde3158

33 files changed

Lines changed: 317 additions & 24 deletions

Libraries/LibWeb/CSS/SystemColor.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,39 @@ Color gray_text(PreferredColorScheme)
8787
return Color(128, 128, 128);
8888
}
8989

90+
Color transform_selection_background_color(Color color)
91+
{
92+
if (color.alpha() < 255)
93+
return color;
94+
95+
constexpr int start_alpha = 153; // 60%
96+
constexpr int end_alpha = 204; // 80%
97+
constexpr int alpha_increment = 17;
98+
99+
auto blend_component = [](u8 component, int alpha) {
100+
auto white_blend = 255 - alpha;
101+
return (static_cast<int>(component) - white_blend) * 255 / alpha;
102+
};
103+
104+
Color result;
105+
for (int alpha = start_alpha; alpha <= end_alpha; alpha += alpha_increment) {
106+
auto red = blend_component(color.red(), alpha);
107+
auto green = blend_component(color.green(), alpha);
108+
auto blue = blend_component(color.blue(), alpha);
109+
110+
result = Color(
111+
static_cast<u8>(clamp(red, 0, 255)),
112+
static_cast<u8>(clamp(green, 0, 255)),
113+
static_cast<u8>(clamp(blue, 0, 255)),
114+
static_cast<u8>(alpha));
115+
116+
if (red >= 0 && green >= 0 && blue >= 0)
117+
break;
118+
}
119+
120+
return result;
121+
}
122+
90123
Color highlight(PreferredColorScheme)
91124
{
92125
return Color(61, 174, 233, 128);

Libraries/LibWeb/CSS/SystemColor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Color canvas_text(PreferredColorScheme);
2424
Color field(PreferredColorScheme);
2525
Color field_text(PreferredColorScheme);
2626
Color gray_text(PreferredColorScheme);
27+
Color transform_selection_background_color(Color);
2728
WEB_API Color highlight(PreferredColorScheme);
2829
WEB_API Color highlight_text(PreferredColorScheme);
2930
Color link_text(PreferredColorScheme);

Libraries/LibWeb/Painting/Paintable.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
#include <LibWeb/CSS/ComputedProperties.h>
10+
#include <LibWeb/CSS/StyleValues/ColorSchemeStyleValue.h>
1011
#include <LibWeb/CSS/SystemColor.h>
1112
#include <LibWeb/DOM/Document.h>
1213
#include <LibWeb/DOM/Element.h>
@@ -15,6 +16,7 @@
1516
#include <LibWeb/Layout/Node.h>
1617
#include <LibWeb/Layout/TextNode.h>
1718
#include <LibWeb/Layout/TextOffsetMapping.h>
19+
#include <LibWeb/Page/Page.h>
1820
#include <LibWeb/Painting/DisplayListRecorder.h>
1921
#include <LibWeb/Painting/DisplayListRecordingContext.h>
2022
#include <LibWeb/Painting/Paintable.h>
@@ -281,19 +283,40 @@ Painting::BorderRadiiData normalize_border_radii_data(Layout::Node const& node,
281283
// fill-color, stroke-width, and CSS custom properties.
282284
Paintable::SelectionStyle Paintable::selection_style() const
283285
{
284-
auto color_scheme = computed_values().color_scheme();
285-
SelectionStyle default_style { CSS::SystemColor::highlight(color_scheme), {}, {}, {} };
286+
auto default_style_for_color_scheme = [&](CSS::PreferredColorScheme color_scheme, bool use_palette_for_normal_color_scheme = true) {
287+
auto palette = document().page().palette();
288+
auto palette_color_scheme = palette.is_dark() ? CSS::PreferredColorScheme::Dark : CSS::PreferredColorScheme::Light;
289+
if (color_scheme == palette_color_scheme || use_palette_for_normal_color_scheme) {
290+
return SelectionStyle {
291+
CSS::SystemColor::transform_selection_background_color(palette.selection()),
292+
palette.selection_text(),
293+
{},
294+
{},
295+
};
296+
}
297+
298+
return SelectionStyle {
299+
CSS::SystemColor::transform_selection_background_color(CSS::SystemColor::highlight(color_scheme)),
300+
CSS::SystemColor::highlight_text(color_scheme),
301+
{},
302+
{},
303+
};
304+
};
286305

287306
// For text nodes, check the parent element since text nodes don't have computed properties.
288307
auto node = dom_node();
289308
if (!node)
290-
return default_style;
309+
return default_style_for_color_scheme(computed_values().color_scheme());
291310

292311
DOM::Element const* element = as_if<DOM::Element>(*node);
293312
if (!element)
294313
element = node->parent_element();
295314
if (!element)
296-
return default_style;
315+
return default_style_for_color_scheme(computed_values().color_scheme());
316+
317+
auto color_scheme_is_normal = element->computed_properties()->property(CSS::PropertyID::ColorScheme).as_color_scheme().schemes().is_empty();
318+
auto use_palette_for_normal_color_scheme = color_scheme_is_normal && !document().supported_color_schemes().has_value();
319+
auto default_style = default_style_for_color_scheme(computed_values().color_scheme(), use_palette_for_normal_color_scheme);
297320

298321
auto style_from_element = [&](DOM::Element const& element) -> Optional<SelectionStyle> {
299322
auto element_layout_node = element.layout_node();

Tests/LibWeb/Ref/expected/selection-background-ref.html

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,10 @@
99
.selected {
1010
background-color: red;
1111
}
12-
.selected-default {
13-
background: Highlight;
14-
}
1512
</style>
1613

1714
<div>
18-
<p><span>P</span><span class="selected-default">ar</span><span class="selected">tial start</span></p>
15+
<p><span>P</span><span class="selected">artial start</span></p>
1916
<p><span class="selected">Full selection</span></p>
20-
<p><span class="selected">Partial </span><span class="selected-default">en</span><span>d</span></p>
17+
<p><span class="selected">Partial en</span><span>d</span></p>
2118
</div>

Tests/LibWeb/Ref/expected/selection-color-ref.html

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,14 @@
99
.selected {
1010
color: green;
1111
}
12-
.selected-default {
13-
background: Highlight;
14-
}
1512
.transparent-selected {
1613
color: transparent;
1714
}
1815
</style>
1916

2017
<div>
21-
<p><span>P</span><span class="selected-default">ar</span><span class="selected">tial start</span></p>
18+
<p><span>P</span><span class="selected">artial start</span></p>
2219
<p><span class="selected">Full selection</span></p>
23-
<p><span class="selected">Partial </span><span class="selected-default">end</span></p>
20+
<p><span class="selected">Partial end</span></p>
2421
<p class="transparent-selected">Invisible when selected</p>
2522
</div>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<style>
3+
p {
4+
font-size: 20px;
5+
line-height: 1.5;
6+
margin: 10px 0;
7+
}
8+
.selected-light {
9+
background: rgba(101, 2, 0, 0.8);
10+
color: white;
11+
}
12+
.selected-dark {
13+
background: rgba(61, 174, 233, 0.5);
14+
color: rgb(20, 20, 20);
15+
}
16+
</style>
17+
18+
<p><span class="selected-light">Light scheme</span><br><span class="selected-dark">Dark scheme</span></p>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<style>
3+
p {
4+
font-size: 20px;
5+
line-height: 1.5;
6+
margin: 10px 0;
7+
}
8+
.selected {
9+
background: rgba(61, 174, 233, 0.5);
10+
color: rgb(20, 20, 20);
11+
}
12+
</style>
13+
14+
<p><span class="selected">Forced dark scheme</span></p>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<style>
3+
td {
4+
font-size: 20px;
5+
line-height: 1.5;
6+
}
7+
.selected {
8+
background: rgba(101, 2, 0, 0.8);
9+
color: white;
10+
}
11+
</style>
12+
13+
<table><tr><td><span class="selected">Default link selection</span></td></tr></table>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!DOCTYPE html>
2+
<meta name="color-scheme" content="dark">
3+
<style>
4+
p {
5+
font-size: 20px;
6+
line-height: 1.5;
7+
margin: 10px 0;
8+
}
9+
.selected {
10+
background: rgba(61, 174, 233, 0.5);
11+
color: rgb(20, 20, 20);
12+
}
13+
</style>
14+
15+
<p><span class="selected">Meta dark scheme</span></p>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<style>
3+
p {
4+
font-size: 20px;
5+
line-height: 1.5;
6+
margin: 10px 0;
7+
}
8+
.selected {
9+
background: rgba(101, 2, 0, 0.8);
10+
color: white;
11+
}
12+
</style>
13+
14+
<p><span class="selected">Normal color scheme</span></p>

0 commit comments

Comments
 (0)