From f57ffc365554ef0e9d9aebde59f2c677b17247c0 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Thu, 28 Aug 2025 15:58:38 +0100 Subject: [PATCH] LibWeb/CSS: Introduce a LengthPercentageOrAuto type --- Libraries/LibWeb/CSS/PercentageOr.h | 79 ++++++++++++++++++++++++++++- Libraries/LibWeb/Forward.h | 1 + 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/Libraries/LibWeb/CSS/PercentageOr.h b/Libraries/LibWeb/CSS/PercentageOr.h index 915dbaa29d6..419c9344878 100644 --- a/Libraries/LibWeb/CSS/PercentageOr.h +++ b/Libraries/LibWeb/CSS/PercentageOr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023, Sam Atkins + * Copyright (c) 2022-2025, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ @@ -214,6 +214,75 @@ public: Length const& length() const { return get_t(); } }; +class LengthPercentageOrAuto { +public: + LengthPercentageOrAuto(LengthPercentage length_percentage) + { + if (length_percentage.is_auto()) + m_length_percentage = {}; + else + m_length_percentage = move(length_percentage); + } + + LengthPercentageOrAuto(Length length) + { + if (length.is_auto()) + m_length_percentage = {}; + else + m_length_percentage = move(length); + } + + LengthPercentageOrAuto(Percentage percentage) + : m_length_percentage(move(percentage)) + { + } + + static LengthPercentageOrAuto make_auto() + { + return LengthPercentageOrAuto(); + } + + bool is_auto() const { return !m_length_percentage.has_value(); } + bool is_length() const { return m_length_percentage.has_value() && m_length_percentage->is_length(); } + bool is_percentage() const { return m_length_percentage.has_value() && m_length_percentage->is_percentage(); } + bool is_calculated() const { return m_length_percentage.has_value() && m_length_percentage->is_calculated(); } + + bool contains_percentage() const { return m_length_percentage.has_value() && m_length_percentage->contains_percentage(); } + + LengthPercentage const& length_percentage() const { return m_length_percentage.value(); } + Length const& length() const { return m_length_percentage->length(); } + Percentage const& percentage() const { return m_length_percentage->percentage(); } + NonnullRefPtr const& calculated() const { return m_length_percentage->calculated(); } + + LengthOrAuto resolved_or_auto(Layout::Node const& layout_node, CSSPixels reference_value) const + { + if (is_auto()) + return LengthOrAuto::make_auto(); + return length_percentage().resolved(layout_node, reference_value); + } + + CSSPixels to_px_or_zero(Layout::Node const& layout_node, CSSPixels reference_value) const + { + if (is_auto()) + return 0; + return length_percentage().to_px(layout_node, reference_value); + } + + String to_string(SerializationMode mode) const + { + if (is_auto()) + return "auto"_string; + return m_length_percentage->to_string(mode); + } + + bool operator==(LengthPercentageOrAuto const&) const = default; + +private: + LengthPercentageOrAuto() = default; + + Optional m_length_percentage; +}; + class TimePercentage : public PercentageOr { public: using PercentageOr::PercentageOr; @@ -256,6 +325,14 @@ struct AK::Formatter : Formatter { } }; +template<> +struct AK::Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, Web::CSS::LengthPercentageOrAuto const& length_percentage_or_auto) + { + return Formatter::format(builder, length_percentage_or_auto.to_string(Web::CSS::SerializationMode::Normal)); + } +}; + template<> struct AK::Formatter : Formatter { ErrorOr format(FormatBuilder& builder, Web::CSS::TimePercentage const& time_percentage) diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index d500b4c516d..810130ecd65 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -314,6 +314,7 @@ class LengthOrAuto; class LengthOrAutoOrCalculated; class LengthOrCalculated; class LengthPercentage; +class LengthPercentageOrAuto; class LengthStyleValue; class LinearGradientStyleValue; class MathDepthStyleValue;