mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 11:36:10 +00:00
LibWeb: Implement text-decoration: spelling-error and grammar-error
This commit is contained in:
parent
7668f91b60
commit
532c01c388
Notes:
github-actions[bot]
2025-02-28 16:35:04 +00:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/LadybirdBrowser/ladybird/commit/532c01c388c Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3724
9 changed files with 74 additions and 13 deletions
|
@ -1008,8 +1008,11 @@ Vector<TextDecorationLine> ComputedProperties::text_decoration_line() const
|
|||
return lines;
|
||||
}
|
||||
|
||||
if (value.is_keyword() && value.to_keyword() == Keyword::None)
|
||||
return {};
|
||||
if (value.is_keyword()) {
|
||||
if (value.to_keyword() == Keyword::None)
|
||||
return {};
|
||||
return { keyword_to_text_decoration_line(value.to_keyword()).release_value() };
|
||||
}
|
||||
|
||||
dbgln("FIXME: Unsupported value for text-decoration-line: {}", value.to_string(CSSStyleValue::SerializationMode::Normal));
|
||||
return {};
|
||||
|
|
|
@ -545,7 +545,9 @@
|
|||
"underline",
|
||||
"overline",
|
||||
"line-through",
|
||||
"blink"
|
||||
"blink",
|
||||
"spelling-error",
|
||||
"grammar-error"
|
||||
],
|
||||
"text-decoration-style": [
|
||||
"dashed",
|
||||
|
|
|
@ -190,6 +190,7 @@
|
|||
"fullscreen",
|
||||
"grab",
|
||||
"grabbing",
|
||||
"grammar-error",
|
||||
"graytext",
|
||||
"grid",
|
||||
"groove",
|
||||
|
@ -404,6 +405,7 @@
|
|||
"space-around",
|
||||
"space-between",
|
||||
"space-evenly",
|
||||
"spelling-error",
|
||||
"square",
|
||||
"square-button",
|
||||
"srgb",
|
||||
|
|
|
@ -3510,6 +3510,8 @@ RefPtr<CSSStyleValue> Parser::parse_text_decoration_line_value(TokenStream<Compo
|
|||
{
|
||||
StyleValueVector style_values;
|
||||
|
||||
bool includes_spelling_or_grammar_error_value = false;
|
||||
|
||||
while (tokens.has_next_token()) {
|
||||
auto maybe_value = parse_css_value_for_property(PropertyID::TextDecorationLine, tokens);
|
||||
if (!maybe_value)
|
||||
|
@ -3522,6 +3524,9 @@ RefPtr<CSSStyleValue> Parser::parse_text_decoration_line_value(TokenStream<Compo
|
|||
break;
|
||||
return value;
|
||||
}
|
||||
if (first_is_one_of(*maybe_line, TextDecorationLine::SpellingError, TextDecorationLine::GrammarError)) {
|
||||
includes_spelling_or_grammar_error_value = true;
|
||||
}
|
||||
if (style_values.contains_slow(value))
|
||||
break;
|
||||
style_values.append(move(value));
|
||||
|
@ -3534,6 +3539,13 @@ RefPtr<CSSStyleValue> Parser::parse_text_decoration_line_value(TokenStream<Compo
|
|||
if (style_values.is_empty())
|
||||
return nullptr;
|
||||
|
||||
// These can only appear on their own.
|
||||
if (style_values.size() > 1 && includes_spelling_or_grammar_error_value)
|
||||
return nullptr;
|
||||
|
||||
if (style_values.size() == 1)
|
||||
return *style_values.first();
|
||||
|
||||
quick_sort(style_values, [](auto& left, auto& right) {
|
||||
return *keyword_to_text_decoration_line(left->to_keyword()) < *keyword_to_text_decoration_line(right->to_keyword());
|
||||
});
|
||||
|
|
|
@ -682,6 +682,7 @@ void paint_text_decoration(PaintContext& context, TextPaintable const& paintable
|
|||
auto baseline = fragment.baseline();
|
||||
|
||||
auto line_color = paintable.computed_values().text_decoration_color();
|
||||
auto line_style = paintable.computed_values().text_decoration_style();
|
||||
auto const& text_paintable = static_cast<TextPaintable const&>(fragment.paintable());
|
||||
auto device_line_thickness = context.rounded_device_pixels(text_paintable.text_decoration_thickness());
|
||||
|
||||
|
@ -690,6 +691,24 @@ void paint_text_decoration(PaintContext& context, TextPaintable const& paintable
|
|||
DevicePixelPoint line_start_point {};
|
||||
DevicePixelPoint line_end_point {};
|
||||
|
||||
if (line == CSS::TextDecorationLine::SpellingError) {
|
||||
// https://drafts.csswg.org/css-text-decor-4/#valdef-text-decoration-line-spelling-error
|
||||
// This value indicates the type of text decoration used by the user agent to highlight spelling mistakes.
|
||||
// Its appearance is UA-defined, and may be platform-dependent. It is often rendered as a red wavy underline.
|
||||
line_color = Color::Red;
|
||||
device_line_thickness = context.rounded_device_pixels(1);
|
||||
line_style = CSS::TextDecorationStyle::Wavy;
|
||||
line = CSS::TextDecorationLine::Underline;
|
||||
} else if (line == CSS::TextDecorationLine::GrammarError) {
|
||||
// https://drafts.csswg.org/css-text-decor-4/#valdef-text-decoration-line-grammar-error
|
||||
// This value indicates the type of text decoration used by the user agent to highlight grammar mistakes.
|
||||
// Its appearance is UA defined, and may be platform-dependent. It is often rendered as a green wavy underline.
|
||||
line_color = Color::DarkGreen;
|
||||
device_line_thickness = context.rounded_device_pixels(1);
|
||||
line_style = CSS::TextDecorationStyle::Wavy;
|
||||
line = CSS::TextDecorationLine::Underline;
|
||||
}
|
||||
|
||||
switch (line) {
|
||||
case CSS::TextDecorationLine::None:
|
||||
return;
|
||||
|
@ -710,9 +729,13 @@ void paint_text_decoration(PaintContext& context, TextPaintable const& paintable
|
|||
case CSS::TextDecorationLine::Blink:
|
||||
// Conforming user agents may simply not blink the text
|
||||
return;
|
||||
case CSS::TextDecorationLine::SpellingError:
|
||||
case CSS::TextDecorationLine::GrammarError:
|
||||
// Handled above.
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
switch (paintable.computed_values().text_decoration_style()) {
|
||||
switch (line_style) {
|
||||
case CSS::TextDecorationStyle::Solid:
|
||||
painter.draw_line(line_start_point.to_type<int>(), line_end_point.to_type<int>(), line_color, device_line_thickness.value(), Gfx::LineStyle::Solid);
|
||||
break;
|
||||
|
@ -742,7 +765,24 @@ void paint_text_decoration(PaintContext& context, TextPaintable const& paintable
|
|||
painter.draw_line(line_start_point.to_type<int>(), line_end_point.to_type<int>(), line_color, device_line_thickness.value(), Gfx::LineStyle::Dotted);
|
||||
break;
|
||||
case CSS::TextDecorationStyle::Wavy:
|
||||
painter.draw_triangle_wave(line_start_point.to_type<int>(), line_end_point.to_type<int>(), line_color, device_line_thickness.value() + 1, device_line_thickness.value());
|
||||
auto amplitude = device_line_thickness.value() * 3;
|
||||
switch (line) {
|
||||
case CSS::TextDecorationLine::Underline:
|
||||
line_start_point.translate_by(0, device_line_thickness + context.rounded_device_pixels(1));
|
||||
line_end_point.translate_by(0, device_line_thickness + context.rounded_device_pixels(1));
|
||||
break;
|
||||
case CSS::TextDecorationLine::Overline:
|
||||
line_start_point.translate_by(0, -device_line_thickness - context.rounded_device_pixels(1));
|
||||
line_end_point.translate_by(0, -device_line_thickness - context.rounded_device_pixels(1));
|
||||
break;
|
||||
case CSS::TextDecorationLine::LineThrough:
|
||||
line_start_point.translate_by(0, -device_line_thickness / 2);
|
||||
line_end_point.translate_by(0, -device_line_thickness / 2);
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
painter.draw_triangle_wave(line_start_point.to_type<int>(), line_end_point.to_type<int>(), line_color, amplitude, device_line_thickness.value());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 22 KiB |
|
@ -8,6 +8,8 @@
|
|||
.strikethrough { text-decoration: line-through dotted green 5px; }
|
||||
.current-color { color: #8B4513; text-decoration: underline; }
|
||||
.overboard { text-decoration: double overline underline line-through magenta; }
|
||||
.spelling-error { text-decoration: spelling-error; }
|
||||
.grammar-error { text-decoration: grammar-error; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -17,5 +19,7 @@
|
|||
<p class="blink">FREE!</p>
|
||||
<p class="current-color">This underline should match the text color</p>
|
||||
<p class="overboard">This should have an underline, overline and line-through, all in glorious magenta.</p>
|
||||
<p class="spelling-error">This should look like a spelling error.</p>
|
||||
<p class="grammar-error">This should look like a grammar error.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -2,8 +2,7 @@ Harness status: OK
|
|||
|
||||
Found 18 tests
|
||||
|
||||
16 Pass
|
||||
2 Fail
|
||||
18 Pass
|
||||
Pass Property text-decoration-line value 'none'
|
||||
Pass Property text-decoration-line value 'underline'
|
||||
Pass Property text-decoration-line value 'overline'
|
||||
|
@ -20,5 +19,5 @@ Pass Property text-decoration-line value 'underline overline blink'
|
|||
Pass Property text-decoration-line value 'underline line-through blink'
|
||||
Pass Property text-decoration-line value 'overline line-through blink'
|
||||
Pass Property text-decoration-line value 'underline overline line-through blink'
|
||||
Fail Property text-decoration-line value 'spelling-error'
|
||||
Fail Property text-decoration-line value 'grammar-error'
|
||||
Pass Property text-decoration-line value 'spelling-error'
|
||||
Pass Property text-decoration-line value 'grammar-error'
|
|
@ -2,8 +2,7 @@ Harness status: OK
|
|||
|
||||
Found 67 tests
|
||||
|
||||
65 Pass
|
||||
2 Fail
|
||||
67 Pass
|
||||
Pass e.style['text-decoration-line'] = "none" should set the property value
|
||||
Pass e.style['text-decoration-line'] = "underline" should set the property value
|
||||
Pass e.style['text-decoration-line'] = "overline" should set the property value
|
||||
|
@ -69,5 +68,5 @@ Pass e.style['text-decoration-line'] = "blink overline underline line-through" s
|
|||
Pass e.style['text-decoration-line'] = "blink overline line-through underline" should set the property value
|
||||
Pass e.style['text-decoration-line'] = "blink line-through underline overline" should set the property value
|
||||
Pass e.style['text-decoration-line'] = "blink line-through overline underline" should set the property value
|
||||
Fail e.style['text-decoration-line'] = "spelling-error" should set the property value
|
||||
Fail e.style['text-decoration-line'] = "grammar-error" should set the property value
|
||||
Pass e.style['text-decoration-line'] = "spelling-error" should set the property value
|
||||
Pass e.style['text-decoration-line'] = "grammar-error" should set the property value
|
Loading…
Add table
Reference in a new issue