| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <AK/Variant.h>
 | 
					
						
							|  |  |  | #include <LibWeb/CSS/Angle.h>
 | 
					
						
							| 
									
										
										
										
											2023-12-27 12:56:00 +00:00
										 |  |  | #include <LibWeb/CSS/Flex.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | #include <LibWeb/CSS/Frequency.h>
 | 
					
						
							|  |  |  | #include <LibWeb/CSS/Length.h>
 | 
					
						
							|  |  |  | #include <LibWeb/CSS/Percentage.h>
 | 
					
						
							| 
									
										
										
										
											2023-12-30 17:05:23 +00:00
										 |  |  | #include <LibWeb/CSS/Resolution.h>
 | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  | #include <LibWeb/CSS/StyleValues/CSSMathValue.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | #include <LibWeb/CSS/Time.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Web::CSS { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<typename T> | 
					
						
							|  |  |  | class CalculatedOr { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     CalculatedOr(T t) | 
					
						
							|  |  |  |         : m_value(move(t)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     CalculatedOr(NonnullRefPtr<CSSMathValue> calculated) | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  |         : m_value(move(calculated)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual ~CalculatedOr() = default; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     bool is_calculated() const { return m_value.template has<NonnullRefPtr<CSSMathValue>>(); } | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     T const& value() const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         VERIFY(!is_calculated()); | 
					
						
							|  |  |  |         return m_value.template get<T>(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 11:10:54 +01:00
										 |  |  |     NonnullRefPtr<CSSStyleValue> as_style_value() const | 
					
						
							| 
									
										
										
										
											2023-12-28 17:37:37 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |         if (is_calculated()) | 
					
						
							|  |  |  |             return calculated(); | 
					
						
							|  |  |  |         return create_style_value(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     NonnullRefPtr<CSSMathValue> const& calculated() const | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         VERIFY(is_calculated()); | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |         return m_value.template get<NonnullRefPtr<CSSMathValue>>(); | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     T resolved(Layout::Node const& layout_node) const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return m_value.visit( | 
					
						
							|  |  |  |             [&](T const& t) { | 
					
						
							|  |  |  |                 return t; | 
					
						
							|  |  |  |             }, | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |             [&](NonnullRefPtr<CSSMathValue> const& calculated) { | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  |                 return resolve_calculated(calculated, layout_node); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-22 12:25:30 +01:00
										 |  |  |     String to_string() const | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         if (is_calculated()) | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |             return m_value.template get<NonnullRefPtr<CSSMathValue>>()->to_string(); | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return m_value.template get<T>().to_string(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool operator==(CalculatedOr<T> const& other) const | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (is_calculated() || other.is_calculated()) | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         return (m_value.template get<T>() == other.m_value.template get<T>()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-28 17:37:37 +00:00
										 |  |  | protected: | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     virtual T resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const = 0; | 
					
						
							| 
									
										
										
										
											2024-08-14 11:10:54 +01:00
										 |  |  |     virtual NonnullRefPtr<CSSStyleValue> create_style_value() const = 0; | 
					
						
							| 
									
										
										
										
											2023-12-28 17:37:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     Variant<T, NonnullRefPtr<CSSMathValue>> m_value; | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AngleOrCalculated : public CalculatedOr<Angle> { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     using CalculatedOr<Angle>::CalculatedOr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-28 17:37:37 +00:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     virtual Angle resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override; | 
					
						
							| 
									
										
										
										
											2024-08-14 11:10:54 +01:00
										 |  |  |     virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override; | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-27 12:56:00 +00:00
										 |  |  | class FlexOrCalculated : public CalculatedOr<Flex> { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     using CalculatedOr<Flex>::CalculatedOr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-28 17:37:37 +00:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     virtual Flex resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override; | 
					
						
							| 
									
										
										
										
											2024-08-14 11:10:54 +01:00
										 |  |  |     virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override; | 
					
						
							| 
									
										
										
										
											2023-12-27 12:56:00 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | class FrequencyOrCalculated : public CalculatedOr<Frequency> { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     using CalculatedOr<Frequency>::CalculatedOr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-28 17:37:37 +00:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     virtual Frequency resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override; | 
					
						
							| 
									
										
										
										
											2024-08-14 11:10:54 +01:00
										 |  |  |     virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override; | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-27 12:56:00 +00:00
										 |  |  | class IntegerOrCalculated : public CalculatedOr<i64> { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     using CalculatedOr<i64>::CalculatedOr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-28 17:37:37 +00:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     virtual i64 resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override; | 
					
						
							| 
									
										
										
										
											2024-08-14 11:10:54 +01:00
										 |  |  |     virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override; | 
					
						
							| 
									
										
										
										
											2023-12-27 12:56:00 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | class LengthOrCalculated : public CalculatedOr<Length> { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     using CalculatedOr<Length>::CalculatedOr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-28 15:52:06 +02:00
										 |  |  |     [[nodiscard]] Length resolved(Length::ResolutionContext const&) const; | 
					
						
							| 
									
										
										
										
											2023-12-28 17:37:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     virtual Length resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override; | 
					
						
							| 
									
										
										
										
											2024-08-14 11:10:54 +01:00
										 |  |  |     virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override; | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-27 12:56:00 +00:00
										 |  |  | class NumberOrCalculated : public CalculatedOr<double> { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     using CalculatedOr<double>::CalculatedOr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-28 17:37:37 +00:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     virtual double resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override; | 
					
						
							| 
									
										
										
										
											2024-08-14 11:10:54 +01:00
										 |  |  |     virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override; | 
					
						
							| 
									
										
										
										
											2023-12-27 12:56:00 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | class PercentageOrCalculated : public CalculatedOr<Percentage> { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     using CalculatedOr<Percentage>::CalculatedOr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-28 17:37:37 +00:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     virtual Percentage resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override; | 
					
						
							| 
									
										
										
										
											2024-08-14 11:10:54 +01:00
										 |  |  |     virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override; | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-30 17:05:23 +00:00
										 |  |  | class ResolutionOrCalculated : public CalculatedOr<Resolution> { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     using CalculatedOr<Resolution>::CalculatedOr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-28 17:37:37 +00:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     virtual Resolution resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override; | 
					
						
							| 
									
										
										
										
											2024-08-14 11:10:54 +01:00
										 |  |  |     virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override; | 
					
						
							| 
									
										
										
										
											2023-12-30 17:05:23 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | class TimeOrCalculated : public CalculatedOr<Time> { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     using CalculatedOr<Time>::CalculatedOr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-28 17:37:37 +00:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2024-09-18 17:27:47 +01:00
										 |  |  |     virtual Time resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override; | 
					
						
							| 
									
										
										
										
											2024-08-14 11:10:54 +01:00
										 |  |  |     virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override; | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<> | 
					
						
							|  |  |  | struct AK::Formatter<Web::CSS::AngleOrCalculated> : Formatter<StringView> { | 
					
						
							|  |  |  |     ErrorOr<void> format(FormatBuilder& builder, Web::CSS::AngleOrCalculated const& calculated_or) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-08-22 12:25:30 +01:00
										 |  |  |         return Formatter<StringView>::format(builder, calculated_or.to_string()); | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<> | 
					
						
							|  |  |  | struct AK::Formatter<Web::CSS::FrequencyOrCalculated> : Formatter<StringView> { | 
					
						
							|  |  |  |     ErrorOr<void> format(FormatBuilder& builder, Web::CSS::FrequencyOrCalculated const& calculated_or) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-08-22 12:25:30 +01:00
										 |  |  |         return Formatter<StringView>::format(builder, calculated_or.to_string()); | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<> | 
					
						
							|  |  |  | struct AK::Formatter<Web::CSS::LengthOrCalculated> : Formatter<StringView> { | 
					
						
							|  |  |  |     ErrorOr<void> format(FormatBuilder& builder, Web::CSS::LengthOrCalculated const& calculated_or) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-08-22 12:25:30 +01:00
										 |  |  |         return Formatter<StringView>::format(builder, calculated_or.to_string()); | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<> | 
					
						
							|  |  |  | struct AK::Formatter<Web::CSS::PercentageOrCalculated> : Formatter<StringView> { | 
					
						
							|  |  |  |     ErrorOr<void> format(FormatBuilder& builder, Web::CSS::PercentageOrCalculated const& calculated_or) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-08-22 12:25:30 +01:00
										 |  |  |         return Formatter<StringView>::format(builder, calculated_or.to_string()); | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<> | 
					
						
							|  |  |  | struct AK::Formatter<Web::CSS::TimeOrCalculated> : Formatter<StringView> { | 
					
						
							|  |  |  |     ErrorOr<void> format(FormatBuilder& builder, Web::CSS::TimeOrCalculated const& calculated_or) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-08-22 12:25:30 +01:00
										 |  |  |         return Formatter<StringView>::format(builder, calculated_or.to_string()); | 
					
						
							| 
									
										
										
										
											2023-03-30 16:57:49 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | }; |