1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-19 03:45:08 +00:00

LibWeb: Parse multiple box-shadows :^)

Again, we don't yet render these (we render nothing) but this gets rid
of a decent amount of CSS spam on Discord.
This commit is contained in:
Sam Atkins 2022-02-08 14:07:06 +00:00 committed by Andreas Kling
parent e5b0369dfd
commit b51f428165
3 changed files with 46 additions and 21 deletions

View file

@ -37,5 +37,9 @@
<p>box-shadow: 20px 10px 5px magenta</p> <p>box-shadow: 20px 10px 5px magenta</p>
</div> </div>
<div class="box" style="box-shadow: 20px 10px 5px magenta, cyan -20px -10px 5px, yellow 10px -5px 5px 20px">
<p>box-shadow: 20px 10px 5px magenta, cyan -20px -10px 5px, yellow 10px -5px 5px 20px</p>
</div>
</body> </body>
</html> </html>

View file

@ -3169,7 +3169,19 @@ RefPtr<StyleValue> Parser::parse_box_shadow_value(Vector<StyleComponentValueRule
return ident; return ident;
} }
// FIXME: Also support multiple comma-separated box-shadows return parse_comma_separated_value_list(component_values, [this](auto& tokens) {
return parse_single_box_shadow_value(tokens);
});
}
RefPtr<StyleValue> Parser::parse_single_box_shadow_value(TokenStream<StyleComponentValueRule>& tokens)
{
auto start_position = tokens.position();
auto error = [&]() {
tokens.rewind_to_position(start_position);
return nullptr;
};
Optional<Color> color; Optional<Color> color;
Optional<Length> offset_x; Optional<Length> offset_x;
Optional<Length> offset_y; Optional<Length> offset_y;
@ -3177,58 +3189,66 @@ RefPtr<StyleValue> Parser::parse_box_shadow_value(Vector<StyleComponentValueRule
Optional<Length> spread_distance; Optional<Length> spread_distance;
Optional<BoxShadowPlacement> placement; Optional<BoxShadowPlacement> placement;
for (size_t i = 0; i < component_values.size(); ++i) { while (tokens.has_next_token()) {
if (auto maybe_color = parse_color(component_values[i]); maybe_color.has_value()) { auto& token = tokens.peek_token();
if (auto maybe_color = parse_color(token); maybe_color.has_value()) {
if (color.has_value()) if (color.has_value())
return nullptr; return error();
color = maybe_color.release_value(); color = maybe_color.release_value();
tokens.next_token();
continue; continue;
} }
if (auto maybe_offset_x = parse_length(component_values[i]); maybe_offset_x.has_value()) { if (auto maybe_offset_x = parse_length(token); maybe_offset_x.has_value()) {
// horizontal offset // horizontal offset
if (offset_x.has_value()) if (offset_x.has_value())
return nullptr; return error();
offset_x = maybe_offset_x.release_value(); offset_x = maybe_offset_x.release_value();
tokens.next_token();
// vertical offset // vertical offset
if (++i >= component_values.size()) if (!tokens.has_next_token())
return nullptr; return error();
auto maybe_offset_y = parse_length(component_values[i]); auto maybe_offset_y = parse_length(tokens.peek_token());
if (!maybe_offset_y.has_value()) if (!maybe_offset_y.has_value())
return nullptr; return error();
offset_y = maybe_offset_y.release_value(); offset_y = maybe_offset_y.release_value();
tokens.next_token();
// blur radius (optional) // blur radius (optional)
if (i + 1 >= component_values.size()) if (!tokens.has_next_token())
break; break;
auto maybe_blur_radius = parse_length(component_values[i + 1]); auto maybe_blur_radius = parse_length(tokens.peek_token());
if (!maybe_blur_radius.has_value()) if (!maybe_blur_radius.has_value())
continue; continue;
++i;
blur_radius = maybe_blur_radius.release_value(); blur_radius = maybe_blur_radius.release_value();
tokens.next_token();
// spread distance (optional) // spread distance (optional)
if (i + 1 >= component_values.size()) if (!tokens.has_next_token())
break; break;
auto maybe_spread_distance = parse_length(component_values[i + 1]); auto maybe_spread_distance = parse_length(tokens.peek_token());
if (!maybe_spread_distance.has_value()) if (!maybe_spread_distance.has_value())
continue; continue;
++i;
spread_distance = maybe_spread_distance.release_value(); spread_distance = maybe_spread_distance.release_value();
tokens.next_token();
continue; continue;
} }
if (component_values[i].is(Token::Type::Ident) && component_values[i].token().ident().equals_ignoring_case("inset"sv)) { if (token.is(Token::Type::Ident) && token.token().ident().equals_ignoring_case("inset"sv)) {
if (placement.has_value()) if (placement.has_value())
return nullptr; return error();
placement = BoxShadowPlacement::Inner; placement = BoxShadowPlacement::Inner;
tokens.next_token();
continue; continue;
} }
// Unrecognized value if (token.is(Token::Type::Comma))
return nullptr; break;
return error();
} }
// FIXME: If color is absent, default to `currentColor` // FIXME: If color is absent, default to `currentColor`
@ -3237,7 +3257,7 @@ RefPtr<StyleValue> Parser::parse_box_shadow_value(Vector<StyleComponentValueRule
// x/y offsets are required // x/y offsets are required
if (!offset_x.has_value() || !offset_y.has_value()) if (!offset_x.has_value() || !offset_y.has_value())
return nullptr; return error();
// Other lengths default to 0 // Other lengths default to 0
if (!blur_radius.has_value()) if (!blur_radius.has_value())

View file

@ -232,6 +232,7 @@ private:
RefPtr<StyleValue> parse_border_radius_value(Vector<StyleComponentValueRule> const&); RefPtr<StyleValue> parse_border_radius_value(Vector<StyleComponentValueRule> const&);
RefPtr<StyleValue> parse_border_radius_shorthand_value(Vector<StyleComponentValueRule> const&); RefPtr<StyleValue> parse_border_radius_shorthand_value(Vector<StyleComponentValueRule> const&);
RefPtr<StyleValue> parse_box_shadow_value(Vector<StyleComponentValueRule> const&); RefPtr<StyleValue> parse_box_shadow_value(Vector<StyleComponentValueRule> const&);
RefPtr<StyleValue> parse_single_box_shadow_value(TokenStream<StyleComponentValueRule>&);
RefPtr<StyleValue> parse_flex_value(Vector<StyleComponentValueRule> const&); RefPtr<StyleValue> parse_flex_value(Vector<StyleComponentValueRule> const&);
RefPtr<StyleValue> parse_flex_flow_value(Vector<StyleComponentValueRule> const&); RefPtr<StyleValue> parse_flex_flow_value(Vector<StyleComponentValueRule> const&);
RefPtr<StyleValue> parse_font_value(Vector<StyleComponentValueRule> const&); RefPtr<StyleValue> parse_font_value(Vector<StyleComponentValueRule> const&);