LibWeb/CSS: Move functions for detecting var()/attr() into Token types

This makes them accessible outside of PropertyParsing.cpp (which will be
useful if/when descriptors can include them). I've also renamed them to
use the correct term: "arbitrary substitution function".
This commit is contained in:
Sam Atkins 2025-03-27 14:35:30 +00:00
parent 732a5cdc12
commit ef3a2bf907
Notes: github-actions[bot] 2025-03-28 09:16:07 +00:00
3 changed files with 35 additions and 34 deletions

View file

@ -379,38 +379,13 @@ Optional<Parser::PropertyAndValue> Parser::parse_css_value_for_properties(Readon
return OptionalNone {};
}
static bool block_contains_var_or_attr(SimpleBlock const& block);
static bool function_contains_var_or_attr(Function const& function)
{
if (function.name.equals_ignoring_ascii_case("var"sv) || function.name.equals_ignoring_ascii_case("attr"sv))
return true;
for (auto const& token : function.value) {
if (token.is_function() && function_contains_var_or_attr(token.function()))
return true;
if (token.is_block() && block_contains_var_or_attr(token.block()))
return true;
}
return false;
}
bool block_contains_var_or_attr(SimpleBlock const& block)
{
for (auto const& token : block.value) {
if (token.is_function() && function_contains_var_or_attr(token.function()))
return true;
if (token.is_block() && block_contains_var_or_attr(token.block()))
return true;
}
return false;
}
Parser::ParseErrorOr<NonnullRefPtr<CSSStyleValue>> Parser::parse_css_value(PropertyID property_id, TokenStream<ComponentValue>& unprocessed_tokens, Optional<String> original_source_text)
{
auto context_guard = push_temporary_value_parsing_context(property_id);
// FIXME: Stop removing whitespace here. It's less helpful than it seems.
Vector<ComponentValue> component_values;
bool contains_var_or_attr = false;
bool contains_arbitrary_substitution_function = false;
bool const property_accepts_custom_ident = property_accepts_type(property_id, ValueType::CustomIdent);
while (unprocessed_tokens.has_next_token()) {
@ -429,18 +404,18 @@ Parser::ParseErrorOr<NonnullRefPtr<CSSStyleValue>> Parser::parse_css_value(Prope
return ParseError::IncludesIgnoredVendorPrefix;
}
if (!contains_var_or_attr) {
if (token.is_function() && function_contains_var_or_attr(token.function()))
contains_var_or_attr = true;
else if (token.is_block() && block_contains_var_or_attr(token.block()))
contains_var_or_attr = true;
if (!contains_arbitrary_substitution_function) {
if (token.is_function() && token.function().contains_arbitrary_substitution_function())
contains_arbitrary_substitution_function = true;
else if (token.is_block() && token.block().contains_arbitrary_substitution_function())
contains_arbitrary_substitution_function = true;
}
component_values.append(token);
}
if (property_id == PropertyID::Custom || contains_var_or_attr)
return UnresolvedStyleValue::create(move(component_values), contains_var_or_attr, original_source_text);
if (property_id == PropertyID::Custom || contains_arbitrary_substitution_function)
return UnresolvedStyleValue::create(move(component_values), contains_arbitrary_substitution_function, original_source_text);
if (component_values.is_empty())
return ParseError::SyntaxError;

View file

@ -51,6 +51,17 @@ String SimpleBlock::original_source_text() const
return builder.to_string_without_validation();
}
bool SimpleBlock::contains_arbitrary_substitution_function() const
{
for (auto const& component_value : value) {
if (component_value.is_function() && component_value.function().contains_arbitrary_substitution_function())
return true;
if (component_value.is_block() && component_value.block().contains_arbitrary_substitution_function())
return true;
}
return false;
}
String Function::to_string() const
{
StringBuilder builder;
@ -75,6 +86,19 @@ String Function::original_source_text() const
return builder.to_string_without_validation();
}
bool Function::contains_arbitrary_substitution_function() const
{
if (name.equals_ignoring_ascii_case("var"sv) || name.equals_ignoring_ascii_case("attr"sv))
return true;
for (auto const& component_value : value) {
if (component_value.is_function() && component_value.function().contains_arbitrary_substitution_function())
return true;
if (component_value.is_block() && component_value.block().contains_arbitrary_substitution_function())
return true;
}
return false;
}
void AtRule::for_each(AtRuleVisitor&& visit_at_rule, QualifiedRuleVisitor&& visit_qualified_rule, DeclarationVisitor&& visit_declaration) const
{
for (auto const& child : child_rules_and_lists_of_declarations) {

View file

@ -72,6 +72,7 @@ struct SimpleBlock {
String to_string() const;
String original_source_text() const;
bool contains_arbitrary_substitution_function() const;
};
// https://drafts.csswg.org/css-syntax/#function
@ -83,6 +84,7 @@ struct Function {
String to_string() const;
String original_source_text() const;
bool contains_arbitrary_substitution_function() const;
};
}