From d18b0c07caf14b831e96a5bfe023fe9b887f6564 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Thu, 10 Jul 2025 14:19:24 +0100 Subject: [PATCH] LibWeb/CSS: Make UnresolvedStyleValue figure out if it contains ASFs UnresolvedStyleValue::create() has one user where we know if there are any arbitrary substitution functions in the list of CVs, and two users where we don't know and just hope there aren't any. I'm about to add another user that also doesn't know, and so it seems worth just making UnresolvedStyleValue::create() do that work instead. We keep the parameter, now Optional<>, so that we save some redundant work in that one place where we do already know. --- .../LibWeb/CSS/Parser/DescriptorParsing.cpp | 2 +- Libraries/LibWeb/CSS/Parser/ValueParsing.cpp | 2 +- .../CSS/StyleValues/UnresolvedStyleValue.cpp | 27 ++++++++++++++++++- .../CSS/StyleValues/UnresolvedStyleValue.h | 13 ++------- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/Libraries/LibWeb/CSS/Parser/DescriptorParsing.cpp b/Libraries/LibWeb/CSS/Parser/DescriptorParsing.cpp index 49a4cd57e0a..0674662dc67 100644 --- a/Libraries/LibWeb/CSS/Parser/DescriptorParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/DescriptorParsing.cpp @@ -117,7 +117,7 @@ Parser::ParseErrorOr> Parser::parse_descripto // `component_values` already has what we want. Just skip through its tokens so code below knows we consumed them. while (tokens.has_next_token()) tokens.discard_a_token(); - return UnresolvedStyleValue::create(move(component_values), false, {}); + return UnresolvedStyleValue::create(move(component_values)); } case DescriptorMetadata::ValueType::PageSize: { // https://drafts.csswg.org/css-page-3/#page-size-prop diff --git a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp index a27f6018b03..2ddb82eef62 100644 --- a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp @@ -4314,7 +4314,7 @@ NonnullRefPtr Parser::resolve_unresolved_style_value(DOM::A // NB: Custom properties have no grammar as such, so we skip this step for them. // FIXME: Parse according to @property syntax once we support that. if (property_id == PropertyID::Custom) - return UnresolvedStyleValue::create(move(result), false, {}); + return UnresolvedStyleValue::create(move(result)); auto expanded_value_tokens = TokenStream { result }; auto parsed_value = parse_css_value(property_id, expanded_value_tokens); diff --git a/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.cpp index 062cc6e3d61..18970b9aece 100644 --- a/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Tobias Christiansen - * Copyright (c) 2021-2024, Sam Atkins + * Copyright (c) 2021-2025, Sam Atkins * Copyright (c) 2022-2023, MacDue * * SPDX-License-Identifier: BSD-2-Clause @@ -13,6 +13,31 @@ namespace Web::CSS { +ValueComparingNonnullRefPtr UnresolvedStyleValue::create(Vector&& values, Optional contains_arbitrary_substitution_function, Optional original_source_text) +{ + if (!contains_arbitrary_substitution_function.has_value()) { + bool found_asf = false; + 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; + } + } + contains_arbitrary_substitution_function = found_asf; + } + + return adopt_ref(*new (nothrow) UnresolvedStyleValue(move(values), contains_arbitrary_substitution_function.value(), move(original_source_text))); +} + +UnresolvedStyleValue::UnresolvedStyleValue(Vector&& values, bool contains_arbitrary_substitution_function, Optional original_source_text) + : CSSStyleValue(Type::Unresolved) + , m_values(move(values)) + , m_contains_arbitrary_substitution_function(contains_arbitrary_substitution_function) + , m_original_source_text(move(original_source_text)) +{ +} + String UnresolvedStyleValue::to_string(SerializationMode) const { if (m_original_source_text.has_value()) diff --git a/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.h index 4c24f853692..d5944b38dab 100644 --- a/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/UnresolvedStyleValue.h @@ -17,10 +17,7 @@ namespace Web::CSS { class UnresolvedStyleValue final : public CSSStyleValue { public: - static ValueComparingNonnullRefPtr create(Vector&& values, bool contains_arbitrary_substitution_function, Optional original_source_text) - { - return adopt_ref(*new (nothrow) UnresolvedStyleValue(move(values), contains_arbitrary_substitution_function, move(original_source_text))); - } + static ValueComparingNonnullRefPtr create(Vector&& values, Optional contains_arbitrary_substitution_function = {}, Optional original_source_text = {}); virtual ~UnresolvedStyleValue() override = default; virtual String to_string(SerializationMode) const override; @@ -32,13 +29,7 @@ public: virtual bool equals(CSSStyleValue const& other) const override; private: - UnresolvedStyleValue(Vector&& values, bool contains_arbitrary_substitution_function, Optional original_source_text) - : CSSStyleValue(Type::Unresolved) - , m_values(move(values)) - , m_contains_arbitrary_substitution_function(contains_arbitrary_substitution_function) - , m_original_source_text(move(original_source_text)) - { - } + UnresolvedStyleValue(Vector&& values, bool contains_arbitrary_substitution_function, Optional original_source_text); Vector m_values; bool m_contains_arbitrary_substitution_function { false };