From b1efd62ce60d6f0b883f528a7df97e57fef30505 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Sun, 27 Jul 2025 19:40:17 +0200 Subject: [PATCH] LibWeb: Save more details about ASF presence in UnresolvedStyleValue In the upcoming changes we would have to know specifically whether `var()`, `attr()` or both are included in UnresolvedStyleValue. --- .../LibWeb/CSS/Parser/PropertyParsing.cpp | 16 +++++------ Libraries/LibWeb/CSS/Parser/Types.cpp | 28 +++++++++---------- Libraries/LibWeb/CSS/Parser/Types.h | 11 ++++++-- .../CSS/StyleValues/UnresolvedStyleValue.cpp | 22 +++++++-------- .../CSS/StyleValues/UnresolvedStyleValue.h | 8 +++--- 5 files changed, 44 insertions(+), 41 deletions(-) diff --git a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp index 6f780fc0738..e0d2769505c 100644 --- a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp @@ -393,7 +393,7 @@ Parser::ParseErrorOr> Parser::parse_css_value // FIXME: Stop removing whitespace here. It's less helpful than it seems. Vector component_values; - bool contains_arbitrary_substitution_function = false; + SubstitutionFunctionsPresence substitution_presence; bool const property_accepts_custom_ident = property_accepts_type(property_id, ValueType::CustomIdent); while (unprocessed_tokens.has_next_token()) { @@ -412,12 +412,10 @@ Parser::ParseErrorOr> Parser::parse_css_value return ParseError::IncludesIgnoredVendorPrefix; } - 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; - } + if (token.is_function()) + token.function().contains_arbitrary_substitution_function(substitution_presence); + else if (token.is_block()) + token.block().contains_arbitrary_substitution_function(substitution_presence); component_values.append(token); } @@ -428,8 +426,8 @@ Parser::ParseErrorOr> Parser::parse_css_value return parsed_value.release_nonnull(); } - if (property_id == PropertyID::Custom || contains_arbitrary_substitution_function) - return UnresolvedStyleValue::create(move(component_values), contains_arbitrary_substitution_function, original_source_text); + if (property_id == PropertyID::Custom || substitution_presence.has_any()) + return UnresolvedStyleValue::create(move(component_values), substitution_presence, original_source_text); if (component_values.is_empty()) return ParseError::SyntaxError; diff --git a/Libraries/LibWeb/CSS/Parser/Types.cpp b/Libraries/LibWeb/CSS/Parser/Types.cpp index fac61e738a2..4781461d02d 100644 --- a/Libraries/LibWeb/CSS/Parser/Types.cpp +++ b/Libraries/LibWeb/CSS/Parser/Types.cpp @@ -51,15 +51,14 @@ String SimpleBlock::original_source_text() const return builder.to_string_without_validation(); } -bool SimpleBlock::contains_arbitrary_substitution_function() const +void SimpleBlock::contains_arbitrary_substitution_function(SubstitutionFunctionsPresence& presence) 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; + if (component_value.is_function()) + component_value.function().contains_arbitrary_substitution_function(presence); + if (component_value.is_block()) + component_value.block().contains_arbitrary_substitution_function(presence); } - return false; } String Function::to_string() const @@ -86,17 +85,18 @@ String Function::original_source_text() const return builder.to_string_without_validation(); } -bool Function::contains_arbitrary_substitution_function() const +void Function::contains_arbitrary_substitution_function(SubstitutionFunctionsPresence& presence) const { - if (name.equals_ignoring_ascii_case("var"sv) || name.equals_ignoring_ascii_case("attr"sv)) - return true; + if (name.equals_ignoring_ascii_case("var"sv)) + presence.var = true; + else if (name.equals_ignoring_ascii_case("attr"sv)) + presence.attr = 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; + if (component_value.is_function()) + component_value.function().contains_arbitrary_substitution_function(presence); + if (component_value.is_block()) + component_value.block().contains_arbitrary_substitution_function(presence); } - return false; } void AtRule::for_each(AtRuleVisitor&& visit_at_rule, QualifiedRuleVisitor&& visit_qualified_rule, DeclarationVisitor&& visit_declaration) const diff --git a/Libraries/LibWeb/CSS/Parser/Types.h b/Libraries/LibWeb/CSS/Parser/Types.h index 874eaf2c88b..accb282a736 100644 --- a/Libraries/LibWeb/CSS/Parser/Types.h +++ b/Libraries/LibWeb/CSS/Parser/Types.h @@ -61,6 +61,13 @@ struct Declaration { String to_string() const; }; +struct SubstitutionFunctionsPresence { + bool attr { false }; + bool var { false }; + + bool has_any() const { return attr || var; } +}; + // https://drafts.csswg.org/css-syntax/#simple-block struct SimpleBlock { Token token; @@ -73,7 +80,7 @@ struct SimpleBlock { String to_string() const; String original_source_text() const; - bool contains_arbitrary_substitution_function() const; + void contains_arbitrary_substitution_function(SubstitutionFunctionsPresence&) const; }; // https://drafts.csswg.org/css-syntax/#function @@ -85,7 +92,7 @@ struct Function { String to_string() const; String original_source_text() const; - bool contains_arbitrary_substitution_function() const; + void contains_arbitrary_substitution_function(SubstitutionFunctionsPresence&) const; }; // https://drafts.csswg.org/css-variables/#guaranteed-invalid-value diff --git a/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.cpp index 18970b9aece..a07f8664d62 100644 --- a/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.cpp @@ -13,27 +13,25 @@ namespace Web::CSS { -ValueComparingNonnullRefPtr UnresolvedStyleValue::create(Vector&& values, Optional contains_arbitrary_substitution_function, Optional original_source_text) +ValueComparingNonnullRefPtr UnresolvedStyleValue::create(Vector&& values, Optional substitution_presence, Optional original_source_text) { - if (!contains_arbitrary_substitution_function.has_value()) { - bool found_asf = false; + if (!substitution_presence.has_value()) { + substitution_presence = Parser::SubstitutionFunctionsPresence {}; for (auto const& value : values) { - if ((value.is_function() && value.function().contains_arbitrary_substitution_function()) - || (value.is_block() && value.block().contains_arbitrary_substitution_function())) { - found_asf = true; - break; - } + if (value.is_function()) + value.function().contains_arbitrary_substitution_function(*substitution_presence); + if (value.is_block()) + value.block().contains_arbitrary_substitution_function(*substitution_presence); } - contains_arbitrary_substitution_function = found_asf; } - return adopt_ref(*new (nothrow) UnresolvedStyleValue(move(values), contains_arbitrary_substitution_function.value(), move(original_source_text))); + return adopt_ref(*new (nothrow) UnresolvedStyleValue(move(values), *substitution_presence, move(original_source_text))); } -UnresolvedStyleValue::UnresolvedStyleValue(Vector&& values, bool contains_arbitrary_substitution_function, Optional original_source_text) +UnresolvedStyleValue::UnresolvedStyleValue(Vector&& values, Parser::SubstitutionFunctionsPresence substitution_presence, Optional original_source_text) : CSSStyleValue(Type::Unresolved) , m_values(move(values)) - , m_contains_arbitrary_substitution_function(contains_arbitrary_substitution_function) + , m_substitution_functions_presence(substitution_presence) , m_original_source_text(move(original_source_text)) { } diff --git a/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.h index d5944b38dab..f69bf3730e9 100644 --- a/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.h @@ -17,22 +17,22 @@ namespace Web::CSS { class UnresolvedStyleValue final : public CSSStyleValue { public: - static ValueComparingNonnullRefPtr create(Vector&& values, Optional contains_arbitrary_substitution_function = {}, Optional original_source_text = {}); + static ValueComparingNonnullRefPtr create(Vector&& values, Optional = {}, Optional original_source_text = {}); virtual ~UnresolvedStyleValue() override = default; virtual String to_string(SerializationMode) const override; virtual Vector tokenize() const override { return m_values; } Vector const& values() const { return m_values; } - bool contains_arbitrary_substitution_function() const { return m_contains_arbitrary_substitution_function; } + bool contains_arbitrary_substitution_function() const { return m_substitution_functions_presence.has_any(); } virtual bool equals(CSSStyleValue const& other) const override; private: - UnresolvedStyleValue(Vector&& values, bool contains_arbitrary_substitution_function, Optional original_source_text); + UnresolvedStyleValue(Vector&& values, Parser::SubstitutionFunctionsPresence, Optional original_source_text); Vector m_values; - bool m_contains_arbitrary_substitution_function { false }; + Parser::SubstitutionFunctionsPresence m_substitution_functions_presence {}; Optional m_original_source_text; };