/* * Copyright (c) 2023, 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)) { } virtual ~CalculatedOr() = default; 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>(); } T resolved(Layout::Node const& layout_node) const { return m_value.visit( [&](T const& t) { return t; }, [&](NonnullRefPtr const& calculated) { return resolve_calculated(calculated, layout_node); }); } String to_string() const { if (is_calculated()) return m_value.template get>()->to_string(); return m_value.template get().to_string(); } 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: virtual T resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const = 0; virtual NonnullRefPtr create_style_value() const = 0; private: Variant> m_value; }; class AngleOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; private: virtual Angle resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const override; virtual NonnullRefPtr create_style_value() const override; }; class FlexOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; private: virtual Flex resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const override; virtual NonnullRefPtr create_style_value() const override; }; class FrequencyOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; private: virtual Frequency resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const override; virtual NonnullRefPtr create_style_value() const override; }; class IntegerOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; [[nodiscard]] i64 resolved(Length::ResolutionContext const&) const; private: virtual i64 resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const override; virtual NonnullRefPtr create_style_value() const override; }; class LengthOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; [[nodiscard]] Length resolved(Length::ResolutionContext const&) const; private: virtual Length resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const override; virtual NonnullRefPtr create_style_value() const override; }; class NumberOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; private: virtual double resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const override; virtual NonnullRefPtr create_style_value() const override; }; class PercentageOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; private: virtual Percentage resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const override; virtual NonnullRefPtr create_style_value() const override; }; class ResolutionOrCalculated : public CalculatedOr { public: using CalculatedOr::CalculatedOr; [[nodiscard]] Resolution resolved() const; private: virtual Resolution resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const override; virtual NonnullRefPtr create_style_value() const override; }; class TimeOrCalculated : public CalculatedOr