1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 21:07:34 +00:00

LibWeb: Resolve cyclic declaration/definitions involving Length

This remained undetected for a long time as HeaderCheck is disabled by
default. This commit makes the following file compile again:

    // file: compile_me.cpp
    #include <LibWeb/CSS/GridTrackSize.h>
    // That's it, this was enough to cause a compilation error.
This commit is contained in:
Ben Wiederhake 2022-09-13 17:42:39 +02:00 committed by Sam Atkins
parent 53eb35caba
commit 8deced39a8
15 changed files with 192 additions and 125 deletions

View file

@ -20,16 +20,20 @@ GridTrackSize::GridTrackSize(Length length)
GridTrackSize::GridTrackSize(Percentage percentage)
: m_type(Type::Percentage)
, m_length { Length::make_px(0) }
, m_percentage(percentage)
{
}
GridTrackSize::GridTrackSize(float flexible_length)
: m_type(Type::FlexibleLength)
, m_length { Length::make_px(0) }
, m_flexible_length(flexible_length)
{
}
GridTrackSize::~GridTrackSize() = default;
GridTrackSize GridTrackSize::make_auto()
{
return GridTrackSize(CSS::Length::make_auto());
@ -48,4 +52,9 @@ String GridTrackSize::to_string() const
VERIFY_NOT_REACHED();
}
Length GridTrackSize::length() const
{
return m_length;
}
}

View file

@ -25,6 +25,7 @@ public:
GridTrackSize(Length);
GridTrackSize(Percentage);
GridTrackSize(float);
~GridTrackSize();
static GridTrackSize make_auto();
@ -34,7 +35,7 @@ public:
bool is_percentage() const { return m_type == Type::Percentage; }
bool is_flexible_length() const { return m_type == Type::FlexibleLength; }
Length length() const { return m_length; }
Length length() const;
Percentage percentage() const { return m_percentage; }
float flexible_length() const { return m_flexible_length; }
@ -57,7 +58,9 @@ public:
private:
Type m_type;
Length m_length { Length::make_px(0) };
// Length includes a RefPtr<CalculatedStyleValue> member, but we can't include the header StyleValue.h as it includes
// this file already. To break the cyclic dependency, we must initialize m_length in the constructor.
Length m_length;
Percentage m_percentage { Percentage(0) };
float m_flexible_length { 0 };
};

View file

@ -28,6 +28,7 @@ Length::Length(float value, Type type)
, m_value(value)
{
}
Length::~Length() = default;
Length Length::make_auto()
{
@ -204,4 +205,11 @@ NonnullRefPtr<CalculatedStyleValue> Length::calculated_style_value() const
return *m_calculated_style;
}
bool Length::operator==(Length const& other) const
{
if (is_calculated())
return m_calculated_style == other.m_calculated_style;
return m_type == other.m_type && m_value == other.m_value;
}
}

View file

