summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@gmail.com>2021-07-28 14:12:28 +0100
committerAndreas Kling <kling@serenityos.org>2021-07-31 00:18:11 +0200
commit919eb7c0aac138d1b35a8f2194a440a4a9a35d3f (patch)
treef66d8dce2a23563479674e64ff3d3464db9fa054 /Userland/Libraries/LibWeb
parent697bffa3bd988e94fe10659dfeaf604c48071d4b (diff)
downloadserenity-919eb7c0aac138d1b35a8f2194a440a4a9a35d3f.zip
LibWeb: Parse box-shadow property in new CSS Parser
Previous multi-value properties use a ValueListStyleValue, which then gets parsed into its sub-properties in the StyleResolver. However, that is not ideal, especially as it exposes StyleResolver to the inner workings of the Parser and Tokenizer, which it should not need to know about. The way `box-shadow` was implemented as a StyleValue subclass means that the parsing can happen inside the Parser instead, which seems like a better solution. Converting the other complicated cases (background, font, list-style) is on my todo list for later.
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp47
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.h1
2 files changed, 48 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
index 4641a5b7a0..4c5974c99a 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
@@ -1714,6 +1714,47 @@ RefPtr<StyleValue> Parser::parse_image_value(ParsingContext const& context, Styl
return {};
}
+RefPtr<StyleValue> Parser::parse_box_shadow_value(ParsingContext const& context, Vector<StyleComponentValueRule> const& component_values)
+{
+ // FIXME: Also support inset, spread-radius and multiple comma-seperated box-shadows
+ Length offset_x {};
+ Length offset_y {};
+ Length blur_radius {};
+ Color color {};
+
+ if (component_values.size() < 3 || component_values.size() > 4)
+ return nullptr;
+
+ auto maybe_x = parse_length(context, component_values[0]);
+ if (!maybe_x.has_value())
+ return nullptr;
+ offset_x = maybe_x.value();
+
+ auto maybe_y = parse_length(context, component_values[1]);
+ if (!maybe_y.has_value())
+ return nullptr;
+ offset_y = maybe_y.value();
+
+ if (component_values.size() == 3) {
+ auto parsed_color = parse_color(context, component_values[2]);
+ if (!parsed_color.has_value())
+ return nullptr;
+ color = parsed_color.value();
+ } else if (component_values.size() == 4) {
+ auto maybe_blur_radius = parse_length(context, component_values[2]);
+ if (!maybe_blur_radius.has_value())
+ return nullptr;
+ blur_radius = maybe_blur_radius.value();
+
+ auto parsed_color = parse_color(context, component_values[3]);
+ if (!parsed_color.has_value())
+ return nullptr;
+ color = parsed_color.value();
+ }
+
+ return BoxShadowStyleValue::create(offset_x, offset_y, blur_radius, color);
+}
+
RefPtr<StyleValue> Parser::parse_css_value(PropertyID property_id, TokenStream<StyleComponentValueRule>& tokens)
{
Vector<StyleComponentValueRule> component_values;
@@ -1735,6 +1776,12 @@ RefPtr<StyleValue> Parser::parse_css_value(PropertyID property_id, TokenStream<S
if (component_values.is_empty())
return {};
+ // Special-case property handling
+ if (property_id == PropertyID::BoxShadow) {
+ if (auto parsed_box_shadow = parse_box_shadow_value(m_context, component_values))
+ return parsed_box_shadow;
+ }
+
if (component_values.size() == 1)
return parse_css_value(m_context, property_id, component_values.first());
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
index cbbb236c08..18c3fde58e 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
@@ -176,6 +176,7 @@ private:
static RefPtr<StyleValue> parse_color_value(ParsingContext const&, StyleComponentValueRule const&);
static RefPtr<StyleValue> parse_string_value(ParsingContext const&, StyleComponentValueRule const&);
static RefPtr<StyleValue> parse_image_value(ParsingContext const&, StyleComponentValueRule const&);
+ static RefPtr<StyleValue> parse_box_shadow_value(ParsingContext const&, Vector<StyleComponentValueRule> const&);
template<typename T>
Optional<SelectorList> parse_a_selector_list(TokenStream<T>&);