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.
This commit is contained in:
Sam Atkins 2025-07-10 14:19:24 +01:00 committed by Tim Ledbetter
commit d18b0c07ca
Notes: github-actions[bot] 2025-07-16 13:49:59 +00:00
4 changed files with 30 additions and 14 deletions

View file

@ -117,7 +117,7 @@ Parser::ParseErrorOr<NonnullRefPtr<CSSStyleValue const>> Parser::parse_descripto
// `component_values` already has what we want. Just skip through its tokens so code below knows we consumed them. // `component_values` already has what we want. Just skip through its tokens so code below knows we consumed them.
while (tokens.has_next_token()) while (tokens.has_next_token())
tokens.discard_a_token(); tokens.discard_a_token();
return UnresolvedStyleValue::create(move(component_values), false, {}); return UnresolvedStyleValue::create(move(component_values));
} }
case DescriptorMetadata::ValueType::PageSize: { case DescriptorMetadata::ValueType::PageSize: {
// https://drafts.csswg.org/css-page-3/#page-size-prop // https://drafts.csswg.org/css-page-3/#page-size-prop

View file

@ -4314,7 +4314,7 @@ NonnullRefPtr<CSSStyleValue const> Parser::resolve_unresolved_style_value(DOM::A
// NB: Custom properties have no grammar as such, so we skip this step for them. // 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. // FIXME: Parse according to @property syntax once we support that.
if (property_id == PropertyID::Custom) if (property_id == PropertyID::Custom)
return UnresolvedStyleValue::create(move(result), false, {}); return UnresolvedStyleValue::create(move(result));
auto expanded_value_tokens = TokenStream { result }; auto expanded_value_tokens = TokenStream { result };
auto parsed_value = parse_css_value(property_id, expanded_value_tokens); auto parsed_value = parse_css_value(property_id, expanded_value_tokens);

View file

@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org> * Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org> * Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
* Copyright (c) 2021-2024, Sam Atkins <sam@ladybird.org> * Copyright (c) 2021-2025, Sam Atkins <sam@ladybird.org>
* Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech> * Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
@ -13,6 +13,31 @@
namespace Web::CSS { namespace Web::CSS {
ValueComparingNonnullRefPtr<UnresolvedStyleValue const> UnresolvedStyleValue::create(Vector<Parser::ComponentValue>&& values, Optional<bool> contains_arbitrary_substitution_function, Optional<String> 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<Parser::ComponentValue>&& values, bool contains_arbitrary_substitution_function, Optional<String> 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 String UnresolvedStyleValue::to_string(SerializationMode) const
{ {
if (m_original_source_text.has_value()) if (m_original_source_text.has_value())

View file

@ -17,10 +17,7 @@ namespace Web::CSS {
class UnresolvedStyleValue final : public CSSStyleValue { class UnresolvedStyleValue final : public CSSStyleValue {
public: public:
static ValueComparingNonnullRefPtr<UnresolvedStyleValue const> create(Vector<Parser::ComponentValue>&& values, bool contains_arbitrary_substitution_function, Optional<String> original_source_text) static ValueComparingNonnullRefPtr<UnresolvedStyleValue const> create(Vector<Parser::ComponentValue>&& values, Optional<bool> contains_arbitrary_substitution_function = {}, Optional<String> original_source_text = {});
{
return adopt_ref(*new (nothrow) UnresolvedStyleValue(move(values), contains_arbitrary_substitution_function, move(original_source_text)));
}
virtual ~UnresolvedStyleValue() override = default; virtual ~UnresolvedStyleValue() override = default;
virtual String to_string(SerializationMode) const override; virtual String to_string(SerializationMode) const override;
@ -32,13 +29,7 @@ public:
virtual bool equals(CSSStyleValue const& other) const override; virtual bool equals(CSSStyleValue const& other) const override;
private: private:
UnresolvedStyleValue(Vector<Parser::ComponentValue>&& values, bool contains_arbitrary_substitution_function, Optional<String> original_source_text) UnresolvedStyleValue(Vector<Parser::ComponentValue>&& values, bool contains_arbitrary_substitution_function, Optional<String> 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))
{
}
Vector<Parser::ComponentValue> m_values; Vector<Parser::ComponentValue> m_values;
bool m_contains_arbitrary_substitution_function { false }; bool m_contains_arbitrary_substitution_function { false };