1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 10:58:12 +00:00

LibWeb: Add basic support for the attr() CSS function

CSS Values and Units Module Level 5 defines attr as:
  `attr(<q-name> <attr-type>?, <declaration-value>?)`

This implementation does not contain support for the type argument,
effectively supporting `attr(<q-name>, <declaration-value>?)`
This commit is contained in:
Simon Wanner 2022-03-29 23:33:50 +02:00 committed by Andreas Kling
parent ba6ba67fa0
commit 6437f5da36
4 changed files with 56 additions and 19 deletions

View file

@ -4294,9 +4294,9 @@ RefPtr<StyleValue> Parser::parse_as_css_value(PropertyID property_id)
Result<NonnullRefPtr<StyleValue>, Parser::ParsingResult> Parser::parse_css_value(PropertyID property_id, TokenStream<StyleComponentValueRule>& tokens)
{
auto block_contains_var = [](StyleBlockRule const& block, auto&& recurse) -> bool {
auto block_contains_var_or_attr = [](StyleBlockRule const& block, auto&& recurse) -> bool {
for (auto const& token : block.values()) {
if (token.is_function() && token.function().name().equals_ignoring_case("var"sv))
if (token.is_function() && (token.function().name().equals_ignoring_case("var"sv) || token.function().name().equals_ignoring_case("attr"sv)))
return true;
if (token.is_block() && recurse(token.block(), recurse))
return true;
@ -4306,7 +4306,7 @@ Result<NonnullRefPtr<StyleValue>, Parser::ParsingResult> Parser::parse_css_value
m_context.set_current_property_id(property_id);
Vector<StyleComponentValueRule> component_values;
bool contains_var = false;
bool contains_var_or_attr = false;
while (tokens.has_next_token()) {
auto& token = tokens.next_token();
@ -4324,18 +4324,18 @@ Result<NonnullRefPtr<StyleValue>, Parser::ParsingResult> Parser::parse_css_value
return ParsingResult::IncludesIgnoredVendorPrefix;
}
if (!contains_var) {
if (token.is_function() && token.function().name().equals_ignoring_case("var"sv))
contains_var = true;
else if (token.is_block() && block_contains_var(token.block(), block_contains_var))
contains_var = true;
if (!contains_var_or_attr) {
if (token.is_function() && (token.function().name().equals_ignoring_case("var"sv) || token.function().name().equals_ignoring_case("attr"sv)))
contains_var_or_attr = true;
else if (token.is_block() && block_contains_var_or_attr(token.block(), block_contains_var_or_attr))
contains_var_or_attr = true;
}
component_values.append(token);
}
if (property_id == PropertyID::Custom || contains_var)
return { UnresolvedStyleValue::create(move(component_values), contains_var) };
if (property_id == PropertyID::Custom || contains_var_or_attr)
return { UnresolvedStyleValue::create(move(component_values), contains_var_or_attr) };
if (component_values.is_empty())
return ParsingResult::SyntaxError;