diff --git a/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Libraries/LibWeb/Layout/BlockFormattingContext.cpp index 1d4e0aa8909..38f52dbd480 100644 --- a/Libraries/LibWeb/Layout/BlockFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/BlockFormattingContext.cpp @@ -416,16 +416,16 @@ void BlockFormattingContext::resolve_used_height_if_not_treated_as_auto(Box cons auto const& computed_values = box.computed_values(); auto& box_state = m_state.get_mutable(box); - auto height = calculate_inner_height(box, available_space.height, box.computed_values().height()); + auto height = calculate_inner_height(box, available_space, box.computed_values().height()); if (!should_treat_max_height_as_none(box, available_space.height)) { if (!computed_values.max_height().is_auto()) { - auto max_height = calculate_inner_height(box, available_space.height, computed_values.max_height()); + auto max_height = calculate_inner_height(box, available_space, computed_values.max_height()); height = min(height, max_height); } } if (!computed_values.min_height().is_auto()) { - height = max(height, calculate_inner_height(box, available_space.height, computed_values.min_height())); + height = max(height, calculate_inner_height(box, available_space, computed_values.min_height())); } box_state.set_content_height(height); @@ -454,12 +454,12 @@ void BlockFormattingContext::resolve_used_height_if_treated_as_auto(Box const& b if (!should_treat_max_height_as_none(box, available_space.height)) { if (!computed_values.max_height().is_auto()) { - auto max_height = calculate_inner_height(box, available_space.height, computed_values.max_height()); + auto max_height = calculate_inner_height(box, available_space, computed_values.max_height()); height = min(height, max_height); } } if (!computed_values.min_height().is_auto()) { - height = max(height, calculate_inner_height(box, available_space.height, computed_values.min_height())); + height = max(height, calculate_inner_height(box, available_space, computed_values.min_height())); } if (box.document().in_quirks_mode() diff --git a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index adcf53bc387..cecdf2d476b 100644 --- a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -25,7 +25,7 @@ CSSPixels FlexFormattingContext::get_pixel_width(Box const& box, CSS::Size const CSSPixels FlexFormattingContext::get_pixel_height(Box const& box, CSS::Size const& size) const { - return calculate_inner_height(box, m_available_space->height, size); + return calculate_inner_height(box, m_available_space.value(), size); } FlexFormattingContext::FlexFormattingContext(LayoutState& state, LayoutMode layout_mode, Box const& flex_container, FormattingContext* parent) diff --git a/Libraries/LibWeb/Layout/FormattingContext.cpp b/Libraries/LibWeb/Layout/FormattingContext.cpp index c4944bd3701..72a4452f469 100644 --- a/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -624,7 +624,7 @@ CSSPixels FormattingContext::tentative_height_for_replaced_element(Box const& bo return 150; // FIXME: Handle cases when available_space is not definite. - return calculate_inner_height(box, available_space.height, computed_height); + return calculate_inner_height(box, available_space, computed_height); } CSSPixels FormattingContext::compute_height_for_replaced_element(Box const& box, AvailableSpace const& available_space) const @@ -954,12 +954,12 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el auto const& computed_max_height = box.computed_values().max_height(); auto constrained_height = unconstrained_height; if (!computed_max_height.is_none()) { - auto inner_max_height = calculate_inner_height(box, available_space.height, computed_max_height); + auto inner_max_height = calculate_inner_height(box, available_space, computed_max_height); if (inner_max_height < constrained_height.to_px(box)) constrained_height = CSS::Length::make_px(inner_max_height); } if (!computed_min_height.is_auto()) { - auto inner_min_height = calculate_inner_height(box, available_space.height, computed_min_height); + auto inner_min_height = calculate_inner_height(box, available_space, computed_min_height); if (inner_min_height > constrained_height.to_px(box)) constrained_height = CSS::Length::make_px(inner_min_height); } @@ -1148,7 +1148,7 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el return CSS::Length::make_px(compute_table_box_height_inside_table_wrapper(box, available_space)); if (should_treat_height_as_auto(box, available_space)) return CSS::Length::make_auto(); - return CSS::Length::make_px(calculate_inner_height(box, available_space.height, box.computed_values().height())); + return CSS::Length::make_px(calculate_inner_height(box, available_space, box.computed_values().height())); }()); used_height = apply_min_max_height_constraints(used_height); @@ -1614,11 +1614,23 @@ CSSPixels FormattingContext::calculate_inner_width(Layout::Box const& box, Avail return width.to_px(box, width_of_containing_block); } -CSSPixels FormattingContext::calculate_inner_height(Layout::Box const& box, AvailableSize const& available_height, CSS::Size const& height) const +CSSPixels FormattingContext::calculate_inner_height(Layout::Box const& box, AvailableSpace const& available_space, CSS::Size const& height) const { VERIFY(!height.is_auto()); - auto height_of_containing_block = available_height.to_px_or_zero(); + + if (height.is_fit_content()) { + return calculate_fit_content_height(box, available_space); + } + if (height.is_max_content()) { + return calculate_max_content_height(box, available_space.width.to_px_or_zero()); + } + if (height.is_min_content()) { + return calculate_min_content_height(box, available_space.width.to_px_or_zero()); + } + + auto height_of_containing_block = available_space.height.to_px_or_zero(); auto& computed_values = box.computed_values(); + if (computed_values.box_sizing() == CSS::BoxSizing::BorderBox) { auto const& state = m_state.get(box); auto inner_height = height.to_px(box, height_of_containing_block) @@ -1682,7 +1694,7 @@ CSSPixels FormattingContext::calculate_stretch_fit_height(Box const& box, Availa - box_state.border_bottom; } -bool FormattingContext::should_treat_width_as_auto(Box const& box, AvailableSpace const& available_space) +bool FormattingContext::should_treat_width_as_auto(Box const& box, AvailableSpace const& available_space) const { auto const& computed_width = box.computed_values().width(); if (computed_width.is_auto()) @@ -1693,35 +1705,42 @@ bool FormattingContext::should_treat_width_as_auto(Box const& box, AvailableSpac if (available_space.width.is_indefinite()) return true; } - // AD-HOC: If the box has a preferred aspect ratio and no natural height, - // we treat the width as auto, since it can't be resolved through the ratio. - if (computed_width.is_min_content() || computed_width.is_max_content() || computed_width.is_fit_content()) { - if (box.has_preferred_aspect_ratio() && !box.has_natural_height()) + // AD-HOC: If the box has a preferred aspect ratio and an intrinsic keyword for width... + if (box.has_preferred_aspect_ratio() + && (computed_width.is_min_content() || computed_width.is_max_content() || computed_width.is_fit_content())) { + // If the box has no natural height to resolve the aspect ratio, we treat the width as auto. + if (!box.has_natural_height()) + return true; + // If the box has definite height, we can resolve the width through the aspect ratio. + if (m_state.get(box).has_definite_height()) return true; } return false; } -bool FormattingContext::should_treat_height_as_auto(Box const& box, AvailableSpace const& available_space) +bool FormattingContext::should_treat_height_as_auto(Box const& box, AvailableSpace const& available_space) const { auto computed_height = box.computed_values().height(); if (computed_height.is_auto()) return true; - // https://www.w3.org/TR/css-sizing-3/#valdef-width-min-content - // https://www.w3.org/TR/css-sizing-3/#valdef-width-max-content - // https://www.w3.org/TR/css-sizing-3/#valdef-width-fit-content - // For a box’s block size, unless otherwise specified, this is equivalent to its automatic size. - // FIXME: If height is not the block axis size, then we should be concerned with the width instead. - if (computed_height.is_min_content() || computed_height.is_max_content() || computed_height.is_fit_content()) - return true; - - if (box.computed_values().height().contains_percentage()) { + if (computed_height.contains_percentage()) { if (available_space.height.is_max_content()) return true; if (available_space.height.is_indefinite()) return true; } + + // AD-HOC: If the box has a preferred aspect ratio and an intrinsic keyword for height... + if (box.has_preferred_aspect_ratio() + && (computed_height.is_min_content() || computed_height.is_max_content() || computed_height.is_fit_content())) { + // If the box has no natural width to resolve the aspect ratio, we treat the height as auto. + if (!box.has_natural_width()) + return true; + // If the box has definite width, we can resolve the height through the aspect ratio. + if (m_state.get(box).has_definite_width()) + return true; + } return false; } diff --git a/Libraries/LibWeb/Layout/FormattingContext.h b/Libraries/LibWeb/Layout/FormattingContext.h index 606fa1d7656..3d47f2c950d 100644 --- a/Libraries/LibWeb/Layout/FormattingContext.h +++ b/Libraries/LibWeb/Layout/FormattingContext.h @@ -76,7 +76,7 @@ public: CSSPixels calculate_fit_content_width(Layout::Box const&, AvailableSpace const&) const; CSSPixels calculate_inner_width(Layout::Box const&, AvailableSize const&, CSS::Size const& width) const; - CSSPixels calculate_inner_height(Layout::Box const&, AvailableSize const&, CSS::Size const& height) const; + [[nodiscard]] CSSPixels calculate_inner_height(Layout::Box const&, AvailableSpace const&, CSS::Size const& height) const; virtual CSSPixels greatest_child_width(Box const&) const; @@ -102,8 +102,8 @@ public: protected: FormattingContext(Type, LayoutMode, LayoutState&, Box const&, FormattingContext* parent = nullptr); - static bool should_treat_width_as_auto(Box const&, AvailableSpace const&); - static bool should_treat_height_as_auto(Box const&, AvailableSpace const&); + [[nodiscard]] bool should_treat_width_as_auto(Box const&, AvailableSpace const&) const; + [[nodiscard]] bool should_treat_height_as_auto(Box const&, AvailableSpace const&) const; [[nodiscard]] bool should_treat_max_width_as_none(Box const&, AvailableSize const&) const; [[nodiscard]] bool should_treat_max_height_as_none(Box const&, AvailableSize const&) const; diff --git a/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Libraries/LibWeb/Layout/GridFormattingContext.cpp index 6d12702a3d1..f6621cc33b5 100644 --- a/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -2032,7 +2032,7 @@ void GridFormattingContext::run(AvailableSpace const& available_space) CSSPixels min_height = 0; if (!grid_computed_values.min_height().is_auto()) - min_height = calculate_inner_height(grid_container(), available_space.height, grid_computed_values.min_height()); + min_height = calculate_inner_height(grid_container(), available_space, grid_computed_values.min_height()); // If automatic grid container height is less than min-height, we need to re-run the track sizing algorithm if (m_automatic_content_height < min_height) { @@ -2355,7 +2355,7 @@ CSSPixels GridFormattingContext::calculate_grid_container_maximum_size(GridDimen auto const& computed_values = grid_container().computed_values(); if (dimension == GridDimension::Column) return calculate_inner_width(grid_container(), m_available_space->width, computed_values.max_width()); - return calculate_inner_height(grid_container(), m_available_space->height, computed_values.max_height()); + return calculate_inner_height(grid_container(), m_available_space.value(), computed_values.max_height()); } CSS::Size const& GridFormattingContext::get_item_preferred_size(GridItem const& item, GridDimension const dimension) const diff --git a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index 3c6b39618be..368691b080c 100644 --- a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -185,13 +185,11 @@ void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode l auto independent_formatting_context = layout_inside(box, layout_mode, box_state.available_inner_space_or_constraints_from(*m_available_space)); - auto const& height_value = box.computed_values().height(); if (should_treat_height_as_auto(box, *m_available_space)) { // FIXME: (10.6.6) If 'height' is 'auto', the height depends on the element's descendants per 10.6.7. - parent().resolve_used_height_if_treated_as_auto(box, AvailableSpace(AvailableSize::make_indefinite(), AvailableSize::make_indefinite())); + parent().resolve_used_height_if_treated_as_auto(box, *m_available_space); } else { - auto inner_height = calculate_inner_height(box, AvailableSize::make_definite(m_containing_block_used_values.content_height()), height_value); - box_state.set_content_height(inner_height); + parent().resolve_used_height_if_not_treated_as_auto(box, *m_available_space); } if (independent_formatting_context) diff --git a/Tests/LibWeb/Layout/expected/dialog-open-modal.txt b/Tests/LibWeb/Layout/expected/dialog-open-modal.txt index df1052f8fda..e6aa589b670 100644 --- a/Tests/LibWeb/Layout/expected/dialog-open-modal.txt +++ b/Tests/LibWeb/Layout/expected/dialog-open-modal.txt @@ -2,11 +2,11 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer at (0,0) content-size 800x600 [BFC] children: not-inline BlockContainer
at (8,8) content-size 784x0 children: inline TextNode <#text> - Box