diff --git a/Tests/LibWeb/Layout/expected/table/inline-table-width.txt b/Tests/LibWeb/Layout/expected/table/inline-table-width.txt index 355b7e40c13..7627b972af9 100644 --- a/Tests/LibWeb/Layout/expected/table/inline-table-width.txt +++ b/Tests/LibWeb/Layout/expected/table/inline-table-width.txt @@ -1,12 +1,12 @@ 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 784x46.9375 children: inline - line 0 width: 137.984375, height: 46.9375, bottom: 46.9375, baseline: 46.9375 - frag 0 from BlockContainer start: 0, length: 0, rect: [9,9 135.984375x44.9375] - BlockContainer at (9,9) content-size 135.984375x44.9375 inline-block [BFC] children: not-inline - TableWrapper <(anonymous)> at (9,9) content-size 135.984375x44.9375 inline-block [BFC] children: not-inline - Box <(anonymous)> at (9,9) content-size 135.984375x44.9375 inline-table table-box [TFC] children: not-inline - Box at (9,9) content-size 129.984375x38.9375 table-row-group children: not-inline + BlockContainer at (8,8) content-size 784x64.875 children: inline + line 0 width: 137.984375, height: 64.875, bottom: 64.875, baseline: 64.875 + frag 0 from BlockContainer start: 0, length: 0, rect: [9,9 135.984375x62.875] + BlockContainer
at (9,9) content-size 135.984375x62.875 inline-block [BFC] children: not-inline + TableWrapper <(anonymous)> at (9,9) content-size 135.984375x62.875 inline-block [BFC] children: not-inline + Box <(anonymous)> at (9,9) content-size 135.984375x62.875 inline-table table-box [TFC] children: not-inline + Box at (9,9) content-size 129.984375x56.875 table-row-group children: not-inline Box at (11,11) content-size 129.984375x19.46875 table-row children: not-inline BlockContainer at (11,32.46875) content-size 129.984375x19.46875 table-row children: not-inline - BlockContainer at (11,32.46875) content-size 129.984375x37.40625 table-row children: not-inline + BlockContainer
at (12,12) content-size 87.90625x17.46875 table-cell [BFC] children: inline line 0 width: 15.734375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 @@ -18,32 +18,32 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline frag 0 from TextNode start: 0, length: 4, rect: [103.90625,12 27.84375x17.46875] "null" TextNode <#text> - Box
at (12,33.46875) content-size 87.90625x17.46875 table-cell [BFC] children: inline + Box
at (12,42.4375) content-size 87.90625x17.46875 table-cell [BFC] children: inline line 0 width: 87.90625, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 11, rect: [12,33.46875 87.90625x17.46875] + frag 0 from TextNode start: 0, length: 11, rect: [12,42.4375 87.90625x17.46875] "Is Selected" TextNode <#text> - BlockContainer at (103.90625,33.46875) content-size 38.078125x17.46875 table-cell [BFC] children: inline + BlockContainer at (103.90625,42.4375) content-size 38.078125x17.46875 table-cell [BFC] children: inline line 0 width: 38.078125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 - frag 0 from TextNode start: 0, length: 5, rect: [103.90625,33.46875 38.078125x17.46875] + frag 0 from TextNode start: 0, length: 5, rect: [103.90625,42.4375 38.078125x17.46875] "false" TextNode <#text> PaintableWithLines (Viewport<#document>) [0,0 800x600] PaintableWithLines (BlockContainer) [0,0 800x600] - PaintableWithLines (BlockContainer) [8,8 784x46.9375] - PaintableWithLines (BlockContainer) [8,8 137.984375x46.9375] - PaintableWithLines (TableWrapper(anonymous)) [9,9 135.984375x44.9375] - PaintableBox (Box(anonymous)) [9,9 135.984375x44.9375] - PaintableBox (Box) [9,9 129.984375x38.9375] overflow: [9,9 133.984375x42.9375] + PaintableWithLines (BlockContainer) [8,8 784x64.875] + PaintableWithLines (BlockContainer
) [8,8 137.984375x64.875] + PaintableWithLines (TableWrapper(anonymous)) [9,9 135.984375x62.875] + PaintableBox (Box(anonymous)) [9,9 135.984375x62.875] + PaintableBox (Box) [9,9 129.984375x56.875] overflow: [9,9 133.984375x60.875] PaintableBox (Box) [11,11 129.984375x19.46875] overflow: [11,11 131.984375x19.46875] PaintableWithLines (BlockContainer) [11,32.46875 129.984375x19.46875] overflow: [11,32.46875 131.984375x19.46875] - PaintableWithLines (BlockContainer) [11,32.46875 129.984375x37.40625] overflow: [11,32.46875 131.984375x37.40625] + PaintableWithLines (BlockContainer
) [11,11 89.90625x19.46875] TextPaintable (TextNode<#text>) PaintableWithLines (BlockContainer) [102.90625,11 40.078125x19.46875] TextPaintable (TextNode<#text>) - PaintableBox (Box
) [11,32.46875 89.90625x19.46875] - TextPaintable (TextNode<#text>) - PaintableWithLines (BlockContainer) [102.90625,32.46875 40.078125x19.46875] + PaintableBox (Box
) [11,32.46875 89.90625x37.40625] TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer) [102.90625,32.46875 40.078125x37.40625] + TextPaintable (TextNode<#text>) \ No newline at end of file diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp index 4013520bc8c..61f45a45fef 100644 --- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp @@ -550,16 +550,16 @@ CSSPixels BlockFormattingContext::compute_auto_height_for_block_level_element(Bo if (display.is_flex_inside()) { // https://drafts.csswg.org/css-flexbox-1/#algo-main-container // NOTE: The automatic block size of a block-level flex container is its max-content size. - return calculate_max_content_height(box, available_space.width); + return calculate_max_content_height(box, available_space.width.to_px_or_zero()); } if (display.is_grid_inside()) { // https://www.w3.org/TR/css-grid-2/#intrinsic-sizes // In both inline and block formatting contexts, the grid container’s auto block size is its // max-content size. - return calculate_max_content_height(box, available_space.width); + return calculate_max_content_height(box, available_space.width.to_px_or_zero()); } if (display.is_table_inside()) { - return calculate_max_content_height(box, available_space.width); + return calculate_max_content_height(box, available_space.width.to_px_or_zero()); } // https://www.w3.org/TR/CSS22/visudet.html#normal-block diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 1d45f239f74..e4df5430e5d 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -834,7 +834,7 @@ void FlexFormattingContext::determine_main_size_of_flex_container() } } else { if (!has_definite_main_size(flex_container())) - set_main_size(flex_container(), calculate_max_content_height(flex_container(), m_available_space_for_flex_container->space.width)); + set_main_size(flex_container(), calculate_max_content_height(flex_container(), m_available_space_for_flex_container->space.width.to_px())); } } @@ -2012,7 +2012,7 @@ CSSPixels FlexFormattingContext::calculate_min_content_main_size(FlexItem const& if (available_space.width.is_indefinite()) { available_space.width = AvailableSize::make_definite(calculate_width_to_use_when_determining_intrinsic_height_of_item(item)); } - return calculate_min_content_height(item.box, available_space.width); + return calculate_min_content_height(item.box, available_space.width.to_px_or_zero()); } CSSPixels FlexFormattingContext::calculate_max_content_main_size(FlexItem const& item) const @@ -2024,7 +2024,7 @@ CSSPixels FlexFormattingContext::calculate_max_content_main_size(FlexItem const& if (available_space.width.is_indefinite()) { available_space.width = AvailableSize::make_definite(calculate_width_to_use_when_determining_intrinsic_height_of_item(item)); } - return calculate_max_content_height(item.box, available_space.width); + return calculate_max_content_height(item.box, available_space.width.to_px_or_zero()); } CSSPixels FlexFormattingContext::calculate_fit_content_main_size(FlexItem const& item) const @@ -2048,7 +2048,7 @@ CSSPixels FlexFormattingContext::calculate_min_content_cross_size(FlexItem const if (available_space.width.is_indefinite()) { available_space.width = AvailableSize::make_definite(calculate_width_to_use_when_determining_intrinsic_height_of_item(item)); } - return calculate_min_content_height(item.box, available_space.width); + return calculate_min_content_height(item.box, available_space.width.to_px_or_zero()); } return calculate_min_content_width(item.box); } @@ -2060,7 +2060,7 @@ CSSPixels FlexFormattingContext::calculate_max_content_cross_size(FlexItem const if (available_space.width.is_indefinite()) { available_space.width = AvailableSize::make_definite(calculate_width_to_use_when_determining_intrinsic_height_of_item(item)); } - return calculate_max_content_height(item.box, available_space.width); + return calculate_max_content_height(item.box, available_space.width.to_px_or_zero()); } return calculate_max_content_width(item.box); } diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index 8bb666cced9..d0372a37856 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -1265,17 +1265,17 @@ CSSPixels FormattingContext::calculate_fit_content_height(Layout::Box const& box // equal to clamp(min-content size, stretch-fit size, max-content size) // (i.e. max(min-content size, min(max-content size, stretch-fit size))). if (available_space.height.is_definite()) { - return max(calculate_min_content_height(box, available_space.width), + return max(calculate_min_content_height(box, available_space.width.to_px_or_zero()), min(calculate_stretch_fit_height(box, available_space.height), - calculate_max_content_height(box, available_space.width))); + calculate_max_content_height(box, available_space.width.to_px_or_zero()))); } // When sizing under a min-content constraint, equal to the min-content size. if (available_space.height.is_min_content()) - return calculate_min_content_height(box, available_space.width); + return calculate_min_content_height(box, available_space.width.to_px_or_zero()); // Otherwise, equal to the max-content size in that axis. - return calculate_max_content_height(box, available_space.width); + return calculate_max_content_height(box, available_space.width.to_px_or_zero()); } CSSPixels FormattingContext::calculate_min_content_width(Layout::Box const& box) const @@ -1355,29 +1355,19 @@ CSSPixels FormattingContext::calculate_max_content_width(Layout::Box const& box) } // https://www.w3.org/TR/css-sizing-3/#min-content-block-size -CSSPixels FormattingContext::calculate_min_content_height(Layout::Box const& box, AvailableSize const& available_width) const +CSSPixels FormattingContext::calculate_min_content_height(Layout::Box const& box, CSSPixels width) const { // For block containers, tables, and inline boxes, this is equivalent to the max-content block size. if (box.is_block_container() || box.display().is_table_inside()) - return calculate_max_content_height(box, available_width); + return calculate_max_content_height(box, width); if (box.has_natural_height()) return *box.natural_height(); - bool is_cacheable = available_width.is_definite() || available_width.is_intrinsic_sizing_constraint(); - auto get_cache_slot = [&]() -> Optional* { - if (!is_cacheable) - return {}; auto& root_state = m_state.m_root; auto& cache = *root_state.intrinsic_sizes.ensure(&box, [] { return adopt_own(*new LayoutState::IntrinsicSizes); }); - if (available_width.is_definite()) - return &cache.min_content_height_with_definite_available_width.ensure(available_width.to_px()); - if (available_width.is_min_content()) - return &cache.min_content_height_with_min_content_available_width; - if (available_width.is_max_content()) - return &cache.min_content_height_with_max_content_available_width; - return {}; + return &cache.min_content_height.ensure(width); }; if (auto* cache_slot = get_cache_slot(); cache_slot && cache_slot->has_value()) @@ -1388,15 +1378,14 @@ CSSPixels FormattingContext::calculate_min_content_height(Layout::Box const& box auto& box_state = throwaway_state.get_mutable(box); box_state.height_constraint = SizeConstraint::MinContent; box_state.set_indefinite_content_height(); - if (available_width.is_definite()) - box_state.set_content_width(available_width.to_px()); + box_state.set_content_width(width); auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, box); if (!context) { context = make(throwaway_state, verify_cast(box), nullptr); } - context->run(box, LayoutMode::IntrinsicSizing, AvailableSpace(available_width, AvailableSize::make_min_content())); + context->run(box, LayoutMode::IntrinsicSizing, AvailableSpace(AvailableSize::make_definite(width), AvailableSize::make_min_content())); auto min_content_height = context->automatic_content_height(); if (!isfinite(min_content_height.to_double())) { @@ -1411,28 +1400,18 @@ CSSPixels FormattingContext::calculate_min_content_height(Layout::Box const& box return min_content_height; } -CSSPixels FormattingContext::calculate_max_content_height(Layout::Box const& box, AvailableSize const& available_width) const +CSSPixels FormattingContext::calculate_max_content_height(Layout::Box const& box, CSSPixels width) const { - if (box.has_preferred_aspect_ratio() && available_width.is_definite()) - return available_width.to_px() / static_cast(*box.preferred_aspect_ratio()); + if (box.has_preferred_aspect_ratio()) + return width / static_cast(*box.preferred_aspect_ratio()); if (box.has_natural_height()) return *box.natural_height(); - bool is_cacheable = available_width.is_definite() || available_width.is_intrinsic_sizing_constraint(); - auto get_cache_slot = [&]() -> Optional* { - if (!is_cacheable) - return {}; auto& root_state = m_state.m_root; auto& cache = *root_state.intrinsic_sizes.ensure(&box, [] { return adopt_own(*new LayoutState::IntrinsicSizes); }); - if (available_width.is_definite()) - return &cache.max_content_height_with_definite_available_width.ensure(available_width.to_px()); - if (available_width.is_min_content()) - return &cache.max_content_height_with_min_content_available_width; - if (available_width.is_max_content()) - return &cache.max_content_height_with_max_content_available_width; - return {}; + return &cache.max_content_height.ensure(width); }; if (auto* cache_slot = get_cache_slot(); cache_slot && cache_slot->has_value()) @@ -1443,15 +1422,14 @@ CSSPixels FormattingContext::calculate_max_content_height(Layout::Box const& box auto& box_state = throwaway_state.get_mutable(box); box_state.height_constraint = SizeConstraint::MaxContent; box_state.set_indefinite_content_height(); - if (available_width.is_definite()) - box_state.set_content_width(available_width.to_px()); + box_state.set_content_width(width); auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, box); if (!context) { context = make(throwaway_state, verify_cast(box), nullptr); } - context->run(box, LayoutMode::IntrinsicSizing, AvailableSpace(available_width, AvailableSize::make_max_content())); + context->run(box, LayoutMode::IntrinsicSizing, AvailableSpace(AvailableSize::make_definite(width), AvailableSize::make_max_content())); auto max_content_height = context->automatic_content_height(); diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.h b/Userland/Libraries/LibWeb/Layout/FormattingContext.h index 68eb0f0993f..db7a8eae51f 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.h @@ -59,8 +59,8 @@ public: CSSPixels calculate_min_content_width(Layout::Box const&) const; CSSPixels calculate_max_content_width(Layout::Box const&) const; - CSSPixels calculate_min_content_height(Layout::Box const&, AvailableSize const& available_width) const; - CSSPixels calculate_max_content_height(Layout::Box const&, AvailableSize const& available_width) const; + CSSPixels calculate_min_content_height(Layout::Box const&, CSSPixels width) const; + CSSPixels calculate_max_content_height(Layout::Box const&, CSSPixels width) const; CSSPixels calculate_fit_content_height(Layout::Box const&, AvailableSpace const&) const; CSSPixels calculate_fit_content_width(Layout::Box const&, AvailableSpace const&) const; diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp index 997b3d0e5d9..041a339ec94 100644 --- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -1954,7 +1954,7 @@ CSSPixels GridFormattingContext::calculate_min_content_size(GridItem const& item if (dimension == GridDimension::Column) { return calculate_min_content_width(item.box); } else { - return calculate_min_content_height(item.box, get_available_space_for_item(item).width); + return calculate_min_content_height(item.box, get_available_space_for_item(item).width.to_px_or_zero()); } } @@ -1963,7 +1963,7 @@ CSSPixels GridFormattingContext::calculate_max_content_size(GridItem const& item if (dimension == GridDimension::Column) { return calculate_max_content_width(item.box); } else { - return calculate_max_content_height(item.box, get_available_space_for_item(item).width); + return calculate_max_content_height(item.box, get_available_space_for_item(item).width.to_px_or_zero()); } } diff --git a/Userland/Libraries/LibWeb/Layout/LayoutState.h b/Userland/Libraries/LibWeb/Layout/LayoutState.h index afdb8772aaa..b599668d27a 100644 --- a/Userland/Libraries/LibWeb/Layout/LayoutState.h +++ b/Userland/Libraries/LibWeb/Layout/LayoutState.h @@ -164,14 +164,8 @@ struct LayoutState { Optional min_content_width; Optional max_content_width; - // NOTE: Since intrinsic heights depend on the amount of available width, we have to cache - // three separate kinds of results, depending on the available width at the time of calculation. - HashMap> min_content_height_with_definite_available_width; - HashMap> max_content_height_with_definite_available_width; - Optional min_content_height_with_min_content_available_width; - Optional max_content_height_with_min_content_available_width; - Optional min_content_height_with_max_content_available_width; - Optional max_content_height_with_max_content_available_width; + HashMap> min_content_height; + HashMap> max_content_height; }; HashMap, NonnullOwnPtr> mutable intrinsic_sizes; diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp index f654f8a53eb..69ff709013f 100644 --- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp @@ -241,8 +241,8 @@ void TableFormattingContext::compute_cell_measures(AvailableSpace const& availab CSSPixels border_left = use_collapsing_borders_model ? round(cell_state.border_left / 2) : computed_values.border_left().width; CSSPixels border_right = use_collapsing_borders_model ? round(cell_state.border_right / 2) : computed_values.border_right().width; - auto min_content_height = calculate_min_content_height(cell.box, available_space.width); - auto max_content_height = calculate_max_content_height(cell.box, available_space.width); + auto min_content_height = calculate_min_content_height(cell.box, available_space.width.to_px_or_zero()); + auto max_content_height = calculate_max_content_height(cell.box, available_space.width.to_px_or_zero()); auto min_content_width = calculate_min_content_width(cell.box); auto max_content_width = calculate_max_content_width(cell.box);