mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-01-03 07:07:23 +00:00
LibWeb: Stop sizing the context root box in formatting contexts
Until now, some formatting contexts (BFC in particular) have been assigning size to the root box. This is really the responsibility of the parent formatting context, so let's stop doing it. To keep position:absolute working, parent formatting contexts now notify child contexts when the child's root box has been sized. (Note that the important thing here is for the child root to have its final used height before it's able to place bottom-relative boxes.) This breaks flexbox layout in some ways, but we'll have to address those by improving the spec compliance of FFC.)
This commit is contained in:
@@ -32,38 +32,25 @@ bool BlockFormattingContext::is_initial() const
|
||||
return is<InitialContainingBlock>(root());
|
||||
}
|
||||
|
||||
void BlockFormattingContext::run(Box& box, LayoutMode layout_mode)
|
||||
void BlockFormattingContext::run(Box&, LayoutMode layout_mode)
|
||||
{
|
||||
if (is_initial()) {
|
||||
layout_initial_containing_block(layout_mode);
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: BFC currently computes the width+height of the target box.
|
||||
// This is necessary to be able to place absolutely positioned descendants.
|
||||
// The same work is also done by the parent BFC for each of its blocks..
|
||||
if (root().children_are_inline())
|
||||
layout_inline_children(root(), layout_mode);
|
||||
else
|
||||
layout_block_level_children(root(), layout_mode);
|
||||
}
|
||||
|
||||
if (layout_mode == LayoutMode::Default)
|
||||
compute_width(box);
|
||||
void BlockFormattingContext::parent_context_did_dimension_child_root_box()
|
||||
{
|
||||
for (auto& box : m_absolutely_positioned_boxes)
|
||||
layout_absolutely_positioned_element(box);
|
||||
|
||||
if (box.children_are_inline()) {
|
||||
layout_inline_children(verify_cast<BlockContainer>(box), layout_mode);
|
||||
} else {
|
||||
layout_block_level_children(verify_cast<BlockContainer>(box), layout_mode);
|
||||
}
|
||||
|
||||
if (layout_mode == LayoutMode::Default) {
|
||||
compute_height(box);
|
||||
|
||||
box.for_each_child_of_type<Box>([&](auto& child_box) {
|
||||
if (child_box.is_absolutely_positioned()) {
|
||||
layout_absolutely_positioned_element(child_box);
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
apply_transformations_to_children(box);
|
||||
apply_transformations_to_children(root());
|
||||
}
|
||||
|
||||
void BlockFormattingContext::apply_transformations_to_children(Box& box)
|
||||
@@ -384,18 +371,24 @@ void BlockFormattingContext::compute_position(Box& box)
|
||||
|
||||
void BlockFormattingContext::layout_inline_children(BlockContainer& block_container, LayoutMode layout_mode)
|
||||
{
|
||||
VERIFY(block_container.children_are_inline());
|
||||
|
||||
InlineFormattingContext context(block_container, *this);
|
||||
context.run(block_container, layout_mode);
|
||||
}
|
||||
|
||||
void BlockFormattingContext::layout_block_level_children(BlockContainer& block_container, LayoutMode layout_mode)
|
||||
{
|
||||
VERIFY(!block_container.children_are_inline());
|
||||
|
||||
float content_height = 0;
|
||||
float content_width = 0;
|
||||
|
||||
block_container.for_each_child_of_type<Box>([&](Box& child_box) {
|
||||
if (child_box.is_absolutely_positioned())
|
||||
if (child_box.is_absolutely_positioned()) {
|
||||
m_absolutely_positioned_boxes.append(child_box);
|
||||
return IterationDecision::Continue;
|
||||
}
|
||||
|
||||
// NOTE: ListItemMarkerBoxes are placed by their corresponding ListItemBox.
|
||||
if (is<ListItemMarkerBox>(child_box))
|
||||
@@ -410,7 +403,15 @@ void BlockFormattingContext::layout_block_level_children(BlockContainer& block_c
|
||||
if (is<ReplacedBox>(child_box) || is<BlockContainer>(child_box))
|
||||
place_block_level_element_in_normal_flow_vertically(child_box, block_container);
|
||||
|
||||
(void)layout_inside(child_box, layout_mode);
|
||||
OwnPtr<FormattingContext> independent_formatting_context;
|
||||
if (child_box.can_have_children()) {
|
||||
independent_formatting_context = create_independent_formatting_context_if_needed(child_box);
|
||||
if (independent_formatting_context)
|
||||
independent_formatting_context->run(child_box, layout_mode);
|
||||
else
|
||||
layout_block_level_children(verify_cast<BlockContainer>(child_box), layout_mode);
|
||||
}
|
||||
|
||||
compute_height(child_box);
|
||||
|
||||
if (child_box.computed_values().position() == CSS::Position::Relative)
|
||||
@@ -426,6 +427,10 @@ void BlockFormattingContext::layout_block_level_children(BlockContainer& block_c
|
||||
|
||||
content_height = max(content_height, child_box.effective_offset().y() + child_box.content_height() + child_box.box_model().margin_box().bottom);
|
||||
content_width = max(content_width, child_box.content_width());
|
||||
|
||||
if (independent_formatting_context)
|
||||
independent_formatting_context->parent_context_did_dimension_child_root_box();
|
||||
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user