@ -40,6 +40,7 @@ public:
// this file already. To break the cyclic dependency, we must move all method definitions out.
Length(int value, Type type);
Length(float value, Type type);
~Length();
static Length make_auto();
static Length make_px(float value);
@ -117,13 +118,9 @@ public:
String to_string() const;
bool operator==(Length const& other) const
{
if (is_calculated())
return m_calculated_style == other.m_calculated_style;
return m_type == other.m_type && m_value == other.m_value;
}
// We have a RefPtr<CalculatedStyleValue> member, but can't include the header StyleValue.h as it includes
// this file already. To break the cyclic dependency, we must move all method definitions out.
bool operator==(Length const& other) const;
bool operator!=(Length const& other) const
{
return !(*this == other);

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2022, Ben Wiederhake <BenWiederhake.GitHub@gmx.de>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "LengthBox.h"
#include <LibWeb/CSS/StyleValue.h>
namespace Web::CSS {
LengthBox::LengthBox()
: m_top(Length::make_auto())
, m_right(Length::make_auto())
, m_bottom(Length::make_auto())
, m_left(Length::make_auto())
{
}
LengthBox::LengthBox(LengthPercentage top, LengthPercentage right, LengthPercentage bottom, LengthPercentage left)
: m_top(top)
, m_right(right)
, m_bottom(bottom)
, m_left(left)
{
}
LengthBox::~LengthBox() = default;
}

View file

@ -10,11 +10,28 @@
namespace Web::CSS {
struct LengthBox {
LengthPercentage top { Length::make_auto() };
LengthPercentage right { Length::make_auto() };
LengthPercentage bottom { Length::make_auto() };
LengthPercentage left { Length::make_auto() };
class LengthBox {
public:
LengthBox();
LengthBox(LengthPercentage top, LengthPercentage right, LengthPercentage bottom, LengthPercentage left);
~LengthBox();
// Length (and thus LengthPercentage) includes a RefPtr<CalculatedStyleValue> member, but we can't include the header StyleValue.h as it includes
// this file already. To break the cyclic dependency, we must initialize these members in the constructor.
LengthPercentage& top() { return m_top; }
LengthPercentage& right() { return m_right; }
LengthPercentage& bottom() { return m_bottom; }
LengthPercentage& left() { return m_left; };
LengthPercentage const& top() const { return m_top; }
LengthPercentage const& right() const { return m_right; }
LengthPercentage const& bottom() const { return m_bottom; }
LengthPercentage const& left() const { return m_left; };
private:
LengthPercentage m_top;
LengthPercentage m_right;
LengthPercentage m_bottom;
LengthPercentage m_left;
};
}

View file

@ -359,20 +359,20 @@ RefPtr<StyleValue> ResolvedCSSStyleDeclaration::style_value_for_property(Layout:
case CSS::PropertyID::Margin: {
auto margin = layout_node.computed_values().margin();
auto values = NonnullRefPtrVector<StyleValue> {};
values.append(style_value_for_length_percentage(margin.top));
values.append(style_value_for_length_percentage(margin.right));
values.append(style_value_for_length_percentage(margin.bottom));
values.append(style_value_for_length_percentage(margin.left));
values.append(style_value_for_length_percentage(margin.top()));
values.append(style_value_for_length_percentage(margin.right()));
values.append(style_value_for_length_percentage(margin.bottom()));
values.append(style_value_for_length_percentage(margin.left()));
return StyleValueList::create(move(values), StyleValueList::Separator::Space);
}
case CSS::PropertyID::MarginBottom:
return style_value_for_length_percentage(layout_node.computed_values().margin().bottom);
return style_value_for_length_percentage(layout_node.computed_values().margin().bottom());
case CSS::PropertyID::MarginLeft:
return style_value_for_length_percentage(layout_node.computed_values().margin().left);
return style_value_for_length_percentage(layout_node.computed_values().margin().left());
case CSS::PropertyID::MarginRight:
return style_value_for_length_percentage(layout_node.computed_values().margin().right);
return style_value_for_length_percentage(layout_node.computed_values().margin().right());
case CSS::PropertyID::MarginTop:
return style_value_for_length_percentage(layout_node.computed_values().margin().top);
return style_value_for_length_percentage(layout_node.computed_values().margin().top());
case CSS::PropertyID::MaxHeight:
return style_value_for_length_percentage(layout_node.computed_values().max_height());
case CSS::PropertyID::MaxWidth:
@ -392,20 +392,20 @@ RefPtr<StyleValue> ResolvedCSSStyleDeclaration::style_value_for_property(Layout:
case CSS::PropertyID::Padding: {
auto padding = layout_node.computed_values().padding();
auto values = NonnullRefPtrVector<StyleValue> {};
values.append(style_value_for_length_percentage(padding.top));
values.append(style_value_for_length_percentage(padding.right));
values.append(style_value_for_length_percentage(padding.bottom));
values.append(style_value_for_length_percentage(padding.left));
values.append(style_value_for_length_percentage(padding.top()));
values.append(style_value_for_length_percentage(padding.right()));
values.append(style_value_for_length_percentage(padding.bottom()));
values.append(style_value_for_length_percentage(padding.left()));
return StyleValueList::create(move(values), StyleValueList::Separator::Space);
}
case CSS::PropertyID::PaddingBottom:
case CSS::PropertyID::PaddingLeft:
return style_value_for_length_percentage(layout_node.computed_values().padding().left);
return style_value_for_length_percentage(layout_node.computed_values().padding().bottom);
return style_value_for_length_percentage(layout_node.computed_values().padding().left());
return style_value_for_length_percentage(layout_node.computed_values().padding().bottom());
case CSS::PropertyID::PaddingRight:
return style_value_for_length_percentage(layout_node.computed_values().padding().right);
return style_value_for_length_percentage(layout_node.computed_values().padding().right());
case CSS::PropertyID::PaddingTop:
return style_value_for_length_percentage(layout_node.computed_values().padding().top);
return style_value_for_length_percentage(layout_node.computed_values().padding().top());
case CSS::PropertyID::Position:
return IdentifierStyleValue::create(to_value_id(layout_node.computed_values().position()));
case CSS::PropertyID::TextAlign:

View file

@ -81,10 +81,10 @@ Optional<LengthPercentage> StyleProperties::length_percentage(CSS::PropertyID id
LengthBox StyleProperties::length_box(CSS::PropertyID left_id, CSS::PropertyID top_id, CSS::PropertyID right_id, CSS::PropertyID bottom_id, const CSS::Length& default_value) const
{
LengthBox box;
box.left = length_percentage_or_fallback(left_id, default_value);
box.top = length_percentage_or_fallback(top_id, default_value);
box.right = length_percentage_or_fallback(right_id, default_value);
box.bottom = length_percentage_or_fallback(bottom_id, default_value);
box.left() = length_percentage_or_fallback(left_id, default_value);
box.top() = length_percentage_or_fallback(top_id, default_value);
box.right() = length_percentage_or_fallback(right_id, default_value);
box.bottom() = length_percentage_or_fallback(bottom_id, default_value);
return box;
}