diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2022-02-08 12:41:50 +0000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-02-08 17:45:51 +0100 |
commit | c547bed13badcee0a5953b3159a2dcd008879c71 (patch) | |
tree | 32094ad7955fbfccb2ed8ed7fb62a699867d1953 | |
parent | 1cd77fd1b478969b80aa967a7d5bfd8ebfebd0a9 (diff) | |
download | serenity-c547bed13badcee0a5953b3159a2dcd008879c71.zip |
LibWeb: Reorganize box-shadow parsing code
The pattern we've adopted for other multi-value properties is to run in
a loop like this, since that makes it easier to cater for values
appearing in different orders.
-rw-r--r-- | Base/res/html/misc/box-shadow.html | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp | 78 |
2 files changed, 51 insertions, 31 deletions
diff --git a/Base/res/html/misc/box-shadow.html b/Base/res/html/misc/box-shadow.html index c1fe9b4d12..5d550f0352 100644 --- a/Base/res/html/misc/box-shadow.html +++ b/Base/res/html/misc/box-shadow.html @@ -21,8 +21,8 @@ <p>box-shadow: 20px 10px magenta</p> </div> -<div class="box" style="box-shadow: -40px -20px magenta"> - <p>box-shadow: -40px -20px magenta</p> +<div class="box" style="box-shadow: magenta -40px -20px"> + <p>box-shadow: magenta -40px -20px</p> </div> <div class="box" style="box-shadow: 20px 10px rgba(255,0,255,0.5)"> diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index a577d3e000..91217269e4 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -3170,42 +3170,62 @@ RefPtr<StyleValue> Parser::parse_box_shadow_value(Vector<StyleComponentValueRule } // FIXME: Also support inset, spread-radius and multiple comma-separated box-shadows - Length offset_x {}; - Length offset_y {}; - Length blur_radius {}; - Color color {}; + Optional<Color> color; + Optional<Length> offset_x; + Optional<Length> offset_y; + Optional<Length> blur_radius; - if (component_values.size() < 3 || component_values.size() > 4) - return nullptr; + for (size_t i = 0; i < component_values.size(); ++i) { + if (auto maybe_color = parse_color(component_values[i]); maybe_color.has_value()) { + if (color.has_value()) + return nullptr; + color = maybe_color.release_value(); + continue; + } - auto maybe_x = parse_length(component_values[0]); - if (!maybe_x.has_value()) - return nullptr; - offset_x = maybe_x.value(); + if (auto maybe_offset_x = parse_length(component_values[i]); maybe_offset_x.has_value()) { + // horizontal offset + if (offset_x.has_value()) + return nullptr; + offset_x = maybe_offset_x.release_value(); - auto maybe_y = parse_length(component_values[1]); - if (!maybe_y.has_value()) - return nullptr; - offset_y = maybe_y.value(); + // vertical offset + if (++i >= component_values.size()) + return nullptr; + auto maybe_offset_y = parse_length(component_values[i]); + if (!maybe_offset_y.has_value()) + return nullptr; + offset_y = maybe_offset_y.release_value(); - if (component_values.size() == 3) { - auto parsed_color = parse_color(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(component_values[2]); - if (!maybe_blur_radius.has_value()) - return nullptr; - blur_radius = maybe_blur_radius.value(); + // blur radius (optional) + if (i + 1 >= component_values.size()) + break; + auto maybe_blur_radius = parse_length(component_values[i + 1]); + if (!maybe_blur_radius.has_value()) + continue; + ++i; + blur_radius = maybe_blur_radius.release_value(); - auto parsed_color = parse_color(component_values[3]); - if (!parsed_color.has_value()) - return nullptr; - color = parsed_color.value(); + continue; + } + + // Unrecognized value + return nullptr; } - return BoxShadowStyleValue::create(offset_x, offset_y, blur_radius, color); + // FIXME: If color is absent, default to `currentColor` + if (!color.has_value()) + color = Color::NamedColor::Black; + + // x/y offsets are required + if (!offset_x.has_value() || !offset_y.has_value()) + return nullptr; + + // Other lengths default to 0 + if (!blur_radius.has_value()) + blur_radius = Length::make_px(0); + + return BoxShadowStyleValue::create(offset_x.release_value(), offset_y.release_value(), blur_radius.release_value(), color.release_value()); } RefPtr<StyleValue> Parser::parse_flex_value(Vector<StyleComponentValueRule> const& component_values) |