diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index b4fb86ac21..2cd4effbcf 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -16,6 +16,7 @@ set(SOURCES Crypto/Crypto.cpp Crypto/SubtleCrypto.cpp CSS/Angle.cpp + CSS/CalculatedOr.cpp CSS/Clip.cpp CSS/CSS.cpp CSS/CSSConditionRule.cpp diff --git a/Userland/Libraries/LibWeb/CSS/CalculatedOr.cpp b/Userland/Libraries/LibWeb/CSS/CalculatedOr.cpp new file mode 100644 index 0000000000..ed01f47a68 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CalculatedOr.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "CalculatedOr.h" + +namespace Web::CSS { + +Angle AngleOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&) const +{ + return calculated->resolve_angle().value(); +} + +Frequency FrequencyOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&) const +{ + return calculated->resolve_frequency().value(); +} + +Length LengthOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const& layout_node) const +{ + return calculated->resolve_length(layout_node).value(); +} + +Percentage PercentageOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&) const +{ + return calculated->resolve_percentage().value(); +} + +Time TimeOrCalculated::resolve_calculated(NonnullRefPtr const& calculated, Layout::Node const&) const +{ + return calculated->resolve_time().value(); +} + +} diff --git a/Userland/Libraries/LibWeb/CSS/CalculatedOr.h b/Userland/Libraries/LibWeb/CSS/CalculatedOr.h new file mode 100644 index 0000000000..f64e879476 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CalculatedOr.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2023, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#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 const& calculated() const + { + VERIFY(is_calculated()); + return m_value.template get>(); + } + + virtual T resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const = 0; + + 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); + }); + } + + ErrorOr 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()); + } + +private: + Variant> m_value; +}; + +class AngleOrCalculated : public CalculatedOr { +public: + using CalculatedOr::CalculatedOr; + + Angle resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const override; +}; + +class FrequencyOrCalculated : public CalculatedOr { +public: + using CalculatedOr::CalculatedOr; + + Frequency resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const override; +}; + +class LengthOrCalculated : public CalculatedOr { +public: + using CalculatedOr::CalculatedOr; + + Length resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const override; +}; + +class PercentageOrCalculated : public CalculatedOr { +public: + using CalculatedOr::CalculatedOr; + + Percentage resolve_calculated(NonnullRefPtr const&, Layout::Node const&) const override; +}; + +class TimeOrCalculated : public CalculatedOr