summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@serenityos.org>2022-02-08 12:41:50 +0000
committerAndreas Kling <kling@serenityos.org>2022-02-08 17:45:51 +0100
commitc547bed13badcee0a5953b3159a2dcd008879c71 (patch)
tree32094ad7955fbfccb2ed8ed7fb62a699867d1953
parent1cd77fd1b478969b80aa967a7d5bfd8ebfebd0a9 (diff)
downloadserenity-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.html4
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp78
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)