diff options
author | Sam Atkins <atkinssj@gmail.com> | 2021-07-28 14:12:28 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-07-31 00:18:11 +0200 |
commit | 919eb7c0aac138d1b35a8f2194a440a4a9a35d3f (patch) | |
tree | f66d8dce2a23563479674e64ff3d3464db9fa054 /Userland/Libraries/LibWeb | |
parent | 697bffa3bd988e94fe10659dfeaf604c48071d4b (diff) | |
download | serenity-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.cpp | 47 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 1 |
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>&); |