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

LibWeb: Convert width/height and min-/max- versions to LengthPercentage

A lot of this is quite ugly, but it should only be so until I remove
Length::Type::Percentage entirely. (Which should happen later in this
PR, otherwise, yell at me!) For now, a lot of things have to be
resolved twice, first from a LengthPercentage to a Length, and then
from a Length to a pixel one.
This commit is contained in:
Sam Atkins 2022-01-19 16:19:43 +00:00 committed by Andreas Kling
parent cb0cce5cdc
commit dc681913e8
12 changed files with 276 additions and 194 deletions

View file

@ -25,6 +25,11 @@ static float get_pixel_size(Box const& box, CSS::LengthPercentage const& length_
.to_px(box);
}
static bool is_undefined_or_auto(CSS::LengthPercentage const& length_percentage)
{
return length_percentage.is_length() && length_percentage.length().is_undefined_or_auto();
}
FlexFormattingContext::FlexFormattingContext(Box& flex_container, FormattingContext* parent)
: FormattingContext(Type::Flex, flex_container, parent)
, m_flex_direction(flex_container.computed_values().flex_direction())
@ -110,17 +115,18 @@ void FlexFormattingContext::run(Box& run_box, LayoutMode)
void FlexFormattingContext::populate_specified_margins(FlexItem& item, CSS::FlexDirection flex_direction) const
{
auto width_of_containing_block = item.box.containing_block()->width();
auto width_of_containing_block_as_length = CSS::Length::make_px(width_of_containing_block);
// FIXME: This should also take reverse-ness into account
if (flex_direction == CSS::FlexDirection::Row || flex_direction == CSS::FlexDirection::RowReverse) {
item.margins.main_before = item.box.computed_values().margin().left.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.main_after = item.box.computed_values().margin().right.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.cross_before = item.box.computed_values().margin().top.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.cross_after = item.box.computed_values().margin().bottom.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.main_before = item.box.computed_values().margin().left.resolved(width_of_containing_block_as_length).resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.main_after = item.box.computed_values().margin().right.resolved(width_of_containing_block_as_length).resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.cross_before = item.box.computed_values().margin().top.resolved(width_of_containing_block_as_length).resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.cross_after = item.box.computed_values().margin().bottom.resolved(width_of_containing_block_as_length).resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
} else {
item.margins.main_before = item.box.computed_values().margin().top.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.main_after = item.box.computed_values().margin().bottom.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.cross_before = item.box.computed_values().margin().left.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.cross_after = item.box.computed_values().margin().right.resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.main_before = item.box.computed_values().margin().top.resolved(width_of_containing_block_as_length).resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.main_after = item.box.computed_values().margin().bottom.resolved(width_of_containing_block_as_length).resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.cross_before = item.box.computed_values().margin().left.resolved(width_of_containing_block_as_length).resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
item.margins.cross_after = item.box.computed_values().margin().right.resolved(width_of_containing_block_as_length).resolved_or_zero(item.box, width_of_containing_block).to_px(item.box);
}
};
@ -136,13 +142,17 @@ void FlexFormattingContext::generate_anonymous_flex_items()
if (!flex_container().has_definite_width()) {
flex_container().set_width(flex_container().containing_block()->width());
} else {
flex_container().set_width(flex_container().computed_values().width().resolved_or_zero(flex_container(), flex_container().containing_block()->width()).to_px(flex_container()));
auto container_width = flex_container().containing_block()->width();
auto width = flex_container().computed_values().width().resolved(CSS::Length::make_px(container_width)).resolved_or_zero(flex_container(), container_width).to_px(flex_container());
flex_container().set_width(width);
}
if (!flex_container().has_definite_height()) {
flex_container().set_height(flex_container().containing_block()->height());
} else {
flex_container().set_height(flex_container().computed_values().height().resolved_or_zero(flex_container(), flex_container().containing_block()->height()).to_px(flex_container()));
auto container_height = flex_container().containing_block()->height();
auto height = flex_container().computed_values().height().resolved(CSS::Length::make_px(container_height)).resolved_or_zero(flex_container(), flex_container().containing_block()->height()).to_px(flex_container());
flex_container().set_height(height);
}
flex_container().for_each_child_of_type<Box>([&](Box& child_box) {
@ -191,13 +201,13 @@ float FlexFormattingContext::specified_cross_size(Box const& box) const
bool FlexFormattingContext::has_main_min_size(Box const& box) const
{
auto value = is_row_layout() ? box.computed_values().min_width() : box.computed_values().min_height();
return !value.is_undefined_or_auto();
return !is_undefined_or_auto(value);
}
bool FlexFormattingContext::has_cross_min_size(Box const& box) const
{
auto value = is_row_layout() ? box.computed_values().min_height() : box.computed_values().min_width();
return !value.is_undefined_or_auto();
return !is_undefined_or_auto(value);
}
bool FlexFormattingContext::has_definite_cross_size(Box const& box) const
@ -207,16 +217,19 @@ bool FlexFormattingContext::has_definite_cross_size(Box const& box) const
bool FlexFormattingContext::cross_size_is_absolute_or_resolved_nicely(NodeWithStyle const& box) const
{
auto length = is_row_layout() ? box.computed_values().height() : box.computed_values().width();
auto length_percentage = is_row_layout() ? box.computed_values().height() : box.computed_values().width();
if (length.is_absolute() || length.is_relative())
return true;
if (length.is_undefined_or_auto())
return false;
if (length_percentage.is_length()) {
auto& length = length_percentage.length();
if (length.is_absolute() || length.is_relative())
return true;
if (length.is_undefined_or_auto())
return false;
}
if (!box.parent())
return false;
if (length.is_percentage() && cross_size_is_absolute_or_resolved_nicely(*box.parent()))
if (length_percentage.is_percentage() && cross_size_is_absolute_or_resolved_nicely(*box.parent()))
return true;
return false;
}
@ -225,7 +238,7 @@ float FlexFormattingContext::specified_main_size_of_child_box(Box const& child_b
{
auto main_size_of_parent = specified_main_size(flex_container());
auto value = is_row_layout() ? child_box.computed_values().width() : child_box.computed_values().height();
return value.resolved_or_zero(child_box, main_size_of_parent).to_px(child_box);
return value.resolved(CSS::Length::make_px(main_size_of_parent)).resolved_or_zero(child_box, main_size_of_parent).to_px(child_box);
}
float FlexFormattingContext::specified_main_min_size(Box const& box) const
@ -245,15 +258,15 @@ float FlexFormattingContext::specified_cross_min_size(Box const& box) const
bool FlexFormattingContext::has_main_max_size(Box const& box) const
{
return is_row_layout()
? !box.computed_values().max_width().is_undefined_or_auto()
: !box.computed_values().max_height().is_undefined_or_auto();
? !is_undefined_or_auto(box.computed_values().max_width())
: !is_undefined_or_auto(box.computed_values().max_height());
}
bool FlexFormattingContext::has_cross_max_size(Box const& box) const
{
return is_row_layout()
? !box.computed_values().max_height().is_undefined_or_auto()
: !box.computed_values().max_width().is_undefined_or_auto();
? !is_undefined_or_auto(box.computed_values().max_height())
: !is_undefined_or_auto(box.computed_values().max_width());
}
float FlexFormattingContext::specified_main_max_size(Box const& box) const
@ -277,17 +290,23 @@ float FlexFormattingContext::calculated_main_size(Box const& box) const
bool FlexFormattingContext::is_cross_auto(Box const& box) const
{
return is_row_layout() ? box.computed_values().height().is_auto() : box.computed_values().width().is_auto();
if (is_row_layout())
return box.computed_values().height().is_length() && box.computed_values().height().length().is_auto();
return box.computed_values().width().is_length() && box.computed_values().width().length().is_auto();
}
bool FlexFormattingContext::is_main_axis_margin_first_auto(Box const& box) const
{
return is_row_layout() ? box.computed_values().margin().left.is_auto() : box.computed_values().margin().top.is_auto();
if (is_row_layout())
return box.computed_values().margin().left.is_length() && box.computed_values().margin().left.length().is_auto();
return box.computed_values().margin().top.is_length() && box.computed_values().margin().top.length().is_auto();
}
bool FlexFormattingContext::is_main_axis_margin_second_auto(Box const& box) const
{
return is_row_layout() ? box.computed_values().margin().right.is_auto() : box.computed_values().margin().bottom.is_auto();
if (is_row_layout())
return box.computed_values().margin().right.is_length() && box.computed_values().margin().right.length().is_auto();
return box.computed_values().margin().bottom.is_length() && box.computed_values().margin().bottom.length().is_auto();
}
void FlexFormattingContext::set_main_size(Box& box, float size)
@ -423,11 +442,11 @@ float FlexFormattingContext::layout_for_maximum_main_size(Box& box)
{
bool main_constrained = false;
if (is_row_layout()) {
if (!box.computed_values().width().is_undefined_or_auto() || !box.computed_values().min_width().is_undefined_or_auto()) {
if (!is_undefined_or_auto(box.computed_values().width()) || !is_undefined_or_auto(box.computed_values().min_width())) {
main_constrained = true;
}
} else {
if (!box.computed_values().height().is_undefined_or_auto() || !box.computed_values().min_height().is_undefined_or_auto()) {
if (!is_undefined_or_auto(box.computed_values().height()) || !is_undefined_or_auto(box.computed_values().min_height())) {
main_constrained = true;
}
}
@ -773,11 +792,11 @@ float FlexFormattingContext::determine_hypothetical_cross_size_of_item(Box& box)
{
bool cross_constrained = false;
if (is_row_layout()) {
if (!box.computed_values().height().is_undefined_or_auto() || !box.computed_values().min_height().is_undefined_or_auto()) {
if (!is_undefined_or_auto(box.computed_values().height()) || !is_undefined_or_auto(box.computed_values().min_height())) {
cross_constrained = true;
}
} else {
if (!box.computed_values().width().is_undefined_or_auto() || !box.computed_values().min_width().is_undefined_or_auto()) {
if (!is_undefined_or_auto(box.computed_values().width()) || !is_undefined_or_auto(box.computed_values().min_width())) {
cross_constrained = true;
}
}