summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@gmail.com>2021-07-22 14:56:44 +0100
committerAndreas Kling <kling@serenityos.org>2021-07-22 23:09:01 +0200
commit68193c365f777ced833b413b5d7a29b54074a73a (patch)
tree44c807627d49e452b6caf03e63f98dac2270e319
parent29b61123a487b5f855ee5f58756556dcec1f72ce (diff)
downloadserenity-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.html18
-rw-r--r--Base/res/html/misc/welcome.html1
-rw-r--r--Userland/Libraries/LibWeb/CSS/Identifiers.json1
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleResolver.cpp100
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;
}