mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 12:48:10 +00:00
LibWeb: Parse comma-separated lists for most background properties
We now can parse lists of values for these properties: - `background-attachment` - `background-clip` - `background-image` - `background-origin` - `background-position` - `background-repeat` - `background-size` This uses two new Parser methods: `parse_simple_comma_separated_value_list()` for the simple case when each value is parsed from a single token; and `parse_comma_separated_value_list()` which takes a lambda for when parsing each value is more involved. This also means that any unconsumed tokens at the end will make the parsing fail as it should, where previously we just ignored them.
This commit is contained in:
parent
50b15bdc1d
commit
8fd4678e79
2 changed files with 47 additions and 46 deletions
|
@ -2345,6 +2345,42 @@ RefPtr<StyleValue> Parser::parse_image_value(StyleComponentValueRule const& comp
|
|||
return {};
|
||||
}
|
||||
|
||||
template<typename ParseFunction>
|
||||
RefPtr<StyleValue> Parser::parse_comma_separated_value_list(Vector<StyleComponentValueRule> const& component_values, ParseFunction parse_one_value)
|
||||
{
|
||||
auto tokens = TokenStream { component_values };
|
||||
auto first = parse_one_value(tokens);
|
||||
if (!first || !tokens.has_next_token())
|
||||
return first;
|
||||
|
||||
NonnullRefPtrVector<StyleValue> values;
|
||||
values.append(first.release_nonnull());
|
||||
|
||||
while (tokens.has_next_token()) {
|
||||
if (!tokens.next_token().is(Token::Type::Comma))
|
||||
return {};
|
||||
|
||||
if (auto maybe_value = parse_one_value(tokens)) {
|
||||
values.append(maybe_value.release_nonnull());
|
||||
continue;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
return StyleValueList::create(move(values));
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_simple_comma_separated_value_list(Vector<StyleComponentValueRule> const& component_values)
|
||||
{
|
||||
return parse_comma_separated_value_list(component_values, [=, this](auto& tokens) -> RefPtr<StyleValue> {
|
||||
auto& token = tokens.next_token();
|
||||
if (auto value = parse_css_value(token); value && property_accepts_value(m_context.current_property_id(), *value))
|
||||
return value;
|
||||
tokens.reconsume_current_input_token();
|
||||
return nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_background_value(Vector<StyleComponentValueRule> const& component_values)
|
||||
{
|
||||
RefPtr<StyleValue> background_color;
|
||||
|
@ -2473,23 +2509,6 @@ RefPtr<StyleValue> Parser::parse_background_value(Vector<StyleComponentValueRule
|
|||
background_clip.release_nonnull());
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_background_image_value(Vector<StyleComponentValueRule> const& component_values)
|
||||
{
|
||||
if (component_values.size() == 1) {
|
||||
auto maybe_value = parse_css_value(component_values.first());
|
||||
if (!maybe_value)
|
||||
return nullptr;
|
||||
auto value = maybe_value.release_nonnull();
|
||||
if (property_accepts_value(PropertyID::BackgroundImage, *value))
|
||||
return value;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// FIXME: Handle multiple sets of comma-separated values.
|
||||
dbgln("CSS Parser does not yet support multiple comma-separated values for background-image.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_single_background_position_value(TokenStream<StyleComponentValueRule>& tokens)
|
||||
{
|
||||
// NOTE: This *looks* like it parses a <position>, but it doesn't. From the spec:
|
||||
|
@ -2652,13 +2671,6 @@ RefPtr<StyleValue> Parser::parse_single_background_position_value(TokenStream<St
|
|||
vertical->edge, vertical->offset);
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_background_position_value(Vector<StyleComponentValueRule> const& component_values)
|
||||
{
|
||||
auto tokens = TokenStream { component_values };
|
||||
// FIXME: Handle multiple sets of comma-separated values.
|
||||
return parse_single_background_position_value(tokens);
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_single_background_repeat_value(TokenStream<StyleComponentValueRule>& tokens)
|
||||
{
|
||||
auto start_position = tokens.position();
|
||||
|
@ -2714,13 +2726,6 @@ RefPtr<StyleValue> Parser::parse_single_background_repeat_value(TokenStream<Styl
|
|||
return BackgroundRepeatStyleValue::create(as_repeat(x_value->to_identifier()), as_repeat(y_value->to_identifier()));
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_background_repeat_value(Vector<StyleComponentValueRule> const& component_values)
|
||||
{
|
||||
auto tokens = TokenStream { component_values };
|
||||
// FIXME: Handle multiple sets of comma-separated values.
|
||||
return parse_single_background_repeat_value(tokens);
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_single_background_size_value(TokenStream<StyleComponentValueRule>& tokens)
|
||||
{
|
||||
auto start_position = tokens.position();
|
||||
|
@ -2749,13 +2754,6 @@ RefPtr<StyleValue> Parser::parse_single_background_size_value(TokenStream<StyleC
|
|||
return error();
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_background_size_value(Vector<StyleComponentValueRule> const& component_values)
|
||||
{
|
||||
auto tokens = TokenStream { component_values };
|
||||
// FIXME: Handle multiple sets of comma-separated values.
|
||||
return parse_single_background_size_value(tokens);
|
||||
}
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_border_value(Vector<StyleComponentValueRule> const& component_values)
|
||||
{
|
||||
if (component_values.size() > 3)
|
||||
|
@ -3472,20 +3470,23 @@ Result<NonnullRefPtr<StyleValue>, Parser::ParsingResult> Parser::parse_css_value
|
|||
if (auto parsed_value = parse_background_value(component_values))
|
||||
return parsed_value.release_nonnull();
|
||||
return ParsingResult::SyntaxError;
|
||||
case PropertyID::BackgroundAttachment:
|
||||
case PropertyID::BackgroundClip:
|
||||
case PropertyID::BackgroundImage:
|
||||
if (auto parsed_value = parse_background_image_value(component_values))
|
||||
case PropertyID::BackgroundOrigin:
|
||||
if (auto parsed_value = parse_simple_comma_separated_value_list(component_values))
|
||||
return parsed_value.release_nonnull();
|
||||
return ParsingResult::SyntaxError;
|
||||
case PropertyID::BackgroundPosition:
|
||||
if (auto parsed_value = parse_background_position_value(component_values))
|
||||
if (auto parsed_value = parse_comma_separated_value_list(component_values, [this](auto& tokens) { return parse_single_background_position_value(tokens); }))
|
||||
return parsed_value.release_nonnull();
|
||||
return ParsingResult::SyntaxError;
|
||||
case PropertyID::BackgroundRepeat:
|
||||
if (auto parsed_value = parse_background_repeat_value(component_values))
|
||||
if (auto parsed_value = parse_comma_separated_value_list(component_values, [this](auto& tokens) { return parse_single_background_repeat_value(tokens); }))
|
||||
return parsed_value.release_nonnull();
|
||||
return ParsingResult::SyntaxError;
|
||||
case PropertyID::BackgroundSize:
|
||||
if (auto parsed_value = parse_background_size_value(component_values))
|
||||
if (auto parsed_value = parse_comma_separated_value_list(component_values, [this](auto& tokens) { return parse_single_background_size_value(tokens); }))
|
||||
return parsed_value.release_nonnull();
|
||||
return ParsingResult::SyntaxError;
|
||||
case PropertyID::Border:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue