LibWeb: Floating boxes with width:auto should be shrink-to-fit

This commit is contained in:
Andreas Kling 2020-12-06 01:08:14 +01:00
parent 484134d818
commit 26a9ab7cd5
Notes: sideshowbarker 2024-07-19 01:02:10 +09:00
2 changed files with 46 additions and 0 deletions

View file

@ -97,6 +97,11 @@ void BlockFormattingContext::compute_width(Box& box)
return;
}
if (box.is_floating()) {
compute_width_for_floating_box(box);
return;
}
auto& style = box.style();
float width_of_containing_block = box.width_of_logical_containing_block();
@ -216,6 +221,46 @@ void BlockFormattingContext::compute_width(Box& box)
box.box_model().padding.right = padding_right;
}
void BlockFormattingContext::compute_width_for_floating_box(Box& box)
{
// 10.3.5 Floating, non-replaced elements
auto& style = box.style();
float width_of_containing_block = box.width_of_logical_containing_block();
auto zero_value = CSS::Length::make_px(0);
auto margin_left = CSS::Length::make_auto();
auto margin_right = CSS::Length::make_auto();
const auto padding_left = style.padding().left.resolved_or_zero(box, width_of_containing_block);
const auto padding_right = style.padding().right.resolved_or_zero(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 width = style.width();
// If 'width' is computed as 'auto', the used value is the "shrink-to-fit" width.
if (width.is_auto()) {
// Find the available width: in this case, this is the width of the containing
// 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.
float available_width = width_of_containing_block
- margin_left.to_px(box) - style.border_left().width - padding_left.to_px(box)
- padding_right.to_px(box) - style.border_right().width - margin_right.to_px(box);
auto result = calculate_shrink_to_fit_widths(box);
// Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).
width = CSS::Length(min(max(result.preferred_minimum_width, available_width), result.preferred_width), CSS::Length::Type::Px);
}
float final_width = width.resolved_or_zero(box, width_of_containing_block).to_px(box);
box.set_width(final_width);
}
void BlockFormattingContext::compute_width_for_absolutely_positioned_block(Box& box)
{
auto& containing_block = context_box();

View file

@ -52,6 +52,7 @@ private:
virtual bool is_block_formatting_context() const final { return true; }
void compute_width_for_absolutely_positioned_block(Box&);
void compute_width_for_floating_box(Box&);
void layout_initial_containing_block(LayoutMode);
void layout_block_level_children(LayoutMode);