From dd122e2f7401d6f40f6e8d2b1d0c1f14bcbbabfa Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Mon, 1 Sep 2025 12:51:52 +0100 Subject: [PATCH] LibWeb: Make LengthBox hold LengthPercentageOrAuto Not every user of this requires an `auto` state, but most do. This has quite a big diff but most of that is mechanical: LengthPercentageOrAuto has `resolved_or_auto()` instead of `resolved()`, and `to_px_or_zero()` instead of `to_px()`, to make their output clearer. --- Libraries/LibWeb/CSS/CSSStyleProperties.cpp | 37 ++++++--- Libraries/LibWeb/CSS/ComputedProperties.cpp | 6 +- Libraries/LibWeb/CSS/ComputedProperties.h | 3 +- Libraries/LibWeb/CSS/LengthBox.cpp | 19 +++-- Libraries/LibWeb/CSS/LengthBox.h | 29 ++++--- Libraries/LibWeb/CSS/Parser/ValueParsing.cpp | 14 ++-- .../CSS/StyleValues/BasicShapeStyleValue.cpp | 16 ++-- .../LibWeb/Layout/BlockFormattingContext.cpp | 73 +++++++---------- .../LibWeb/Layout/FlexFormattingContext.cpp | 40 ++++----- Libraries/LibWeb/Layout/FormattingContext.cpp | 82 ++++++++----------- .../LibWeb/Layout/GridFormattingContext.cpp | 24 +++--- .../LibWeb/Layout/GridFormattingContext.h | 4 +- .../LibWeb/Layout/InlineFormattingContext.cpp | 16 ++-- .../LibWeb/Layout/InlineLevelIterator.cpp | 16 ++-- Libraries/LibWeb/Layout/LayoutState.cpp | 17 ++-- Libraries/LibWeb/Layout/Node.cpp | 2 +- .../LibWeb/Layout/TableFormattingContext.cpp | 16 ++-- 17 files changed, 199 insertions(+), 215 deletions(-) diff --git a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp index 856080c5ead..afa4db52df6 100644 --- a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp +++ b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp @@ -330,6 +330,17 @@ static NonnullRefPtr style_value_for_length_percentage(LengthP return length_percentage.calculated(); } +static NonnullRefPtr style_value_for_length_percentage_or_auto(LengthPercentageOrAuto const& length_percentage) +{ + if (length_percentage.is_auto()) + return KeywordStyleValue::create(Keyword::Auto); + if (length_percentage.is_percentage()) + return PercentageStyleValue::create(length_percentage.percentage()); + if (length_percentage.is_length()) + return LengthStyleValue::create(length_percentage.length()); + return length_percentage.calculated(); +} + static NonnullRefPtr style_value_for_size(Size const& size) { if (size.is_none()) @@ -517,7 +528,7 @@ RefPtr CSSStyleProperties::style_value_for_computed_property(L auto& element = owner_node()->element(); auto pseudo_element = owner_node()->pseudo_element(); - auto used_value_for_inset = [&layout_node, used_value_for_property](LengthPercentage const& start_side, LengthPercentage const& end_side, Function&& used_value_getter) -> Optional { + auto used_value_for_inset = [&layout_node, used_value_for_property](LengthPercentageOrAuto const& start_side, LengthPercentageOrAuto const& end_side, Function&& used_value_getter) -> Optional { if (!layout_node.is_positioned()) return {}; @@ -630,35 +641,35 @@ RefPtr CSSStyleProperties::style_value_for_computed_property(L case PropertyID::MarginBottom: if (auto maybe_used_value = used_value_for_property([](auto const& paintable_box) { return paintable_box.box_model().margin.bottom; }); maybe_used_value.has_value()) return LengthStyleValue::create(Length::make_px(maybe_used_value.release_value())); - return style_value_for_length_percentage(layout_node.computed_values().margin().bottom()); + return style_value_for_length_percentage_or_auto(layout_node.computed_values().margin().bottom()); case PropertyID::MarginLeft: if (auto maybe_used_value = used_value_for_property([](auto const& paintable_box) { return paintable_box.box_model().margin.left; }); maybe_used_value.has_value()) return LengthStyleValue::create(Length::make_px(maybe_used_value.release_value())); - return style_value_for_length_percentage(layout_node.computed_values().margin().left()); + return style_value_for_length_percentage_or_auto(layout_node.computed_values().margin().left()); case PropertyID::MarginRight: if (auto maybe_used_value = used_value_for_property([](auto const& paintable_box) { return paintable_box.box_model().margin.right; }); maybe_used_value.has_value()) return LengthStyleValue::create(Length::make_px(maybe_used_value.release_value())); - return style_value_for_length_percentage(layout_node.computed_values().margin().right()); + return style_value_for_length_percentage_or_auto(layout_node.computed_values().margin().right()); case PropertyID::MarginTop: if (auto maybe_used_value = used_value_for_property([](auto const& paintable_box) { return paintable_box.box_model().margin.top; }); maybe_used_value.has_value()) return LengthStyleValue::create(Length::make_px(maybe_used_value.release_value())); - return style_value_for_length_percentage(layout_node.computed_values().margin().top()); + return style_value_for_length_percentage_or_auto(layout_node.computed_values().margin().top()); case PropertyID::PaddingBottom: if (auto maybe_used_value = used_value_for_property([](auto const& paintable_box) { return paintable_box.box_model().padding.bottom; }); maybe_used_value.has_value()) return LengthStyleValue::create(Length::make_px(maybe_used_value.release_value())); - return style_value_for_length_percentage(layout_node.computed_values().padding().bottom()); + return style_value_for_length_percentage_or_auto(layout_node.computed_values().padding().bottom()); case PropertyID::PaddingLeft: if (auto maybe_used_value = used_value_for_property([](auto const& paintable_box) { return paintable_box.box_model().padding.left; }); maybe_used_value.has_value()) return LengthStyleValue::create(Length::make_px(maybe_used_value.release_value())); - return style_value_for_length_percentage(layout_node.computed_values().padding().left()); + return style_value_for_length_percentage_or_auto(layout_node.computed_values().padding().left()); case PropertyID::PaddingRight: if (auto maybe_used_value = used_value_for_property([](auto const& paintable_box) { return paintable_box.box_model().padding.right; }); maybe_used_value.has_value()) return LengthStyleValue::create(Length::make_px(maybe_used_value.release_value())); - return style_value_for_length_percentage(layout_node.computed_values().padding().right()); + return style_value_for_length_percentage_or_auto(layout_node.computed_values().padding().right()); case PropertyID::PaddingTop: if (auto maybe_used_value = used_value_for_property([](auto const& paintable_box) { return paintable_box.box_model().padding.top; }); maybe_used_value.has_value()) return LengthStyleValue::create(Length::make_px(maybe_used_value.release_value())); - return style_value_for_length_percentage(layout_node.computed_values().padding().top()); + return style_value_for_length_percentage_or_auto(layout_node.computed_values().padding().top()); case PropertyID::Width: { auto maybe_used_width = used_value_for_property([](auto const& paintable_box) { return paintable_box.content_width(); }); if (maybe_used_width.has_value()) @@ -683,27 +694,27 @@ RefPtr CSSStyleProperties::style_value_for_computed_property(L if (auto maybe_used_value = used_value_for_inset(inset.bottom(), inset.top(), [](auto const& paintable_box) { return paintable_box.box_model().inset.bottom; }); maybe_used_value.has_value()) return LengthStyleValue::create(Length::make_px(maybe_used_value.release_value())); - return style_value_for_length_percentage(inset.bottom()); + return style_value_for_length_percentage_or_auto(inset.bottom()); } case PropertyID::Left: { auto& inset = layout_node.computed_values().inset(); if (auto maybe_used_value = used_value_for_inset(inset.left(), inset.right(), [](auto const& paintable_box) { return paintable_box.box_model().inset.left; }); maybe_used_value.has_value()) return LengthStyleValue::create(Length::make_px(maybe_used_value.release_value())); - return style_value_for_length_percentage(inset.left()); + return style_value_for_length_percentage_or_auto(inset.left()); } case PropertyID::Right: { auto& inset = layout_node.computed_values().inset(); if (auto maybe_used_value = used_value_for_inset(inset.right(), inset.left(), [](auto const& paintable_box) { return paintable_box.box_model().inset.right; }); maybe_used_value.has_value()) return LengthStyleValue::create(Length::make_px(maybe_used_value.release_value())); - return style_value_for_length_percentage(inset.right()); + return style_value_for_length_percentage_or_auto(inset.right()); } case PropertyID::Top: { auto& inset = layout_node.computed_values().inset(); if (auto maybe_used_value = used_value_for_inset(inset.top(), inset.bottom(), [](auto const& paintable_box) { return paintable_box.box_model().inset.top; }); maybe_used_value.has_value()) return LengthStyleValue::create(Length::make_px(maybe_used_value.release_value())); - return style_value_for_length_percentage(inset.top()); + return style_value_for_length_percentage_or_auto(inset.top()); } // -> A resolved value special case property defined in another specification diff --git a/Libraries/LibWeb/CSS/ComputedProperties.cpp b/Libraries/LibWeb/CSS/ComputedProperties.cpp index 9ed0fbecab4..d3c8db89e1b 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.cpp +++ b/Libraries/LibWeb/CSS/ComputedProperties.cpp @@ -261,9 +261,9 @@ Length ComputedProperties::length(PropertyID property_id) const return property(property_id).as_length().length(); } -LengthBox ComputedProperties::length_box(PropertyID left_id, PropertyID top_id, PropertyID right_id, PropertyID bottom_id, Layout::NodeWithStyle const& layout_node, ClampNegativeLengths disallow_negative_lengths, Length const& default_value) const +LengthBox ComputedProperties::length_box(PropertyID left_id, PropertyID top_id, PropertyID right_id, PropertyID bottom_id, Layout::NodeWithStyle const& layout_node, ClampNegativeLengths disallow_negative_lengths, LengthPercentageOrAuto const& default_value) const { - auto length_box_side = [&](PropertyID id) -> LengthPercentage { + auto length_box_side = [&](PropertyID id) -> LengthPercentageOrAuto { auto const& value = property(id); if (value.is_calculated()) @@ -292,7 +292,7 @@ LengthBox ComputedProperties::length_box(PropertyID left_id, PropertyID top_id, } if (value.has_auto()) - return LengthPercentage { Length::make_auto() }; + return LengthPercentageOrAuto::make_auto(); return default_value; }; diff --git a/Libraries/LibWeb/CSS/ComputedProperties.h b/Libraries/LibWeb/CSS/ComputedProperties.h index c4d43f23209..042f3649ca2 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.h +++ b/Libraries/LibWeb/CSS/ComputedProperties.h @@ -77,13 +77,12 @@ public: Size size_value(PropertyID) const; [[nodiscard]] Variant gap_value(PropertyID) const; Length length(PropertyID) const; - LengthBox length_box(PropertyID left_id, PropertyID top_id, PropertyID right_id, PropertyID bottom_id, Length const& default_value) const; enum class ClampNegativeLengths { No, Yes, }; Optional length_percentage(PropertyID, Layout::NodeWithStyle const&, ClampNegativeLengths) const; - LengthBox length_box(PropertyID left_id, PropertyID top_id, PropertyID right_id, PropertyID bottom_id, Layout::NodeWithStyle const&, ClampNegativeLengths, Length const& default_value) const; + LengthBox length_box(PropertyID left_id, PropertyID top_id, PropertyID right_id, PropertyID bottom_id, Layout::NodeWithStyle const&, ClampNegativeLengths, LengthPercentageOrAuto const& default_value) const; Color color_or_fallback(PropertyID, ColorResolutionContext, Color fallback) const; ColorInterpolation color_interpolation() const; PreferredColorScheme color_scheme(PreferredColorScheme, Optional const&> document_supported_schemes) const; diff --git a/Libraries/LibWeb/CSS/LengthBox.cpp b/Libraries/LibWeb/CSS/LengthBox.cpp index 776193f440d..15a44a092ad 100644 --- a/Libraries/LibWeb/CSS/LengthBox.cpp +++ b/Libraries/LibWeb/CSS/LengthBox.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2022, Ben Wiederhake + * Copyright (c) 2025, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ @@ -10,18 +11,18 @@ 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()) + : m_top(LengthPercentageOrAuto::make_auto()) + , m_right(LengthPercentageOrAuto::make_auto()) + , m_bottom(LengthPercentageOrAuto::make_auto()) + , m_left(LengthPercentageOrAuto::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(LengthPercentageOrAuto top, LengthPercentageOrAuto right, LengthPercentageOrAuto bottom, LengthPercentageOrAuto left) + : m_top(move(top)) + , m_right(move(right)) + , m_bottom(move(bottom)) + , m_left(move(left)) { } diff --git a/Libraries/LibWeb/CSS/LengthBox.h b/Libraries/LibWeb/CSS/LengthBox.h index 36df706830e..77a5fb2d4ca 100644 --- a/Libraries/LibWeb/CSS/LengthBox.h +++ b/Libraries/LibWeb/CSS/LengthBox.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2025, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ @@ -13,27 +14,25 @@ namespace Web::CSS { class LengthBox { public: LengthBox(); - LengthBox(LengthPercentage top, LengthPercentage right, LengthPercentage bottom, LengthPercentage left); + LengthBox(LengthPercentageOrAuto top, LengthPercentageOrAuto right, LengthPercentageOrAuto bottom, LengthPercentageOrAuto left); ~LengthBox(); - // Length (and thus LengthPercentage) includes a RefPtr 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; } + LengthPercentageOrAuto& top() { return m_top; } + LengthPercentageOrAuto& right() { return m_right; } + LengthPercentageOrAuto& bottom() { return m_bottom; } + LengthPercentageOrAuto& left() { return m_left; } + LengthPercentageOrAuto const& top() const { return m_top; } + LengthPercentageOrAuto const& right() const { return m_right; } + LengthPercentageOrAuto const& bottom() const { return m_bottom; } + LengthPercentageOrAuto const& left() const { return m_left; } bool operator==(LengthBox const&) const = default; private: - LengthPercentage m_top; - LengthPercentage m_right; - LengthPercentage m_bottom; - LengthPercentage m_left; + LengthPercentageOrAuto m_top; + LengthPercentageOrAuto m_right; + LengthPercentageOrAuto m_bottom; + LengthPercentageOrAuto m_left; }; } diff --git a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp index b911ed03dc6..31d8ae66020 100644 --- a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp @@ -3310,15 +3310,13 @@ RefPtr Parser::parse_basic_shape_value(TokenStream& tokens) -> Optional { + auto parse_length_percentage_or_auto = [this](TokenStream& tokens) -> Optional { tokens.discard_whitespace(); - auto value = parse_length_percentage(tokens); - if (!value.has_value()) { - if (tokens.consume_a_token().is_ident("auto"sv)) { - value = Length::make_auto(); - } - } - return value; + if (auto value = parse_length_percentage(tokens); value.has_value()) + return value.release_value(); + if (tokens.consume_a_token().is_ident("auto"sv)) + return LengthPercentageOrAuto::make_auto(); + return {}; }; auto top = parse_length_percentage_or_auto(arguments_tokens); diff --git a/Libraries/LibWeb/CSS/StyleValues/BasicShapeStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/BasicShapeStyleValue.cpp index abb6d48c766..97614de585a 100644 --- a/Libraries/LibWeb/CSS/StyleValues/BasicShapeStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/BasicShapeStyleValue.cpp @@ -29,10 +29,10 @@ Gfx::Path Inset::to_path(CSSPixelRect reference_box, Layout::Node const& node) c // (such as left and right insets of 75% apiece) use the CSS Backgrounds 3 § 4.5 Overlapping Curves rules // to proportionally reduce the inset effect to 100%. - auto top = inset_box.top().to_px(node, reference_box.height()).to_float(); - auto right = reference_box.width().to_float() - inset_box.right().to_px(node, reference_box.width()).to_float(); - auto bottom = reference_box.height().to_float() - inset_box.bottom().to_px(node, reference_box.height()).to_float(); - auto left = inset_box.left().to_px(node, reference_box.width()).to_float(); + auto top = inset_box.top().to_px_or_zero(node, reference_box.height()).to_float(); + auto right = reference_box.width().to_float() - inset_box.right().to_px_or_zero(node, reference_box.width()).to_float(); + auto bottom = reference_box.height().to_float() - inset_box.bottom().to_px_or_zero(node, reference_box.height()).to_float(); + auto left = inset_box.left().to_px_or_zero(node, reference_box.width()).to_float(); return path_from_resolved_rect(top, right, bottom, left); } @@ -62,10 +62,10 @@ Gfx::Path Rect::to_path(CSSPixelRect reference_box, Layout::Node const& node) co // An auto value makes the edge of the box coincide with the corresponding edge of the reference box: // it’s equivalent to 0% as the first (top) or fourth (left) value, and equivalent to 100% as the second (right) or third (bottom) value. - auto top = box.top().is_auto() ? 0 : box.top().to_px(node, reference_box.height()).to_float(); - auto right = box.right().is_auto() ? reference_box.width().to_float() : box.right().to_px(node, reference_box.width()).to_float(); - auto bottom = box.bottom().is_auto() ? reference_box.height().to_float() : box.bottom().to_px(node, reference_box.height()).to_float(); - auto left = box.left().is_auto() ? 0 : box.left().to_px(node, reference_box.width()).to_float(); + auto top = box.top().is_auto() ? 0 : box.top().to_px_or_zero(node, reference_box.height()).to_float(); + auto right = box.right().is_auto() ? reference_box.width().to_float() : box.right().to_px_or_zero(node, reference_box.width()).to_float(); + auto bottom = box.bottom().is_auto() ? reference_box.height().to_float() : box.bottom().to_px_or_zero(node, reference_box.height()).to_float(); + auto left = box.left().is_auto() ? 0 : box.left().to_px_or_zero(node, reference_box.width()).to_float(); // The second (right) and third (bottom) values are floored by the fourth (left) and second (top) values, respectively. return path_from_resolved_rect(top, max(right, left), max(bottom, top), left); diff --git a/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Libraries/LibWeb/Layout/BlockFormattingContext.cpp index f65c5f1a468..a8b3271f75a 100644 --- a/Libraries/LibWeb/Layout/BlockFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/BlockFormattingContext.cpp @@ -208,18 +208,18 @@ void BlockFormattingContext::compute_width(Box const& box, AvailableSpace const& auto const& computed_values = box.computed_values(); auto available_width_px = available_space.width.to_px_or_zero(); - auto margin_left = computed_values.margin().left().resolved(box, available_width_px); - auto margin_right = computed_values.margin().right().resolved(box, available_width_px); - auto const padding_left = computed_values.padding().left().resolved(box, available_width_px); - auto const padding_right = computed_values.padding().right().resolved(box, available_width_px); + auto margin_left = computed_values.margin().left().resolved_or_auto(box, available_width_px); + auto margin_right = computed_values.margin().right().resolved_or_auto(box, available_width_px); + auto const padding_left = computed_values.padding().left().resolved_or_auto(box, available_width_px); + auto const padding_right = computed_values.padding().right().resolved_or_auto(box, available_width_px); auto& box_state = m_state.get_mutable(box); - box_state.margin_left = margin_left.to_px(box); - box_state.margin_right = margin_right.to_px(box); + box_state.margin_left = margin_left.to_px_or_zero(box); + box_state.margin_right = margin_right.to_px_or_zero(box); box_state.border_left = computed_values.border_left().width; box_state.border_right = computed_values.border_right().width; - box_state.padding_left = padding_left.to_px(box); - box_state.padding_right = padding_right.to_px(box); + box_state.padding_left = padding_left.to_px_or_zero(box); + box_state.padding_right = padding_right.to_px_or_zero(box); // https://html.spec.whatwg.org/multipage/rendering.html#button-layout // If the computed value of 'inline-size' is 'auto', then the used value is the fit-content inline size. @@ -240,8 +240,8 @@ void BlockFormattingContext::compute_width(Box const& box, AvailableSpace const& auto try_compute_width = [&](CSS::LengthOrAuto const& a_width) { auto width = a_width; - margin_left = computed_values.margin().left().resolved(box, available_space.width.to_px_or_zero()); - margin_right = computed_values.margin().right().resolved(box, available_space.width.to_px_or_zero()); + margin_left = computed_values.margin().left().resolved_or_auto(box, available_space.width.to_px_or_zero()); + margin_right = computed_values.margin().right().resolved_or_auto(box, available_space.width.to_px_or_zero()); CSSPixels total_px = computed_values.border_left().width + computed_values.border_right().width; for (auto& value : { CSS::LengthOrAuto(margin_left), CSS::LengthOrAuto(padding_left), width, CSS::LengthOrAuto(padding_right), CSS::LengthOrAuto(margin_right) }) total_px += value.to_px_or_zero(box); @@ -285,7 +285,7 @@ void BlockFormattingContext::compute_width(Box const& box, AvailableSpace const& } } else { if (!margin_left.is_auto() && !margin_right.is_auto()) { - margin_right = CSS::Length::make_px(margin_right.to_px(box) + underflow_px); + margin_right = CSS::Length::make_px(margin_right.to_px_or_zero(box) + underflow_px); } else if (!margin_left.is_auto() && margin_right.is_auto()) { margin_right = CSS::Length::make_px(underflow_px); } else if (margin_left.is_auto() && !margin_right.is_auto()) { @@ -337,8 +337,8 @@ void BlockFormattingContext::compute_width(Box const& box, AvailableSpace const& if (!box_is_sized_as_replaced_element(box, available_space) && !used_width.is_auto()) box_state.set_content_width(used_width.to_px_or_zero(box)); - box_state.margin_left = margin_left.to_px(box); - box_state.margin_right = margin_right.to_px(box); + box_state.margin_left = margin_left.to_px_or_zero(box); + box_state.margin_right = margin_right.to_px_or_zero(box); } void BlockFormattingContext::avoid_float_intrusions(Box const& box, AvailableSpace const& available_space) @@ -388,20 +388,15 @@ void BlockFormattingContext::compute_width_for_floating_box(Box const& box, Avai auto zero_value = CSS::Length::make_px(0); auto width_of_containing_block = available_space.width.to_px_or_zero(); - auto margin_left = computed_values.margin().left().resolved(box, width_of_containing_block); - auto margin_right = computed_values.margin().right().resolved(box, width_of_containing_block); - // If 'margin-left', or 'margin-right' are computed as 'auto', their used value is '0'. - if (margin_left.is_auto()) - margin_left = zero_value; - if (margin_right.is_auto()) - margin_right = zero_value; + auto margin_left = computed_values.margin().left().to_px_or_zero(box, width_of_containing_block); + auto margin_right = computed_values.margin().right().to_px_or_zero(box, width_of_containing_block); auto& box_state = m_state.get_mutable(box); - box_state.padding_left = computed_values.padding().left().resolved(box, width_of_containing_block).to_px(box); - box_state.padding_right = computed_values.padding().right().resolved(box, width_of_containing_block).to_px(box); - box_state.margin_left = margin_left.to_px(box); - box_state.margin_right = margin_right.to_px(box); + box_state.padding_left = computed_values.padding().left().to_px_or_zero(box, width_of_containing_block); + box_state.padding_right = computed_values.padding().right().to_px_or_zero(box, width_of_containing_block); + box_state.margin_left = margin_left; + box_state.margin_right = margin_right; box_state.border_left = computed_values.border_left().width; box_state.border_right = computed_values.border_right().width; @@ -415,8 +410,8 @@ void BlockFormattingContext::compute_width_for_floating_box(Box const& box, Avai // block minus the used values of 'margin-left', 'border-left-width', 'padding-left', // 'padding-right', 'border-right-width', 'margin-right', and the widths of any relevant scroll bars. auto available_width = available_space.width.to_px_or_zero() - - margin_left.to_px(box) - computed_values.border_left().width - box_state.padding_left - - box_state.padding_right - computed_values.border_right().width - margin_right.to_px(box); + - margin_left - computed_values.border_left().width - box_state.padding_left + - box_state.padding_right - computed_values.border_right().width - margin_right; // Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width). width = CSS::Length::make_px(min(max(result.preferred_minimum_width, available_width), result.preferred_width)); } else if (available_space.width.is_indefinite() || available_space.width.is_max_content()) { @@ -464,27 +459,21 @@ void BlockFormattingContext::compute_width_for_block_level_replaced_element_in_n // 10.3.6 Floating, replaced elements auto& computed_values = box.computed_values(); - auto zero_value = CSS::Length::make_px(0); auto width_of_containing_block = available_space.width.to_px_or_zero(); // 10.3.4 Block-level, replaced elements in normal flow // The used value of 'width' is determined as for inline replaced elements. Then the rules for // non-replaced block-level elements are applied to determine the margins. - auto margin_left = computed_values.margin().left().resolved(box, width_of_containing_block); - auto margin_right = computed_values.margin().right().resolved(box, width_of_containing_block); - auto const padding_left = computed_values.padding().left().resolved(box, width_of_containing_block).to_px(box); - auto const padding_right = computed_values.padding().right().resolved(box, width_of_containing_block).to_px(box); - // If 'margin-left', or 'margin-right' are computed as 'auto', their used value is '0'. - if (margin_left.is_auto()) - margin_left = zero_value; - if (margin_right.is_auto()) - margin_right = zero_value; + auto margin_left = computed_values.margin().left().to_px_or_zero(box, width_of_containing_block); + auto margin_right = computed_values.margin().right().to_px_or_zero(box, width_of_containing_block); + auto const padding_left = computed_values.padding().left().to_px_or_zero(box, width_of_containing_block); + auto const padding_right = computed_values.padding().right().to_px_or_zero(box, width_of_containing_block); auto& box_state = m_state.get_mutable(box); auto width = compute_width_for_replaced_element(box, available_space); - box_state.margin_left = margin_left.to_px(box); - box_state.margin_right = margin_right.to_px(box); + box_state.margin_left = margin_left; + box_state.margin_right = margin_right; box_state.border_left = computed_values.border_left().width; box_state.border_right = computed_values.border_right().width; box_state.padding_left = padding_left; @@ -936,12 +925,12 @@ void BlockFormattingContext::resolve_vertical_box_model_metrics(Box const& box, auto& box_state = m_state.get_mutable(box); auto const& computed_values = box.computed_values(); - box_state.margin_top = computed_values.margin().top().to_px(box, width_of_containing_block); - box_state.margin_bottom = computed_values.margin().bottom().to_px(box, width_of_containing_block); + box_state.margin_top = computed_values.margin().top().to_px_or_zero(box, width_of_containing_block); + box_state.margin_bottom = computed_values.margin().bottom().to_px_or_zero(box, width_of_containing_block); box_state.border_top = computed_values.border_top().width; box_state.border_bottom = computed_values.border_bottom().width; - box_state.padding_top = computed_values.padding().top().to_px(box, width_of_containing_block); - box_state.padding_bottom = computed_values.padding().bottom().to_px(box, width_of_containing_block); + box_state.padding_top = computed_values.padding().top().to_px_or_zero(box, width_of_containing_block); + box_state.padding_bottom = computed_values.padding().bottom().to_px_or_zero(box, width_of_containing_block); } CSSPixels BlockFormattingContext::BlockMarginState::current_collapsed_margin() const diff --git a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 6f283a2d81a..400c9081c34 100644 --- a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -243,10 +243,10 @@ void FlexFormattingContext::populate_specified_margins(FlexItem& item, CSS::Flex { auto width_of_containing_block = m_flex_container_state.content_width(); - item.used_values.padding_left = item.box->computed_values().padding().left().to_px(item.box, width_of_containing_block); - item.used_values.padding_right = item.box->computed_values().padding().right().to_px(item.box, width_of_containing_block); - item.used_values.padding_top = item.box->computed_values().padding().top().to_px(item.box, width_of_containing_block); - item.used_values.padding_bottom = item.box->computed_values().padding().bottom().to_px(item.box, width_of_containing_block); + item.used_values.padding_left = item.box->computed_values().padding().left().to_px_or_zero(item.box, width_of_containing_block); + item.used_values.padding_right = item.box->computed_values().padding().right().to_px_or_zero(item.box, width_of_containing_block); + item.used_values.padding_top = item.box->computed_values().padding().top().to_px_or_zero(item.box, width_of_containing_block); + item.used_values.padding_bottom = item.box->computed_values().padding().bottom().to_px_or_zero(item.box, width_of_containing_block); // FIXME: This should also take reverse-ness into account if (flex_direction == CSS::FlexDirection::Row || flex_direction == CSS::FlexDirection::RowReverse) { @@ -255,15 +255,15 @@ void FlexFormattingContext::populate_specified_margins(FlexItem& item, CSS::Flex item.borders.cross_before = item.box->computed_values().border_top().width; item.borders.cross_after = item.box->computed_values().border_bottom().width; - item.padding.main_before = item.box->computed_values().padding().left().to_px(item.box, width_of_containing_block); - item.padding.main_after = item.box->computed_values().padding().right().to_px(item.box, width_of_containing_block); - item.padding.cross_before = item.box->computed_values().padding().top().to_px(item.box, width_of_containing_block); - item.padding.cross_after = item.box->computed_values().padding().bottom().to_px(item.box, width_of_containing_block); + item.padding.main_before = item.box->computed_values().padding().left().to_px_or_zero(item.box, width_of_containing_block); + item.padding.main_after = item.box->computed_values().padding().right().to_px_or_zero(item.box, width_of_containing_block); + item.padding.cross_before = item.box->computed_values().padding().top().to_px_or_zero(item.box, width_of_containing_block); + item.padding.cross_after = item.box->computed_values().padding().bottom().to_px_or_zero(item.box, width_of_containing_block); - item.margins.main_before = item.box->computed_values().margin().left().to_px(item.box, width_of_containing_block); - item.margins.main_after = item.box->computed_values().margin().right().to_px(item.box, width_of_containing_block); - item.margins.cross_before = item.box->computed_values().margin().top().to_px(item.box, width_of_containing_block); - item.margins.cross_after = item.box->computed_values().margin().bottom().to_px(item.box, width_of_containing_block); + item.margins.main_before = item.box->computed_values().margin().left().to_px_or_zero(item.box, width_of_containing_block); + item.margins.main_after = item.box->computed_values().margin().right().to_px_or_zero(item.box, width_of_containing_block); + item.margins.cross_before = item.box->computed_values().margin().top().to_px_or_zero(item.box, width_of_containing_block); + item.margins.cross_after = item.box->computed_values().margin().bottom().to_px_or_zero(item.box, width_of_containing_block); item.margins.main_before_is_auto = item.box->computed_values().margin().left().is_auto(); item.margins.main_after_is_auto = item.box->computed_values().margin().right().is_auto(); @@ -280,10 +280,10 @@ void FlexFormattingContext::populate_specified_margins(FlexItem& item, CSS::Flex item.padding.cross_before = item.used_values.padding_left; item.padding.cross_after = item.used_values.padding_right; - item.margins.main_before = item.box->computed_values().margin().top().to_px(item.box, width_of_containing_block); - item.margins.main_after = item.box->computed_values().margin().bottom().to_px(item.box, width_of_containing_block); - item.margins.cross_before = item.box->computed_values().margin().left().to_px(item.box, width_of_containing_block); - item.margins.cross_after = item.box->computed_values().margin().right().to_px(item.box, width_of_containing_block); + item.margins.main_before = item.box->computed_values().margin().top().to_px_or_zero(item.box, width_of_containing_block); + item.margins.main_after = item.box->computed_values().margin().bottom().to_px_or_zero(item.box, width_of_containing_block); + item.margins.cross_before = item.box->computed_values().margin().left().to_px_or_zero(item.box, width_of_containing_block); + item.margins.cross_after = item.box->computed_values().margin().right().to_px_or_zero(item.box, width_of_containing_block); item.margins.main_before_is_auto = item.box->computed_values().margin().top().is_auto(); item.margins.main_after_is_auto = item.box->computed_values().margin().bottom().is_auto(); @@ -1693,10 +1693,10 @@ void FlexFormattingContext::copy_dimensions_from_flex_items_to_boxes() for (auto& item : m_flex_items) { auto const& box = item.box; - item.used_values.margin_left = box->computed_values().margin().left().to_px(box, m_flex_container_state.content_width()); - item.used_values.margin_right = box->computed_values().margin().right().to_px(box, m_flex_container_state.content_width()); - item.used_values.margin_top = box->computed_values().margin().top().to_px(box, m_flex_container_state.content_width()); - item.used_values.margin_bottom = box->computed_values().margin().bottom().to_px(box, m_flex_container_state.content_width()); + item.used_values.margin_left = box->computed_values().margin().left().to_px_or_zero(box, m_flex_container_state.content_width()); + item.used_values.margin_right = box->computed_values().margin().right().to_px_or_zero(box, m_flex_container_state.content_width()); + item.used_values.margin_top = box->computed_values().margin().top().to_px_or_zero(box, m_flex_container_state.content_width()); + item.used_values.margin_bottom = box->computed_values().margin().bottom().to_px_or_zero(box, m_flex_container_state.content_width()); item.used_values.border_left = box->computed_values().border_left().width; item.used_values.border_right = box->computed_values().border_right().width; diff --git a/Libraries/LibWeb/Layout/FormattingContext.cpp b/Libraries/LibWeb/Layout/FormattingContext.cpp index 1635ca2f24b..204aee1882b 100644 --- a/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -416,17 +416,12 @@ CSSPixels FormattingContext::compute_table_box_width_inside_table_wrapper(Box co auto zero_value = CSS::Length::make_px(0); - auto margin_left = computed_values.margin().left().resolved(box, width_of_containing_block); - auto margin_right = computed_values.margin().right().resolved(box, width_of_containing_block); - // If 'margin-left', or 'margin-right' are computed as 'auto', their used value is '0'. - if (margin_left.is_auto()) - margin_left = zero_value; - if (margin_right.is_auto()) - margin_right = zero_value; + auto margin_left = computed_values.margin().left().to_px_or_zero(box, width_of_containing_block); + auto margin_right = computed_values.margin().right().to_px_or_zero(box, width_of_containing_block); // table-wrapper can't have borders or paddings but it might have margin taken from table-root. - auto available_width = width_of_containing_block - margin_left.to_px(box) - margin_right.to_px(box); + auto available_width = width_of_containing_block - margin_left - margin_right; Optional table_box; box.for_each_in_subtree_of_type([&](Box const& child_box) { @@ -463,19 +458,12 @@ CSSPixels FormattingContext::compute_table_box_height_inside_table_wrapper(Box c auto width_of_containing_block = available_space.width.to_px_or_zero(); auto height_of_containing_block = available_space.height.to_px_or_zero(); - auto zero_value = CSS::Length::make_px(0); - - auto margin_top = computed_values.margin().top().resolved(box, width_of_containing_block); - auto margin_bottom = computed_values.margin().bottom().resolved(box, width_of_containing_block); - - // If 'margin-top', or 'margin-top' are computed as 'auto', their used value is '0'. - if (margin_top.is_auto()) - margin_top = zero_value; - if (margin_bottom.is_auto()) - margin_bottom = zero_value; + // If 'margin-top', or 'margin-bottom' are computed as 'auto', their used value is '0'. + auto margin_top = computed_values.margin().top().resolved_or_auto(box, width_of_containing_block).to_px_or_zero(box); + auto margin_bottom = computed_values.margin().bottom().resolved_or_auto(box, width_of_containing_block).to_px_or_zero(box); // table-wrapper can't have borders or paddings but it might have margin taken from table-root. - auto available_height = height_of_containing_block - margin_top.to_px(box) - margin_bottom.to_px(box); + auto available_height = height_of_containing_block - margin_top - margin_bottom; LayoutState throwaway_state; @@ -699,12 +687,12 @@ void FormattingContext::compute_width_for_absolutely_positioned_non_replaced_ele auto computed_left = computed_values.inset().left(); auto computed_right = computed_values.inset().right(); - auto left = computed_values.inset().left().to_px(box, width_of_containing_block); - auto right = computed_values.inset().right().to_px(box, width_of_containing_block); + auto left = computed_values.inset().left().to_px_or_zero(box, width_of_containing_block); + auto right = computed_values.inset().right().to_px_or_zero(box, width_of_containing_block); auto try_compute_width = [&](CSS::LengthOrAuto const& a_width) { - margin_left = computed_values.margin().left().resolved(box, width_of_containing_block); - margin_right = computed_values.margin().right().resolved(box, width_of_containing_block); + margin_left = computed_values.margin().left().resolved_or_auto(box, width_of_containing_block); + margin_right = computed_values.margin().right().resolved_or_auto(box, width_of_containing_block); auto width = a_width; @@ -886,8 +874,8 @@ void FormattingContext::compute_width_for_absolutely_positioned_replaced_element auto margin_right = computed_values.margin().right(); auto static_position = m_state.get(box).static_position(); - auto to_px = [&](CSS::LengthPercentage const& l) { - return l.to_px(box, width_of_containing_block); + auto to_px = [&](CSS::LengthPercentageOrAuto const& l) { + return l.to_px_or_zero(box, width_of_containing_block); }; // If 'margin-left' or 'margin-right' is specified as 'auto' its used value is determined by the rules below. @@ -993,15 +981,15 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el auto try_compute_height = [&](CSS::LengthOrAuto height) -> CSS::LengthOrAuto { auto solve_for = [&](CSS::LengthOrAuto const& length_or_auto, ClampToZero clamp_to_zero = ClampToZero::No) { auto unclamped_value = height_of_containing_block - - top.to_px(box, height_of_containing_block) - - margin_top.to_px(box, width_of_containing_block) + - top.to_px_or_zero(box, height_of_containing_block) + - margin_top.to_px_or_zero(box, width_of_containing_block) - box.computed_values().border_top().width - state.padding_top - apply_min_max_height_constraints(height).to_px_or_zero(box) - state.padding_bottom - box.computed_values().border_bottom().width - - margin_bottom.to_px(box, width_of_containing_block) - - bottom.to_px(box, height_of_containing_block) + - margin_bottom.to_px_or_zero(box, width_of_containing_block) + - bottom.to_px_or_zero(box, height_of_containing_block) + length_or_auto.to_px_or_zero(box); if (clamp_to_zero == ClampToZero::Yes) return CSS::Length::make_px(max(CSSPixels(0), unclamped_value)); @@ -1009,11 +997,11 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el }; auto solve_for_top = [&] { - top = solve_for(top.resolved(box, height_of_containing_block)); + top = solve_for(top.resolved_or_auto(box, height_of_containing_block)); }; auto solve_for_bottom = [&] { - bottom = solve_for(bottom.resolved(box, height_of_containing_block)); + bottom = solve_for(bottom.resolved_or_auto(box, height_of_containing_block)); }; auto solve_for_height = [&] { @@ -1021,15 +1009,15 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el }; auto solve_for_margin_top = [&] { - margin_top = solve_for(margin_top.resolved(box, width_of_containing_block)); + margin_top = solve_for(margin_top.resolved_or_auto(box, width_of_containing_block)); }; auto solve_for_margin_bottom = [&] { - margin_bottom = solve_for(margin_bottom.resolved(box, width_of_containing_block)); + margin_bottom = solve_for(margin_bottom.resolved_or_auto(box, width_of_containing_block)); }; auto solve_for_margin_top_and_margin_bottom = [&] { - auto remainder = solve_for(CSS::Length::make_px(margin_top.to_px(box, width_of_containing_block) + margin_bottom.to_px(box, width_of_containing_block))).to_px(box); + auto remainder = solve_for(CSS::Length::make_px(margin_top.to_px_or_zero(box, width_of_containing_block) + margin_bottom.to_px_or_zero(box, width_of_containing_block))).to_px(box); margin_top = CSS::Length::make_px(remainder / 2); margin_bottom = CSS::Length::make_px(remainder / 2); }; @@ -1173,10 +1161,10 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el if (box.computed_values().height().is_auto() && before_or_after_inside_layout == BeforeOrAfterInsideLayout::Before) return; box_state.set_has_definite_height(true); - box_state.inset_top = top.to_px(box, height_of_containing_block); - box_state.inset_bottom = bottom.to_px(box, height_of_containing_block); - box_state.margin_top = margin_top.to_px(box, width_of_containing_block); - box_state.margin_bottom = margin_bottom.to_px(box, width_of_containing_block); + box_state.inset_top = top.to_px_or_zero(box, height_of_containing_block); + box_state.inset_bottom = bottom.to_px_or_zero(box, height_of_containing_block); + box_state.margin_top = margin_top.to_px_or_zero(box, width_of_containing_block); + box_state.margin_bottom = margin_bottom.to_px_or_zero(box, width_of_containing_block); } CSSPixelRect FormattingContext::content_box_rect_in_static_position_ancestor_coordinate_space(Box const& box, Box const& ancestor_box) const @@ -1217,10 +1205,10 @@ void FormattingContext::layout_absolutely_positioned_element(Box const& box, Ava box_state.border_bottom = box.computed_values().border_bottom().width; auto const containing_block_width = available_space.width.to_px_or_zero(); - box_state.padding_left = box.computed_values().padding().left().to_px(box, containing_block_width); - box_state.padding_right = box.computed_values().padding().right().to_px(box, containing_block_width); - box_state.padding_top = box.computed_values().padding().top().to_px(box, containing_block_width); - box_state.padding_bottom = box.computed_values().padding().bottom().to_px(box, containing_block_width); + box_state.padding_left = box.computed_values().padding().left().to_px_or_zero(box, containing_block_width); + box_state.padding_right = box.computed_values().padding().right().to_px_or_zero(box, containing_block_width); + box_state.padding_top = box.computed_values().padding().top().to_px_or_zero(box, containing_block_width); + box_state.padding_bottom = box.computed_values().padding().bottom().to_px_or_zero(box, containing_block_width); compute_width_for_absolutely_positioned_element(box, available_space); @@ -1305,8 +1293,8 @@ void FormattingContext::compute_height_for_absolutely_positioned_replaced_elemen auto margin_bottom = computed_values.margin().bottom(); auto static_position = m_state.get(box).static_position(); - auto to_px = [&](CSS::LengthPercentage const& l) { - return l.to_px(box, height_of_containing_block); + auto to_px = [&](CSS::LengthPercentageOrAuto const& l) { + return l.to_px_or_zero(box, height_of_containing_block); }; // If 'margin-top' or 'margin-bottom' is specified as 'auto' its used value is determined by the rules below. @@ -1366,9 +1354,9 @@ void FormattingContext::compute_inset(NodeWithStyleAndBoxModelMetrics const& box if (box.computed_values().position() != CSS::Positioning::Relative) return; - auto resolve_two_opposing_insets = [&](CSS::LengthPercentage const& computed_first, CSS::LengthPercentage const& computed_second, CSSPixels& used_start, CSSPixels& used_end, CSSPixels reference_for_percentage) { - auto resolved_first = computed_first.to_px(box, reference_for_percentage); - auto resolved_second = computed_second.to_px(box, reference_for_percentage); + auto resolve_two_opposing_insets = [&](CSS::LengthPercentageOrAuto const& computed_first, CSS::LengthPercentageOrAuto const& computed_second, CSSPixels& used_start, CSSPixels& used_end, CSSPixels reference_for_percentage) { + auto resolved_first = computed_first.to_px_or_zero(box, reference_for_percentage); + auto resolved_second = computed_second.to_px_or_zero(box, reference_for_percentage); if (computed_first.is_auto() && computed_second.is_auto()) { // If opposing inset properties in an axis both compute to auto (their initial values), diff --git a/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Libraries/LibWeb/Layout/GridFormattingContext.cpp index 7fb13a87bc1..0073f83c00e 100644 --- a/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -1819,20 +1819,20 @@ void GridFormattingContext::resolve_items_box_metrics(GridDimension dimension) CSSPixels containing_block_width = containing_block_size_for_item(item, GridDimension::Column); if (dimension == GridDimension::Column) { - item.used_values.padding_right = computed_values.padding().right().to_px(grid_container(), containing_block_width); - item.used_values.padding_left = computed_values.padding().left().to_px(grid_container(), containing_block_width); + item.used_values.padding_right = computed_values.padding().right().to_px_or_zero(grid_container(), containing_block_width); + item.used_values.padding_left = computed_values.padding().left().to_px_or_zero(grid_container(), containing_block_width); - item.used_values.margin_right = computed_values.margin().right().to_px(grid_container(), containing_block_width); - item.used_values.margin_left = computed_values.margin().left().to_px(grid_container(), containing_block_width); + item.used_values.margin_right = computed_values.margin().right().to_px_or_zero(grid_container(), containing_block_width); + item.used_values.margin_left = computed_values.margin().left().to_px_or_zero(grid_container(), containing_block_width); item.used_values.border_right = computed_values.border_right().width; item.used_values.border_left = computed_values.border_left().width; } else { - item.used_values.padding_top = computed_values.padding().top().to_px(grid_container(), containing_block_width); - item.used_values.padding_bottom = computed_values.padding().bottom().to_px(grid_container(), containing_block_width); + item.used_values.padding_top = computed_values.padding().top().to_px_or_zero(grid_container(), containing_block_width); + item.used_values.padding_bottom = computed_values.padding().bottom().to_px_or_zero(grid_container(), containing_block_width); - item.used_values.margin_top = computed_values.margin().top().to_px(grid_container(), containing_block_width); - item.used_values.margin_bottom = computed_values.margin().bottom().to_px(grid_container(), containing_block_width); + item.used_values.margin_top = computed_values.margin().top().to_px_or_zero(grid_container(), containing_block_width); + item.used_values.margin_bottom = computed_values.margin().bottom().to_px_or_zero(grid_container(), containing_block_width); item.used_values.border_top = computed_values.border_top().width; item.used_values.border_bottom = computed_values.border_bottom().width; @@ -2179,10 +2179,10 @@ void GridFormattingContext::layout_absolutely_positioned_element(Box const& box) box_state.border_right = box.computed_values().border_right().width; box_state.border_top = box.computed_values().border_top().width; box_state.border_bottom = box.computed_values().border_bottom().width; - box_state.padding_left = box.computed_values().padding().left().to_px(grid_container(), grid_area_rect.width()); - box_state.padding_right = box.computed_values().padding().right().to_px(grid_container(), grid_area_rect.width()); - box_state.padding_top = box.computed_values().padding().top().to_px(grid_container(), grid_area_rect.width()); - box_state.padding_bottom = box.computed_values().padding().bottom().to_px(grid_container(), grid_area_rect.width()); + box_state.padding_left = box.computed_values().padding().left().to_px_or_zero(grid_container(), grid_area_rect.width()); + box_state.padding_right = box.computed_values().padding().right().to_px_or_zero(grid_container(), grid_area_rect.width()); + box_state.padding_top = box.computed_values().padding().top().to_px_or_zero(grid_container(), grid_area_rect.width()); + box_state.padding_bottom = box.computed_values().padding().bottom().to_px_or_zero(grid_container(), grid_area_rect.width()); compute_width_for_absolutely_positioned_element(box, available_space); diff --git a/Libraries/LibWeb/Layout/GridFormattingContext.h b/Libraries/LibWeb/Layout/GridFormattingContext.h index eca40f52fcb..13616350d90 100644 --- a/Libraries/LibWeb/Layout/GridFormattingContext.h +++ b/Libraries/LibWeb/Layout/GridFormattingContext.h @@ -94,12 +94,12 @@ struct GridItem { return dimension == GridDimension::Column ? computed_values().width() : computed_values().height(); } - CSS::LengthPercentage const& margin_start(GridDimension dimension) const + CSS::LengthPercentageOrAuto const& margin_start(GridDimension dimension) const { return dimension == GridDimension::Column ? computed_values().margin().left() : computed_values().margin().top(); } - CSS::LengthPercentage const& margin_end(GridDimension dimension) const + CSS::LengthPercentageOrAuto const& margin_end(GridDimension dimension) const { return dimension == GridDimension::Column ? computed_values().margin().right() : computed_values().margin().bottom(); } diff --git a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index 9ddd9edc241..dcd68f7576b 100644 --- a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -103,21 +103,21 @@ void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode l auto& box_state = m_state.get_mutable(box); auto const& computed_values = box.computed_values(); - box_state.margin_left = computed_values.margin().left().to_px(box, width_of_containing_block); + box_state.margin_left = computed_values.margin().left().to_px_or_zero(box, width_of_containing_block); box_state.border_left = computed_values.border_left().width; - box_state.padding_left = computed_values.padding().left().to_px(box, width_of_containing_block); + box_state.padding_left = computed_values.padding().left().to_px_or_zero(box, width_of_containing_block); - box_state.margin_right = computed_values.margin().right().to_px(box, width_of_containing_block); + box_state.margin_right = computed_values.margin().right().to_px_or_zero(box, width_of_containing_block); box_state.border_right = computed_values.border_right().width; - box_state.padding_right = computed_values.padding().right().to_px(box, width_of_containing_block); + box_state.padding_right = computed_values.padding().right().to_px_or_zero(box, width_of_containing_block); - box_state.margin_top = computed_values.margin().top().to_px(box, width_of_containing_block); + box_state.margin_top = computed_values.margin().top().to_px_or_zero(box, width_of_containing_block); box_state.border_top = computed_values.border_top().width; - box_state.padding_top = computed_values.padding().top().to_px(box, width_of_containing_block); + box_state.padding_top = computed_values.padding().top().to_px_or_zero(box, width_of_containing_block); - box_state.padding_bottom = computed_values.padding().bottom().to_px(box, width_of_containing_block); + box_state.padding_bottom = computed_values.padding().bottom().to_px_or_zero(box, width_of_containing_block); box_state.border_bottom = computed_values.border_bottom().width; - box_state.margin_bottom = computed_values.margin().bottom().to_px(box, width_of_containing_block); + box_state.margin_bottom = computed_values.margin().bottom().to_px_or_zero(box, width_of_containing_block); if (box_is_sized_as_replaced_element(box, *m_available_space)) { box_state.set_content_width(compute_width_for_replaced_element(box, *m_available_space)); diff --git a/Libraries/LibWeb/Layout/InlineLevelIterator.cpp b/Libraries/LibWeb/Layout/InlineLevelIterator.cpp index 6a551d737ba..f4ee713664d 100644 --- a/Libraries/LibWeb/Layout/InlineLevelIterator.cpp +++ b/Libraries/LibWeb/Layout/InlineLevelIterator.cpp @@ -35,21 +35,21 @@ void InlineLevelIterator::enter_node_with_box_model_metrics(Layout::NodeWithStyl auto& used_values = m_layout_state.get_mutable(node); auto const& computed_values = node.computed_values(); - used_values.margin_top = computed_values.margin().top().to_px(node, m_containing_block_used_values.content_width()); - used_values.margin_bottom = computed_values.margin().bottom().to_px(node, m_containing_block_used_values.content_width()); + used_values.margin_top = computed_values.margin().top().to_px_or_zero(node, m_containing_block_used_values.content_width()); + used_values.margin_bottom = computed_values.margin().bottom().to_px_or_zero(node, m_containing_block_used_values.content_width()); - used_values.margin_left = computed_values.margin().left().to_px(node, m_containing_block_used_values.content_width()); + used_values.margin_left = computed_values.margin().left().to_px_or_zero(node, m_containing_block_used_values.content_width()); used_values.border_left = computed_values.border_left().width; - used_values.padding_left = computed_values.padding().left().to_px(node, m_containing_block_used_values.content_width()); + used_values.padding_left = computed_values.padding().left().to_px_or_zero(node, m_containing_block_used_values.content_width()); - used_values.margin_right = computed_values.margin().right().to_px(node, m_containing_block_used_values.content_width()); + used_values.margin_right = computed_values.margin().right().to_px_or_zero(node, m_containing_block_used_values.content_width()); used_values.border_right = computed_values.border_right().width; - used_values.padding_right = computed_values.padding().right().to_px(node, m_containing_block_used_values.content_width()); + used_values.padding_right = computed_values.padding().right().to_px_or_zero(node, m_containing_block_used_values.content_width()); used_values.border_top = computed_values.border_top().width; used_values.border_bottom = computed_values.border_bottom().width; - used_values.padding_bottom = computed_values.padding().bottom().to_px(node, m_containing_block_used_values.content_width()); - used_values.padding_top = computed_values.padding().top().to_px(node, m_containing_block_used_values.content_width()); + used_values.padding_bottom = computed_values.padding().bottom().to_px_or_zero(node, m_containing_block_used_values.content_width()); + used_values.padding_top = computed_values.padding().top().to_px_or_zero(node, m_containing_block_used_values.content_width()); m_extra_leading_metrics->margin += used_values.margin_left; m_extra_leading_metrics->border += used_values.border_left; diff --git a/Libraries/LibWeb/Layout/LayoutState.cpp b/Libraries/LibWeb/Layout/LayoutState.cpp index 9852541afa0..55c4a90c474 100644 --- a/Libraries/LibWeb/Layout/LayoutState.cpp +++ b/Libraries/LibWeb/Layout/LayoutState.cpp @@ -458,14 +458,13 @@ void LayoutState::commit(Box& root) scrollport_size = nearest_scrollable_ancestor->absolute_rect().size(); if (!inset.top().is_auto()) - sticky_insets->top = inset.top().to_px(node, scrollport_size.height()); + sticky_insets->top = inset.top().to_px_or_zero(node, scrollport_size.height()); if (!inset.right().is_auto()) - sticky_insets->right = inset.right().to_px(node, scrollport_size.width()); + sticky_insets->right = inset.right().to_px_or_zero(node, scrollport_size.width()); if (!inset.bottom().is_auto()) - sticky_insets->bottom = inset.bottom().to_px(node, scrollport_size.height()); + sticky_insets->bottom = inset.bottom().to_px_or_zero(node, scrollport_size.height()); if (!inset.left().is_auto()) - sticky_insets->left = inset.left().to_px(node, scrollport_size.width()); - + sticky_insets->left = inset.left().to_px_or_zero(node, scrollport_size.width()); paintable_box->set_sticky_insets(move(sticky_insets)); } } @@ -498,14 +497,14 @@ void LayoutState::UsedValues::set_node(NodeWithStyle const& node, UsedValues con if (width) { border_and_padding = computed_values.border_left().width - + computed_values.padding().left().to_px(*m_node, containing_block_used_values->content_width()) + + computed_values.padding().left().to_px_or_zero(*m_node, containing_block_used_values->content_width()) + computed_values.border_right().width - + computed_values.padding().right().to_px(*m_node, containing_block_used_values->content_width()); + + computed_values.padding().right().to_px_or_zero(*m_node, containing_block_used_values->content_width()); } else { border_and_padding = computed_values.border_top().width - + computed_values.padding().top().to_px(*m_node, containing_block_used_values->content_width()) + + computed_values.padding().top().to_px_or_zero(*m_node, containing_block_used_values->content_width()) + computed_values.border_bottom().width - + computed_values.padding().bottom().to_px(*m_node, containing_block_used_values->content_width()); + + computed_values.padding().bottom().to_px_or_zero(*m_node, containing_block_used_values->content_width()); } return unadjusted_pixels - border_and_padding; diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index 3fb45deb80a..0c0e1a9417b 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -672,7 +672,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style) computed_values.set_min_height(computed_style.size_value(CSS::PropertyID::MinHeight)); computed_values.set_max_height(computed_style.size_value(CSS::PropertyID::MaxHeight)); - computed_values.set_inset(computed_style.length_box(CSS::PropertyID::Left, CSS::PropertyID::Top, CSS::PropertyID::Right, CSS::PropertyID::Bottom, *this, CSS::ComputedProperties::ClampNegativeLengths::No, CSS::Length::make_auto())); + computed_values.set_inset(computed_style.length_box(CSS::PropertyID::Left, CSS::PropertyID::Top, CSS::PropertyID::Right, CSS::PropertyID::Bottom, *this, CSS::ComputedProperties::ClampNegativeLengths::No, CSS::LengthPercentageOrAuto::make_auto())); computed_values.set_margin(computed_style.length_box(CSS::PropertyID::MarginLeft, CSS::PropertyID::MarginTop, CSS::PropertyID::MarginRight, CSS::PropertyID::MarginBottom, *this, CSS::ComputedProperties::ClampNegativeLengths::No, CSS::Length::make_px(0))); computed_values.set_padding(computed_style.length_box(CSS::PropertyID::PaddingLeft, CSS::PropertyID::PaddingTop, CSS::PropertyID::PaddingRight, CSS::PropertyID::PaddingBottom, *this, CSS::ComputedProperties::ClampNegativeLengths::Yes, CSS::Length::make_px(0))); diff --git a/Libraries/LibWeb/Layout/TableFormattingContext.cpp b/Libraries/LibWeb/Layout/TableFormattingContext.cpp index 2979e612950..0a2f7933030 100644 --- a/Libraries/LibWeb/Layout/TableFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/TableFormattingContext.cpp @@ -108,10 +108,10 @@ void TableFormattingContext::compute_cell_measures() for (auto& cell : m_cells) { auto const& computed_values = cell.box->computed_values(); - CSSPixels padding_top = computed_values.padding().top().to_px(cell.box, containing_block.content_height()); - CSSPixels padding_bottom = computed_values.padding().bottom().to_px(cell.box, containing_block.content_height()); - CSSPixels padding_left = computed_values.padding().left().to_px(cell.box, containing_block.content_width()); - CSSPixels padding_right = computed_values.padding().right().to_px(cell.box, containing_block.content_width()); + CSSPixels padding_top = computed_values.padding().top().to_px_or_zero(cell.box, containing_block.content_height()); + CSSPixels padding_bottom = computed_values.padding().bottom().to_px_or_zero(cell.box, containing_block.content_height()); + CSSPixels padding_left = computed_values.padding().left().to_px_or_zero(cell.box, containing_block.content_width()); + CSSPixels padding_right = computed_values.padding().right().to_px_or_zero(cell.box, containing_block.content_width()); auto const& cell_state = m_state.get(cell.box); auto use_collapsing_borders_model = cell_state.override_borders_data().has_value(); @@ -861,10 +861,10 @@ void TableFormattingContext::compute_table_height() auto width_of_containing_block = cell_state.containing_block_used_values()->content_width(); auto height_of_containing_block = cell_state.containing_block_used_values()->content_height(); - cell_state.padding_top = cell.box->computed_values().padding().top().to_px(cell.box, width_of_containing_block); - cell_state.padding_bottom = cell.box->computed_values().padding().bottom().to_px(cell.box, width_of_containing_block); - cell_state.padding_left = cell.box->computed_values().padding().left().to_px(cell.box, width_of_containing_block); - cell_state.padding_right = cell.box->computed_values().padding().right().to_px(cell.box, width_of_containing_block); + cell_state.padding_top = cell.box->computed_values().padding().top().to_px_or_zero(cell.box, width_of_containing_block); + cell_state.padding_bottom = cell.box->computed_values().padding().bottom().to_px_or_zero(cell.box, width_of_containing_block); + cell_state.padding_left = cell.box->computed_values().padding().left().to_px_or_zero(cell.box, width_of_containing_block); + cell_state.padding_right = cell.box->computed_values().padding().right().to_px_or_zero(cell.box, width_of_containing_block); if (table_box().computed_values().border_collapse() == CSS::BorderCollapse::Separate) { cell_state.border_top = cell.box->computed_values().border_top().width;