diff options
author | Sam Atkins <atkinssj@gmail.com> | 2021-07-22 14:56:44 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-07-22 23:09:01 +0200 |
commit | 68193c365f777ced833b413b5d7a29b54074a73a (patch) | |
tree | 44c807627d49e452b6caf03e63f98dac2270e319 | |
parent | 29b61123a487b5f855ee5f58756556dcec1f72ce (diff) | |
download | serenity-68193c365f777ced833b413b5d7a29b54074a73a.zip |
LibWeb: Resolve CSS text-decoration from value list
This detects and resolves these in the text-decoration property, in any
order:
- text-decoration-color
- text-decoration-line
- text-decoration-style
Only the solid underline renders, but all three sub-properties are
assigned correctly.
-rw-r--r-- | Base/res/html/misc/text-decoration.html | 18 | ||||
-rw-r--r-- | Base/res/html/misc/welcome.html | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Identifiers.json | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleResolver.cpp | 100 |
4 files changed, 110 insertions, 10 deletions
diff --git a/Base/res/html/misc/text-decoration.html b/Base/res/html/misc/text-decoration.html new file mode 100644 index 0000000000..3406e82c76 --- /dev/null +++ b/Base/res/html/misc/text-decoration.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> +<title>text-decoration test</title> +<style> +.overline { text-decoration: wavy blue overline; } +.underline { text-decoration: double red underline; } +.strikethrough { text-decoration: dotted green line-through; } +.blink { text-decoration: blink; } +</style> +</head> +<body> + <p class="overline">Overline</p> + <p class="underline">Underline</p> + <p class="strikethrough">Wombling</p> + <p class="blink">FREE!</p> +</body> +</html> diff --git a/Base/res/html/misc/welcome.html b/Base/res/html/misc/welcome.html index 2cb2a2f11c..8d102c83d7 100644 --- a/Base/res/html/misc/welcome.html +++ b/Base/res/html/misc/welcome.html @@ -48,6 +48,7 @@ <ul> <li><a href="justify-content.html">Flexbox justify-content</a></li> <li><a href="lists.html">Lists</a></li> + <li><a href="text-decoration.html">Text-decoration</a></li> <li><a href="fonts.html">Fonts</a></li> <li><a href="border-radius.html">Border-Radius</a></li> <li><a href="custom-properties.html">Custom Properties</a></li> diff --git a/Userland/Libraries/LibWeb/CSS/Identifiers.json b/Userland/Libraries/LibWeb/CSS/Identifiers.json index 2c95fe7b54..c5e6718335 100644 --- a/Userland/Libraries/LibWeb/CSS/Identifiers.json +++ b/Userland/Libraries/LibWeb/CSS/Identifiers.json @@ -185,6 +185,7 @@ "visible", "vertical-text", "wait", + "wavy", "wrap", "wrap-reverse", "w-resize", diff --git a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp index d0f3f42d4d..d9b84b1cb3 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp @@ -488,6 +488,40 @@ static inline bool is_list_style_type(StyleValue const& value) } } +static inline bool is_text_decoration_line(StyleValue const& value) +{ + if (value.is_builtin_or_dynamic()) + return true; + + switch (value.to_identifier()) { + case ValueID::None: + case ValueID::Underline: + case ValueID::Overline: + case ValueID::LineThrough: + case ValueID::Blink: + return true; + default: + return false; + } +} + +static inline bool is_text_decoration_style(StyleValue const& value) +{ + if (value.is_builtin_or_dynamic()) + return true; + + switch (value.to_identifier()) { + case ValueID::Solid: + case ValueID::Double: + case ValueID::Dotted: + case ValueID::Dashed: + case ValueID::Wavy: + return true; + default: + return false; + } +} + static void set_property_expanding_shorthands(StyleProperties& style, CSS::PropertyID property_id, StyleValue const& value, DOM::Document& document, bool is_internally_generated_pseudo_property = false) { CSS::DeprecatedParsingContext deprecated_context(document); @@ -499,17 +533,63 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope } if (property_id == CSS::PropertyID::TextDecoration) { - switch (value.to_identifier()) { - case CSS::ValueID::None: - case CSS::ValueID::Underline: - case CSS::ValueID::Overline: - case CSS::ValueID::LineThrough: - case CSS::ValueID::Blink: - set_property_expanding_shorthands(style, CSS::PropertyID::TextDecorationLine, value, document); - break; - default: - break; + if (value.is_color()) { + style.set_property(CSS::PropertyID::TextDecorationColor, value); + return; } + if (is_text_decoration_line(value)) { + style.set_property(CSS::PropertyID::TextDecorationLine, value); + return; + } + if (is_text_decoration_style(value)) { + style.set_property(CSS::PropertyID::TextDecorationStyle, value); + return; + } + + if (value.is_value_list()) { + auto& parts = static_cast<CSS::ValueListStyleValue const&>(value).values(); + if (!parts.is_empty() && parts.size() <= 3) { + RefPtr<StyleValue> color_value; + RefPtr<StyleValue> line_value; + RefPtr<StyleValue> style_value; + + for (auto& part : parts) { + auto value = Parser::parse_css_value(context, property_id, part); + if (!value) + return; + + if (value->is_color()) { + if (color_value) + return; + color_value = move(value); + continue; + } + if (is_text_decoration_line(*value)) { + if (line_value) + return; + line_value = move(value); + continue; + } + if (is_text_decoration_style(*value)) { + if (style_value) + return; + style_value = move(value); + continue; + } + + return; + } + + if (color_value) + style.set_property(CSS::PropertyID::TextDecorationColor, *color_value); + if (line_value) + style.set_property(CSS::PropertyID::TextDecorationLine, *line_value); + if (style_value) + style.set_property(CSS::PropertyID::TextDecorationStyle, *style_value); + } + return; + } + return; } |