LibWeb/CSS: Introduce a LengthPercentageOrAuto type

This commit is contained in:
Sam Atkins 2025-08-28 15:58:38 +01:00
commit f57ffc3655
Notes: github-actions[bot] 2025-09-04 12:33:35 +00:00
2 changed files with 79 additions and 1 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023, Sam Atkins <atkinssj@serenityos.org>
* Copyright (c) 2022-2025, Sam Atkins <sam@ladybird.org>
*
* 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<CalculatedStyleValue const> 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<LengthPercentage> m_length_percentage;
};
class TimePercentage : public PercentageOr<Time, TimePercentage> {
public:
using PercentageOr<Time, TimePercentage>::PercentageOr;
@ -256,6 +325,14 @@ struct AK::Formatter<Web::CSS::LengthPercentage> : Formatter<StringView> {
}
};
template<>
struct AK::Formatter<Web::CSS::LengthPercentageOrAuto> : Formatter<StringView> {
ErrorOr<void> format(FormatBuilder& builder, Web::CSS::LengthPercentageOrAuto const& length_percentage_or_auto)
{
return Formatter<StringView>::format(builder, length_percentage_or_auto.to_string(Web::CSS::SerializationMode::Normal));
}
};
template<>
struct AK::Formatter<Web::CSS::TimePercentage> : Formatter<StringView> {
ErrorOr<void> format(FormatBuilder& builder, Web::CSS::TimePercentage const& time_percentage)

View file

@ -314,6 +314,7 @@ class LengthOrAuto;
class LengthOrAutoOrCalculated;
class LengthOrCalculated;
class LengthPercentage;
class LengthPercentageOrAuto;
class LengthStyleValue;
class LinearGradientStyleValue;
class MathDepthStyleValue;