ladybird/Libraries/LibWeb/CSS/Parser/ArbitrarySubstitutionFunctions.h
Andreas Kling ff13ac2b79 LibWeb: Avoid copying ASF argument component values
Parse arbitrary substitution function arguments as spans into the
existing component value list. This avoids copying each argument into a
new vector for var(), attr(), env(), if(), and inherit() parsing.

Expose a span-returning declaration-value parser that shares the same
walker as the existing vector-returning API, so the argument parser does
not duplicate declaration-value grammar logic. Substitution output still
uses owned vectors, and the unresolved Typed OM reifier now consumes
spans too.
2026-06-03 22:28:54 +02:00

68 lines
2 KiB
C++

/*
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Span.h>
#include <AK/String.h>
#include <LibWeb/Forward.h>
namespace Web::CSS::Parser {
// https://drafts.csswg.org/css-values-5/#substitution-context
struct SubstitutionContext {
enum class DependencyType : u8 {
Property,
Attribute,
Function,
};
DependencyType dependency_type;
String first;
Optional<String> second {};
bool is_cyclic { false };
bool operator==(SubstitutionContext const&) const;
String to_string() const;
};
class GuardedSubstitutionContexts {
public:
void guard(SubstitutionContext&);
void unguard(SubstitutionContext const&);
private:
Vector<SubstitutionContext&> m_contexts;
};
enum class ArbitrarySubstitutionFunction : u8 {
Attr,
Env,
If,
Inherit,
Var,
};
[[nodiscard]] Optional<ArbitrarySubstitutionFunction> to_arbitrary_substitution_function(FlyString const& name);
bool contains_guaranteed_invalid_value(ReadonlySpan<ComponentValue>);
[[nodiscard]] Vector<ComponentValue> substitute_arbitrary_substitution_functions(DOM::AbstractElement&, GuardedSubstitutionContexts&, ReadonlySpan<ComponentValue>, Optional<SubstitutionContext> = {});
using DeclarationValueList = Vector<ReadonlySpan<ComponentValue>>;
struct IfArgsBranch {
ReadonlySpan<ComponentValue> condition;
Optional<ReadonlySpan<ComponentValue>> value;
};
using IfArgs = Vector<IfArgsBranch>;
using ArbitrarySubstitutionFunctionArguments = Variant<DeclarationValueList, IfArgs>;
// The returned argument spans borrow from the input component value list.
[[nodiscard]] Optional<ArbitrarySubstitutionFunctionArguments> parse_according_to_argument_grammar(ArbitrarySubstitutionFunction, ReadonlySpan<ComponentValue>);
[[nodiscard]] Vector<ComponentValue> replace_an_arbitrary_substitution_function(DOM::AbstractElement&, GuardedSubstitutionContexts&, ArbitrarySubstitutionFunction, ArbitrarySubstitutionFunctionArguments const&);
}