LibWeb: Let parent formatting context determine size of flex containers
Until now, we had implemented flex container sizing by awkwardly doing exactly what the spec said (basically having FFC size the container) despite that not really making sense in the big picture. (Parent formatting contexts should be responsible for sizing and placing their children) This patch moves us away from the Flexbox spec text a little bit, by removing the logic for sizing the flex container in FFC, and instead making sure that all formatting contexts can set both width and height of flex container children. This required changes in BFC and IFC, but it's actually quite simple! Width was already not a problem, and it turns out height isn't either, since the automatic height of a flex container is max-content. With this in mind, we can simply determine the height of flex containers before transferring control to FFC, and everything flows nicely. With this change, we can remove all the virtuals and FFC logic for negotiating container size with the parent formatting context. We also don't need the "available space for flex container" stuff anymore either, so that's gone as well. There are some minor diffs in layout test results from this, but the new results actually match other browsers more closely, so that's fine. This should make flex layout, and indeed layout in general, easier to understand, since this was the main weird special case outside of BFC/IFC where a formatting context delegates work to its parent instead of the other way around. :^)
This commit is contained in:
parent
5f0230a57e
commit
5af02a914c
Notes:
sideshowbarker
2024-07-17 02:28:18 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/5af02a914c Pull-request: https://github.com/SerenityOS/serenity/pull/22686
9 changed files with 40 additions and 196 deletions
|
@ -2,7 +2,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
|||
BlockContainer <html> at (1,1) content-size 798x39.46875 [BFC] children: not-inline
|
||||
BlockContainer <body> at (10,10) content-size 780x21.46875 children: not-inline
|
||||
Box <div.flexrow> at (11,11) content-size 778x19.46875 flex-container(row) [FFC] children: not-inline
|
||||
Box <div.project> at (12,12) content-size 44.03125x17.46875 flex-container(column) flex-item [FFC] children: not-inline
|
||||
Box <div.project> at (12,12) content-size 44.03125x19.46875 flex-container(column) flex-item [FFC] children: not-inline
|
||||
BlockContainer <(anonymous)> at (12,12) content-size 44.03125x17.46875 flex-item [BFC] children: inline
|
||||
line 0 width: 44.03125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 6, rect: [12,12 44.03125x17.46875]
|
||||
|
@ -11,8 +11,8 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
|||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x41.46875]
|
||||
PaintableWithLines (BlockContainer<BODY>) [9,9 782x23.46875]
|
||||
PaintableBox (Box<DIV>.flexrow) [10,10 780x21.46875]
|
||||
PaintableBox (Box<DIV>.project) [11,11 46.03125x19.46875]
|
||||
PaintableWithLines (BlockContainer<BODY>) [9,9 782x23.46875] overflow: [10,10 780x22.46875]
|
||||
PaintableBox (Box<DIV>.flexrow) [10,10 780x21.46875] overflow: [11,11 778x21.46875]
|
||||
PaintableBox (Box<DIV>.project) [11,11 46.03125x21.46875]
|
||||
PaintableWithLines (BlockContainer(anonymous)) [12,12 44.03125x17.46875]
|
||||
TextPaintable (TextNode<#text>)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (1,1) content-size 798x69.96875 [BFC] children: not-inline
|
||||
Box <body> at (10,10) content-size 780x51.96875 flex-container(row) [FFC] children: not-inline
|
||||
ImageBox <img> at (11,11) content-size 66.65625x49.984375 flex-item children: not-inline
|
||||
BlockContainer <html> at (1,1) content-size 798x69.984375 [BFC] children: not-inline
|
||||
Box <body> at (10,10) content-size 780x51.984375 flex-container(row) [FFC] children: not-inline
|
||||
ImageBox <img> at (11,11) content-size 64x49.984375 flex-item children: not-inline
|
||||
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
|
||||
TextNode <#text>
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x71.96875]
|
||||
PaintableBox (Box<BODY>) [9,9 782x53.96875] overflow: [10,10 780x51.984375]
|
||||
ImagePaintable (ImageBox<IMG>) [10,10 68.65625x51.984375]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x71.984375]
|
||||
PaintableBox (Box<BODY>) [9,9 782x53.984375]
|
||||
ImagePaintable (ImageBox<IMG>) [10,10 66x51.984375]
|
||||
|
|
|
@ -680,7 +680,8 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain
|
|||
|
||||
place_block_level_element_in_normal_flow_horizontally(box, available_space);
|
||||
|
||||
if (box.is_replaced_box())
|
||||
// NOTE: Flex containers with `auto` height are treated as `max-content`, so we can compute their height early.
|
||||
if (box.is_replaced_box() || box.display().is_flex_inside())
|
||||
compute_height(box, available_space);
|
||||
|
||||
if (independent_formatting_context) {
|
||||
|
@ -1247,15 +1248,4 @@ CSSPixels BlockFormattingContext::greatest_child_width(Box const& box) const
|
|||
return max_width;
|
||||
}
|
||||
|
||||
void BlockFormattingContext::determine_width_of_child(Box const&, AvailableSpace const&)
|
||||
{
|
||||
// NOTE: We don't do anything here, since we'll have already determined the width of the child
|
||||
// before recursing into nested layout within the child.
|
||||
}
|
||||
|
||||
void BlockFormattingContext::determine_height_of_child(Box const& box, AvailableSpace const& available_space)
|
||||
{
|
||||
compute_height(box, available_space);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,10 +50,6 @@ public:
|
|||
|
||||
void layout_block_level_box(Box const&, BlockContainer const&, LayoutMode, CSSPixels& bottom_of_lowest_margin_box, AvailableSpace const&);
|
||||
|
||||
virtual bool can_determine_size_of_child() const override { return true; }
|
||||
virtual void determine_width_of_child(Box const&, AvailableSpace const&) override;
|
||||
virtual void determine_height_of_child(Box const&, AvailableSpace const&) override;
|
||||
|
||||
void resolve_vertical_box_model_metrics(Box const&);
|
||||
|
||||
enum class DidIntroduceClearance {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2023, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2021-2024, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
|
@ -56,35 +56,17 @@ CSSPixels FlexFormattingContext::automatic_content_height() const
|
|||
return m_flex_container_state.content_height();
|
||||
}
|
||||
|
||||
void FlexFormattingContext::run(Box const& run_box, LayoutMode, AvailableSpace const& available_content_space)
|
||||
void FlexFormattingContext::run(Box const& run_box, LayoutMode, AvailableSpace const& available_space)
|
||||
{
|
||||
VERIFY(&run_box == &flex_container());
|
||||
|
||||
// NOTE: The available space provided by the parent context is basically our *content box*.
|
||||
// FFC is currently written in a way that expects that to include padding and border as well,
|
||||
// so we pad out the available space here to accommodate that.
|
||||
// FIXME: Refactor the necessary parts of FFC so we don't need this hack!
|
||||
|
||||
auto available_width = available_content_space.width;
|
||||
if (available_width.is_definite())
|
||||
available_width = AvailableSize::make_definite(available_width.to_px_or_zero() + m_flex_container_state.border_box_left() + m_flex_container_state.border_box_right());
|
||||
auto available_height = available_content_space.height;
|
||||
if (available_height.is_definite())
|
||||
available_height = AvailableSize::make_definite(available_height.to_px_or_zero() + m_flex_container_state.border_box_top() + m_flex_container_state.border_box_bottom());
|
||||
|
||||
m_available_space_for_flex_container = AxisAgnosticAvailableSpace {
|
||||
.main = is_row_layout() ? available_width : available_height,
|
||||
.cross = !is_row_layout() ? available_width : available_height,
|
||||
.space = { available_width, available_height },
|
||||
};
|
||||
|
||||
// This implements https://www.w3.org/TR/css-flexbox-1/#layout-algorithm
|
||||
|
||||
// 1. Generate anonymous flex items
|
||||
generate_anonymous_flex_items();
|
||||
|
||||
// 2. Determine the available main and cross space for the flex items
|
||||
determine_available_space_for_items(AvailableSpace(available_width, available_height));
|
||||
determine_available_space_for_items(available_space);
|
||||
|
||||
{
|
||||
// https://drafts.csswg.org/css-flexbox-1/#definite-sizes
|
||||
|
@ -114,12 +96,16 @@ void FlexFormattingContext::run(Box const& run_box, LayoutMode, AvailableSpace c
|
|||
determine_flex_base_size_and_hypothetical_main_size(item);
|
||||
}
|
||||
|
||||
if (available_width.is_intrinsic_sizing_constraint() || available_height.is_intrinsic_sizing_constraint()) {
|
||||
if (available_space.width.is_intrinsic_sizing_constraint() || available_space.height.is_intrinsic_sizing_constraint()) {
|
||||
// We're computing intrinsic size for the flex container. This happens at the end of run().
|
||||
} else {
|
||||
|
||||
// 4. Determine the main size of the flex container
|
||||
determine_main_size_of_flex_container();
|
||||
// Determine the main size of the flex container using the rules of the formatting context in which it participates.
|
||||
// NOTE: The automatic block size of a block-level flex container is its max-content size.
|
||||
|
||||
// NOTE: We've already handled this in the parent formatting context.
|
||||
// Specifically, all formatting contexts will have assigned width & height to the flex container
|
||||
// before this formatting context runs.
|
||||
}
|
||||
|
||||
// 5. Collect flex items into flex lines:
|
||||
|
@ -186,7 +172,7 @@ void FlexFormattingContext::run(Box const& run_box, LayoutMode, AvailableSpace c
|
|||
// 16. Align all flex lines (per align-content)
|
||||
align_all_flex_lines();
|
||||
|
||||
if (available_width.is_intrinsic_sizing_constraint() || available_height.is_intrinsic_sizing_constraint()) {
|
||||
if (available_space.width.is_intrinsic_sizing_constraint() || available_space.height.is_intrinsic_sizing_constraint()) {
|
||||
// We're computing intrinsic size for the flex container.
|
||||
determine_intrinsic_size_of_flex_container();
|
||||
} else {
|
||||
|
@ -195,7 +181,7 @@ void FlexFormattingContext::run(Box const& run_box, LayoutMode, AvailableSpace c
|
|||
copy_dimensions_from_flex_items_to_boxes();
|
||||
for (auto& item : m_flex_items) {
|
||||
auto& box_state = m_state.get(item.box);
|
||||
if (auto independent_formatting_context = layout_inside(item.box, LayoutMode::Normal, box_state.available_inner_space_or_constraints_from(m_available_space_for_flex_container->space)))
|
||||
if (auto independent_formatting_context = layout_inside(item.box, LayoutMode::Normal, box_state.available_inner_space_or_constraints_from(m_available_space_for_items->space)))
|
||||
independent_formatting_context->parent_context_did_dimension_child_root_box();
|
||||
|
||||
compute_inset(item.box);
|
||||
|
@ -443,66 +429,17 @@ void FlexFormattingContext::set_main_axis_second_margin(FlexItem& item, CSSPixel
|
|||
// https://drafts.csswg.org/css-flexbox-1/#algo-available
|
||||
void FlexFormattingContext::determine_available_space_for_items(AvailableSpace const& available_space)
|
||||
{
|
||||
// For each dimension, if that dimension of the flex container’s content box is a definite size, use that;
|
||||
// if that dimension of the flex container is being sized under a min or max-content constraint, the available space in that dimension is that constraint;
|
||||
// otherwise, subtract the flex container’s margin, border, and padding from the space available to the flex container in that dimension and use that value.
|
||||
// This might result in an infinite value.
|
||||
|
||||
Optional<AvailableSize> available_width_for_items;
|
||||
if (m_flex_container_state.has_definite_width()) {
|
||||
available_width_for_items = AvailableSize::make_definite(m_flex_container_state.content_width());
|
||||
} else {
|
||||
if (available_space.width.is_intrinsic_sizing_constraint()) {
|
||||
available_width_for_items = available_space.width;
|
||||
} else {
|
||||
if (available_space.width.is_definite()) {
|
||||
auto remaining = available_space.width.to_px_or_zero()
|
||||
- m_flex_container_state.margin_left
|
||||
- m_flex_container_state.margin_right
|
||||
- m_flex_container_state.border_left
|
||||
- m_flex_container_state.padding_right
|
||||
- m_flex_container_state.padding_left
|
||||
- m_flex_container_state.padding_right;
|
||||
available_width_for_items = AvailableSize::make_definite(remaining);
|
||||
} else {
|
||||
available_width_for_items = AvailableSize::make_indefinite();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Optional<AvailableSize> available_height_for_items;
|
||||
if (m_flex_container_state.has_definite_height()) {
|
||||
available_height_for_items = AvailableSize::make_definite(m_flex_container_state.content_height());
|
||||
} else {
|
||||
if (available_space.height.is_intrinsic_sizing_constraint()) {
|
||||
available_height_for_items = available_space.height;
|
||||
} else {
|
||||
if (available_space.height.is_definite()) {
|
||||
auto remaining = available_space.height.to_px_or_zero()
|
||||
- m_flex_container_state.margin_top
|
||||
- m_flex_container_state.margin_bottom
|
||||
- m_flex_container_state.border_top
|
||||
- m_flex_container_state.padding_bottom
|
||||
- m_flex_container_state.padding_top
|
||||
- m_flex_container_state.padding_bottom;
|
||||
available_height_for_items = AvailableSize::make_definite(remaining);
|
||||
} else {
|
||||
available_height_for_items = AvailableSize::make_indefinite();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_row_layout()) {
|
||||
m_available_space_for_items = AxisAgnosticAvailableSpace {
|
||||
.main = *available_width_for_items,
|
||||
.cross = *available_height_for_items,
|
||||
.space = { *available_width_for_items, *available_height_for_items },
|
||||
.main = available_space.width,
|
||||
.cross = available_space.height,
|
||||
.space = { available_space.width, available_space.height },
|
||||
};
|
||||
} else {
|
||||
m_available_space_for_items = AxisAgnosticAvailableSpace {
|
||||
.main = *available_height_for_items,
|
||||
.cross = *available_width_for_items,
|
||||
.space = { *available_width_for_items, *available_height_for_items },
|
||||
.main = available_space.height,
|
||||
.cross = available_space.width,
|
||||
.space = { available_space.width, available_space.height },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -785,59 +722,6 @@ CSSPixels FlexFormattingContext::content_based_minimum_size(FlexItem const& item
|
|||
return unclamped_size;
|
||||
}
|
||||
|
||||
bool FlexFormattingContext::can_determine_size_of_child() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void FlexFormattingContext::determine_width_of_child(Box const&, AvailableSpace const&)
|
||||
{
|
||||
// NOTE: For now, we simply do nothing here. If a child context is calling up to us
|
||||
// and asking us to determine its width, we've already done so as part of the
|
||||
// flex layout algorithm.
|
||||
}
|
||||
|
||||
void FlexFormattingContext::determine_height_of_child(Box const&, AvailableSpace const&)
|
||||
{
|
||||
// NOTE: For now, we simply do nothing here. If a child context is calling up to us
|
||||
// and asking us to determine its height, we've already done so as part of the
|
||||
// flex layout algorithm.
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-flexbox-1/#algo-main-container
|
||||
void FlexFormattingContext::determine_main_size_of_flex_container()
|
||||
{
|
||||
// Determine the main size of the flex container using the rules of the formatting context in which it participates.
|
||||
// NOTE: The automatic block size of a block-level flex container is its max-content size.
|
||||
|
||||
// FIXME: The code below doesn't know how to size absolutely positioned flex containers at all.
|
||||
// We just leave it alone for now and let the parent context deal with it.
|
||||
if (flex_container().is_absolutely_positioned())
|
||||
return;
|
||||
|
||||
// FIXME: Once all parent contexts now how to size a given child, we can remove
|
||||
// `can_determine_size_of_child()`.
|
||||
if (parent()->can_determine_size_of_child()) {
|
||||
if (is_row_layout()) {
|
||||
parent()->determine_width_of_child(flex_container(), m_available_space_for_flex_container->space);
|
||||
} else {
|
||||
parent()->determine_height_of_child(flex_container(), m_available_space_for_flex_container->space);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_row_layout()) {
|
||||
if (!flex_container().is_out_of_flow(*parent()) && m_state.get(*flex_container().containing_block()).has_definite_width()) {
|
||||
set_main_size(flex_container(), calculate_stretch_fit_width(flex_container(), m_available_space_for_flex_container->space.width));
|
||||
} else {
|
||||
set_main_size(flex_container(), calculate_max_content_width(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.to_px_or_zero()));
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/css-flexbox-1/#algo-line-break
|
||||
void FlexFormattingContext::collect_flex_items_into_flex_lines()
|
||||
{
|
||||
|
@ -1229,7 +1113,7 @@ void FlexFormattingContext::calculate_cross_size_of_each_flex_line()
|
|||
// If the flex container is single-line, then clamp the line’s cross-size to be within the container’s computed min and max cross sizes.
|
||||
// Note that if CSS 2.1’s definition of min/max-width/height applied more generally, this behavior would fall out automatically.
|
||||
// AD-HOC: We don't do this when the flex container is being sized under a min-content or max-content constraint.
|
||||
if (is_single_line() && !m_available_space_for_flex_container->cross.is_intrinsic_sizing_constraint()) {
|
||||
if (is_single_line() && !m_available_space_for_items->cross.is_intrinsic_sizing_constraint()) {
|
||||
auto const& computed_min_size = this->computed_cross_min_size(flex_container());
|
||||
auto const& computed_max_size = this->computed_cross_max_size(flex_container());
|
||||
auto cross_min_size = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_cross_min_size(flex_container()) : 0;
|
||||
|
@ -1553,7 +1437,7 @@ void FlexFormattingContext::determine_flex_container_used_cross_size()
|
|||
}
|
||||
|
||||
// AD-HOC: We don't apply min/max cross size constraints when sizing the flex container under an intrinsic sizing constraint.
|
||||
if (!m_available_space_for_flex_container->cross.is_intrinsic_sizing_constraint()) {
|
||||
if (!m_available_space_for_items->cross.is_intrinsic_sizing_constraint()) {
|
||||
auto const& computed_min_size = this->computed_cross_min_size(flex_container());
|
||||
auto const& computed_max_size = this->computed_cross_max_size(flex_container());
|
||||
auto cross_min_size = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_cross_min_size(flex_container()) : 0;
|
||||
|
@ -1689,7 +1573,7 @@ void FlexFormattingContext::copy_dimensions_from_flex_items_to_boxes()
|
|||
// https://drafts.csswg.org/css-flexbox-1/#intrinsic-sizes
|
||||
void FlexFormattingContext::determine_intrinsic_size_of_flex_container()
|
||||
{
|
||||
if (m_available_space_for_flex_container->main.is_intrinsic_sizing_constraint()) {
|
||||
if (m_available_space_for_items->main.is_intrinsic_sizing_constraint()) {
|
||||
CSSPixels main_size = calculate_intrinsic_main_size_of_flex_container();
|
||||
set_main_size(flex_container(), main_size);
|
||||
}
|
||||
|
@ -2051,7 +1935,7 @@ CSSPixels FlexFormattingContext::calculate_fit_content_cross_size(FlexItem const
|
|||
CSSPixels FlexFormattingContext::calculate_min_content_cross_size(FlexItem const& item) const
|
||||
{
|
||||
if (is_row_layout()) {
|
||||
auto available_space = m_state.get(item.box).available_inner_space_or_constraints_from(m_available_space_for_flex_container->space);
|
||||
auto available_space = m_state.get(item.box).available_inner_space_or_constraints_from(m_available_space_for_items->space);
|
||||
if (available_space.width.is_indefinite()) {
|
||||
available_space.width = AvailableSize::make_definite(calculate_width_to_use_when_determining_intrinsic_height_of_item(item));
|
||||
}
|
||||
|
@ -2063,7 +1947,7 @@ CSSPixels FlexFormattingContext::calculate_min_content_cross_size(FlexItem const
|
|||
CSSPixels FlexFormattingContext::calculate_max_content_cross_size(FlexItem const& item) const
|
||||
{
|
||||
if (is_row_layout()) {
|
||||
auto available_space = m_state.get(item.box).available_inner_space_or_constraints_from(m_available_space_for_flex_container->space);
|
||||
auto available_space = m_state.get(item.box).available_inner_space_or_constraints_from(m_available_space_for_items->space);
|
||||
if (available_space.width.is_indefinite()) {
|
||||
available_space.width = AvailableSize::make_definite(calculate_width_to_use_when_determining_intrinsic_height_of_item(item));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2021-2024, Andreas Kling <kling@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -24,10 +24,6 @@ public:
|
|||
|
||||
Box const& flex_container() const { return context_box(); }
|
||||
|
||||
virtual bool can_determine_size_of_child() const override;
|
||||
virtual void determine_width_of_child(Box const&, AvailableSpace const&) override;
|
||||
virtual void determine_height_of_child(Box const&, AvailableSpace const&) override;
|
||||
|
||||
virtual CSSPixelPoint calculate_static_position(Box const&) const override;
|
||||
|
||||
private:
|
||||
|
@ -162,8 +158,6 @@ private:
|
|||
|
||||
void determine_flex_base_size_and_hypothetical_main_size(FlexItem&);
|
||||
|
||||
void determine_main_size_of_flex_container();
|
||||
|
||||
void collect_flex_items_into_flex_lines();
|
||||
|
||||
void resolve_flexible_lengths();
|
||||
|
@ -229,7 +223,6 @@ private:
|
|||
AvailableSpace space;
|
||||
};
|
||||
Optional<AxisAgnosticAvailableSpace> m_available_space_for_items;
|
||||
Optional<AxisAgnosticAvailableSpace> m_available_space_for_flex_container;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -89,10 +89,6 @@ public:
|
|||
[[nodiscard]] CSSPixels calculate_stretch_fit_width(Box const&, AvailableSize const&) const;
|
||||
[[nodiscard]] CSSPixels calculate_stretch_fit_height(Box const&, AvailableSize const&) const;
|
||||
|
||||
virtual bool can_determine_size_of_child() const { return false; }
|
||||
virtual void determine_width_of_child(Box const&, AvailableSpace const&) { }
|
||||
virtual void determine_height_of_child(Box const&, AvailableSpace const&) { }
|
||||
|
||||
virtual CSSPixelPoint calculate_static_position(Box const&) const;
|
||||
bool can_skip_is_anonymous_text_run(Box&);
|
||||
|
||||
|
|
|
@ -172,6 +172,10 @@ void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode l
|
|||
|
||||
box_state.set_content_width(width);
|
||||
|
||||
// NOTE: Flex containers with `auto` height are treated as `max-content`, so we can compute their height early.
|
||||
if (box_state.has_definite_height() || box.display().is_flex_inside())
|
||||
parent().compute_height(box, AvailableSpace(AvailableSize::make_definite(width), AvailableSize::make_definite(m_containing_block_state.content_height())));
|
||||
|
||||
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();
|
||||
|
@ -389,21 +393,6 @@ bool InlineFormattingContext::can_fit_new_line_at_y(CSSPixels y) const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool InlineFormattingContext::can_determine_size_of_child() const
|
||||
{
|
||||
return parent().can_determine_size_of_child();
|
||||
}
|
||||
|
||||
void InlineFormattingContext::determine_width_of_child(Box const& box, AvailableSpace const& available_space)
|
||||
{
|
||||
return parent().determine_width_of_child(box, available_space);
|
||||
}
|
||||
|
||||
void InlineFormattingContext::determine_height_of_child(Box const& box, AvailableSpace const& available_space)
|
||||
{
|
||||
return parent().determine_height_of_child(box, available_space);
|
||||
}
|
||||
|
||||
CSSPixels InlineFormattingContext::vertical_float_clearance() const
|
||||
{
|
||||
return m_vertical_float_clearance;
|
||||
|
|
|
@ -34,10 +34,6 @@ public:
|
|||
bool any_floats_intrude_at_y(CSSPixels y) const;
|
||||
bool can_fit_new_line_at_y(CSSPixels y) const;
|
||||
|
||||
virtual bool can_determine_size_of_child() const override;
|
||||
virtual void determine_width_of_child(Box const&, AvailableSpace const&) override;
|
||||
virtual void determine_height_of_child(Box const&, AvailableSpace const&) override;
|
||||
|
||||
CSSPixels vertical_float_clearance() const;
|
||||
void set_vertical_float_clearance(CSSPixels);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue