diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2023-03-30 16:57:49 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-03-30 21:29:50 +0200 |
commit | fa90a3bb4fc3e4a8a0caa0b80a7ac87765ab67f9 (patch) | |
tree | 2d6acd146dcc1107c56d6a28d2da6d69ddde1f3b /Userland | |
parent | b727f8113f9280e64e18dcbb0ed2921b19e51083 (diff) | |
download | serenity-fa90a3bb4fc3e4a8a0caa0b80a7ac87765ab67f9.zip |
LibWeb: Introduce CalculatedOr type
This is intended as a replacement for Length and friends each holding a
`RefPtr<CalculatedStyleValue>`. Instead, let's make the types explicit
about whether they are calculated or not. This then means a Length is
always a Length, and won't require including `StyleValue.h`.
As noted, it's probably nicer for LengthOrCalculated to live in
`Length.h`, but we can't do that until Length stops including
`StyleValue.h`.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CalculatedOr.cpp | 36 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CalculatedOr.h | 155 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Percentage.h | 13 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Forward.h | 5 |
5 files changed, 206 insertions, 4 deletions
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 <atkinssj@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "CalculatedOr.h" + +namespace Web::CSS { + +Angle AngleOrCalculated::resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const& calculated, Layout::Node const&) const +{ + return calculated->resolve_angle().value(); +} + +Frequency FrequencyOrCalculated::resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const& calculated, Layout::Node const&) const +{ + return calculated->resolve_frequency().value(); +} + +Length LengthOrCalculated::resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const& calculated, Layout::Node const& layout_node) const +{ + return calculated->resolve_length(layout_node).value(); +} + +Percentage PercentageOrCalculated::resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const& calculated, Layout::Node const&) const +{ + return calculated->resolve_percentage().value(); +} + +Time TimeOrCalculated::resolve_calculated(NonnullRefPtr<CalculatedStyleValue> 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 <atkinssj@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/Variant.h> +#include <LibWeb/CSS/Angle.h> +#include <LibWeb/CSS/Frequency.h> +#include <LibWeb/CSS/Length.h> +#include <LibWeb/CSS/Percentage.h> +#include <LibWeb/CSS/StyleValue.h> +#include <LibWeb/CSS/Time.h> + +namespace Web::CSS { + +template<typename T> +class CalculatedOr { +public: + CalculatedOr(T t) + : m_value(move(t)) + { + } + + CalculatedOr(NonnullRefPtr<CalculatedStyleValue> calculated) + : m_value(move(calculated)) + { + } + + virtual ~CalculatedOr() = default; + + bool is_calculated() const { return m_value.template has<NonnullRefPtr<CalculatedStyleValue>>(); } + + T const& value() const + { + VERIFY(!is_calculated()); + return m_value.template get<T>(); + } + + NonnullRefPtr<CalculatedStyleValue> const& calculated() const + { + VERIFY(is_calculated()); + return m_value.template get<NonnullRefPtr<CalculatedStyleValue>>(); + } + + virtual T resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const&, Layout::Node const&) const = 0; + + T resolved(Layout::Node const& layout_node) const + { + return m_value.visit( + [&](T const& t) { + return t; + }, + [&](NonnullRefPtr<CalculatedStyleValue> const& calculated) { + return resolve_calculated(calculated, layout_node); + }); + } + + ErrorOr<String> to_string() const + { + if (is_calculated()) + return m_value.template get<NonnullRefPtr<CalculatedStyleValue>>()->to_string(); + + 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>()); + } + +private: + Variant<T, NonnullRefPtr<CalculatedStyleValue>> m_value; +}; + +class AngleOrCalculated : public CalculatedOr<Angle> { +public: + using CalculatedOr<Angle>::CalculatedOr; + + Angle resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const&, Layout::Node const&) const override; +}; + +class FrequencyOrCalculated : public CalculatedOr<Frequency> { +public: + using CalculatedOr<Frequency>::CalculatedOr; + + Frequency resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const&, Layout::Node const&) const override; +}; + +class LengthOrCalculated : public CalculatedOr<Length> { +public: + using CalculatedOr<Length>::CalculatedOr; + + Length resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const&, Layout::Node const&) const override; +}; + +class PercentageOrCalculated : public CalculatedOr<Percentage> { +public: + using CalculatedOr<Percentage>::CalculatedOr; + + Percentage resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const&, Layout::Node const&) const override; +}; + +class TimeOrCalculated : public CalculatedOr<Time> { +public: + using CalculatedOr<Time>::CalculatedOr; + + Time resolve_calculated(NonnullRefPtr<CalculatedStyleValue> const&, Layout::Node const&) const override; +}; + +} + +template<> +struct AK::Formatter<Web::CSS::AngleOrCalculated> : Formatter<StringView> { + ErrorOr<void> format(FormatBuilder& builder, Web::CSS::AngleOrCalculated const& calculated_or) + { + return Formatter<StringView>::format(builder, TRY(calculated_or.to_string())); + } +}; + +template<> +struct AK::Formatter<Web::CSS::FrequencyOrCalculated> : Formatter<StringView> { + ErrorOr<void> format(FormatBuilder& builder, Web::CSS::FrequencyOrCalculated const& calculated_or) + { + return Formatter<StringView>::format(builder, TRY(calculated_or.to_string())); + } +}; + +template<> +struct AK::Formatter<Web::CSS::LengthOrCalculated> : Formatter<StringView> { + ErrorOr<void> format(FormatBuilder& builder, Web::CSS::LengthOrCalculated const& calculated_or) + { + return Formatter<StringView>::format(builder, TRY(calculated_or.to_string())); + } +}; + +template<> +struct AK::Formatter<Web::CSS::PercentageOrCalculated> : Formatter<StringView> { + ErrorOr<void> format(FormatBuilder& builder, Web::CSS::PercentageOrCalculated const& calculated_or) + { + return Formatter<StringView>::format(builder, TRY(calculated_or.to_string())); + } +}; + +template<> +struct AK::Formatter<Web::CSS::TimeOrCalculated> : Formatter<StringView> { + ErrorOr<void> format(FormatBuilder& builder, Web::CSS::TimeOrCalculated const& calculated_or) + { + return Formatter<StringView>::format(builder, TRY(calculated_or.to_string())); + } +}; diff --git a/Userland/Libraries/LibWeb/CSS/Percentage.h b/Userland/Libraries/LibWeb/CSS/Percentage.h index f49ec90777..48fbc067f9 100644 --- a/Userland/Libraries/LibWeb/CSS/Percentage.h +++ b/Userland/Libraries/LibWeb/CSS/Percentage.h @@ -83,8 +83,10 @@ public: { return m_value.visit( [&](T const& t) { - if (t.is_calculated()) - return calculated_style_value_contains_percentage(*t.calculated_style_value()); + if constexpr (requires { t.is_calculated(); }) { + if (t.is_calculated()) + return calculated_style_value_contains_percentage(*t.calculated_style_value()); + } return false; }, [&](Percentage const&) { @@ -116,8 +118,11 @@ public: { return m_value.visit( [&](T const& t) { - if (t.is_calculated()) - return resolve_calculated(t.calculated_style_value(), layout_node, reference_value); + if constexpr (requires { t.is_calculated(); }) { + if (t.is_calculated()) + return resolve_calculated(t.calculated_style_value(), layout_node, reference_value); + } + return t; }, [&](Percentage const& percentage) { diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index a5d52e689e..2d3f1a9ad7 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -28,6 +28,7 @@ namespace Web::CSS { class AbstractImageStyleValue; class Angle; class AnglePercentage; +class AngleOrCalculated; class AngleStyleValue; class BackgroundRepeatStyleValue; class BackgroundSizeStyleValue; @@ -61,6 +62,7 @@ class FontFace; class FontStyleValue; class Frequency; class FrequencyPercentage; +class FrequencyOrCalculated; class FrequencyStyleValue; class GridAreaShorthandStyleValue; class GridMinMax; @@ -79,6 +81,7 @@ class InitialStyleValue; class Length; class LengthBox; class LengthPercentage; +class LengthOrCalculated; class LengthStyleValue; class LinearGradientStyleValue; class ListStyleStyleValue; @@ -91,6 +94,7 @@ class Number; class NumericStyleValue; class OverflowStyleValue; class Percentage; +class PercentageOrCalculated; class PercentageStyleValue; class PositionStyleValue; class PropertyOwningCSSStyleDeclaration; @@ -113,6 +117,7 @@ class Supports; class TextDecorationStyleValue; class Time; class TimePercentage; +class TimeOrCalculated; class TimeStyleValue; class TransformationStyleValue; class UnicodeRange; |