LibWeb: Draw selected text with its own color

Other browsers such as Chrome and Firefox retain the text's color when
the text is part of a selection, so let's mimic them.
This commit is contained in:
Jelle Raaijmakers 2025-08-20 12:26:37 +02:00 committed by Jelle Raaijmakers
commit 1a52fcd6ad
Notes: github-actions[bot] 2025-08-20 12:31:28 +00:00
8 changed files with 27 additions and 11 deletions

View file

@ -934,6 +934,10 @@ void paint_text_fragment(DisplayListRecordingContext& context, TextPaintable con
if (!glyph_run)
return;
auto selection_rect = context.enclosing_device_rect(fragment.selection_rect()).to_type<int>();
if (!selection_rect.is_empty())
painter.fill_rect(selection_rect, CSS::SystemColor::highlight(paintable.computed_values().color_scheme()));
auto scale = context.device_pixels_per_css_pixel();
auto baseline_start = Gfx::FloatPoint {
fragment_absolute_rect.x().to_float(),
@ -941,14 +945,6 @@ void paint_text_fragment(DisplayListRecordingContext& context, TextPaintable con
} * scale;
painter.draw_glyph_run(baseline_start, *glyph_run, paintable.computed_values().webkit_text_fill_color(), fragment_enclosing_device_rect, scale, fragment.orientation());
auto selection_rect = context.enclosing_device_rect(fragment.selection_rect()).to_type<int>();
if (!selection_rect.is_empty()) {
painter.fill_rect(selection_rect, CSS::SystemColor::highlight(paintable.computed_values().color_scheme()));
DisplayListRecorderStateSaver saver(painter);
painter.add_clip_rect(selection_rect);
painter.draw_glyph_run(baseline_start, *glyph_run, CSS::SystemColor::highlight_text(paintable.computed_values().color_scheme()), fragment_enclosing_device_rect, scale, fragment.orientation());
}
paint_text_decoration(context, paintable, fragment);
paint_cursor_if_needed(context, paintable, fragment);
}

View file

@ -0,0 +1,7 @@
<!DOCTYPE html>
<style>
* {
margin: 0;
}
</style>
<img src="../images/selection-text-color-ref.png">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View file

@ -1,6 +1,6 @@
<!DOCTYPE html>
<link rel="match" href="../expected/selection-start-in-end-node-ref.html" />
<meta name="fuzzy" content="maxDifference=0-1;totalPixels=0-230">
<meta name="fuzzy" content="maxDifference=0-1;totalPixels=0-268">
<!-- The space after the start node, as well as "NOT SELECTED" must not be selected. -->
<span id="end">End Node <span id="start">Start Node</span> </span>NOT SELECTED
<script>

View file

@ -1,6 +1,6 @@
<!DOCTYPE html>
<link rel="match" href="../expected/selection-start-in-end-node-ref.html" />
<meta name="fuzzy" content="maxDifference=0-1;totalPixels=0-230">
<meta name="fuzzy" content="maxDifference=0-1;totalPixels=0-268">
<!-- here the end node contains the start node, as well as some further selected content and some non-selected content. -->
<span id="end">End Node <span id="start">Start</span> <span>Node</span> </span>NOT SELECTED
<script>

View file

@ -1,6 +1,6 @@
<!DOCTYPE html>
<link rel="match" href="../expected/selection-start-in-end-node-ref.html" />
<meta name="fuzzy" content="maxDifference=0-1;totalPixels=0-230">
<meta name="fuzzy" content="maxDifference=0-1;totalPixels=0-268">
<!-- The text after the end node must not be selected. -->
<span id="end">End Node <span id="start">Start Node</span></span> NOT SELECTED
<script>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<link rel="match" href="../expected/selection-text-color-ref.html" />
<meta name="fuzzy" content="maxDifference=0-1;totalPixels=0-345">
<style>
span {
color: red;
}
</style>
<div contenteditable>lorem ipsum <span>sit dolor amet</span></div>
<script>
const divElm = document.querySelector('div[contenteditable]');
getSelection().setBaseAndExtent(divElm.childNodes[0], 6, divElm.childNodes[1].childNodes[0], 9);
</script>