From 919eb7c0aac138d1b35a8f2194a440a4a9a35d3f Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Wed, 28 Jul 2021 14:12:28 +0100 Subject: [PATCH] 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. --- .../Libraries/LibWeb/CSS/Parser/Parser.cpp | 47 +++++++++++++++++++ Userland/Libraries/LibWeb/CSS/Parser/Parser.h | 1 + 2 files changed, 48 insertions(+) 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 Parser::parse_image_value(ParsingContext const& context, Styl return {}; } +RefPtr Parser::parse_box_shadow_value(ParsingContext const& context, Vector 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 Parser::parse_css_value(PropertyID property_id, TokenStream& tokens) { Vector component_values; @@ -1735,6 +1776,12 @@ RefPtr Parser::parse_css_value(PropertyID property_id, TokenStream parse_color_value(ParsingContext const&, StyleComponentValueRule const&); static RefPtr parse_string_value(ParsingContext const&, StyleComponentValueRule const&); static RefPtr parse_image_value(ParsingContext const&, StyleComponentValueRule const&); + static RefPtr parse_box_shadow_value(ParsingContext const&, Vector const&); template Optional parse_a_selector_list(TokenStream&);