/* * Copyright (c) 2023-2025, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include namespace Web::CSS { template class CalculatedOr { public: CalculatedOr(T t) : m_value(move(t)) { } CalculatedOr(NonnullRefPtr calculated) : m_value(move(calculated)) { } bool is_calculated() const { return m_value.template has>(); } T const& value() const { VERIFY(!is_calculated()); return m_value.template get(); } NonnullRefPtr as_style_value() const { if (is_calculated()) return calculated(); return create_style_value(); } NonnullRefPtr const& calculated() const { VERIFY(is_calculated()); return m_value.template get>(); } Optional resolved(CalculationResolutionContext const& context) const { return m_value.visit( [&](T const& t) -> Optional { return t; }, [&](NonnullRefPtr const& calculated) { return resolve_calculated(calculated, context); }); } String to_string() const { return m_value.visit( [](T const& t) { if constexpr (IsArithmetic) { return String::number(t); } else { return t.to_string(); } }, [](NonnullRefPtr const& calculated) { return calculated->to_string(CSSStyleValue::SerializationMode::Normal); }); } bool operator==(CalculatedOr const& other) const { if (is_calculated() || other.is_calculated()) return false; return (m_value.template get() == other.m_value.template get()); } protected: Optional resolve_calculated(NonnullRefPtr const& calculated, CalculationResolutionContext const& context) const { return static_cast(this)->resolve_calculated(calculated, context); } NonnullRefPtr create_style_value() const { return static_cast(this)->create_style_value(); } private: Variant> m_value; }; class AngleOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; Optional resolve_calculated(NonnullRefPtr const&, CalculationResolutionContext const&) const; NonnullRefPtr create_style_value() const; }; class FlexOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; Optional resolve_calculated(NonnullRefPtr const&, CalculationResolutionContext const&) const; NonnullRefPtr create_style_value() const; }; class FrequencyOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; Optional resolve_calculated(NonnullRefPtr const&, CalculationResolutionContext const&) const; NonnullRefPtr create_style_value() const; }; class IntegerOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; Optional resolve_calculated(NonnullRefPtr const&, CalculationResolutionContext const&) const; NonnullRefPtr create_style_value() const; }; class LengthOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; Optional resolve_calculated(NonnullRefPtr const&, CalculationResolutionContext const&) const; NonnullRefPtr create_style_value() const; }; class NumberOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; Optional resolve_calculated(NonnullRefPtr const&, CalculationResolutionContext const&) const; NonnullRefPtr create_style_value() const; }; class PercentageOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; Optional resolve_calculated(NonnullRefPtr const&, CalculationResolutionContext const&) const; NonnullRefPtr create_style_value() const; }; class ResolutionOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; Optional resolve_calculated(NonnullRefPtr const&, CalculationResolutionContext const&) const; NonnullRefPtr create_style_value() const; }; class TimeOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; Optional