diff options
author | Egor Ananyin <ananinegor@gmail.com> | 2021-04-22 10:59:04 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-04-22 19:17:10 +0200 |
commit | 174c94047933cd11763231fd3250d04c5ca33340 (patch) | |
tree | b099e2faaa4f04f44e9d0202627607db6204e552 /Userland/Libraries/LibWeb | |
parent | 0eedf3bfea889596a492363fac46524691f8e772 (diff) | |
download | serenity-174c94047933cd11763231fd3250d04c5ca33340.zip |
LibWeb: Fix height computation (again) :^)
Height computation algorithm is actually
different for absolutely positioned boxes
and block formatting contexts (where it doesn't include floats)
Fixes #6408
Diffstat (limited to 'Userland/Libraries/LibWeb')
3 files changed, 44 insertions, 2 deletions
diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp index 30f3f9f1b5..cca7a854c1 100644 --- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp @@ -247,6 +247,49 @@ void BlockFormattingContext::compute_width_for_block_level_replaced_element_in_n box.set_width(compute_width_for_replaced_element(box)); } +static float compute_auto_height_for_block_level_element(const Box& box) +{ + Optional<float> top; + Optional<float> bottom; + + if (box.children_are_inline()) { + // If it only has inline-level children, the height is the distance between + // the top of the topmost line box and the bottom of the bottommost line box. + if (!box.line_boxes().is_empty()) { + for (auto& fragment : box.line_boxes().first().fragments()) { + if (!top.has_value() || fragment.offset().y() < top.value()) + top = fragment.offset().y(); + } + for (auto& fragment : box.line_boxes().last().fragments()) { + if (!bottom.has_value() || (fragment.offset().y() + fragment.height()) > bottom.value()) + bottom = fragment.offset().y() + fragment.height(); + } + } + } else { + // If it has block-level children, the height is the distance between + // the top margin-edge of the topmost block-level child box + // and the bottom margin-edge of the bottommost block-level child box. + box.for_each_child_of_type<Box>([&](Layout::Box& child_box) { + if (child_box.is_absolutely_positioned()) + return IterationDecision::Continue; + if ((box.computed_values().overflow_y() == CSS::Overflow::Visible) && child_box.is_floating()) + return IterationDecision::Continue; + + float child_box_top = child_box.effective_offset().y() - child_box.box_model().margin_box().top; + float child_box_bottom = child_box.effective_offset().y() + child_box.height() + child_box.box_model().margin_box().bottom; + + if (!top.has_value() || child_box_top < top.value()) + top = child_box_top; + + if (!bottom.has_value() || child_box_bottom > bottom.value()) + bottom = child_box_bottom; + + return IterationDecision::Continue; + }); + } + return bottom.value_or(0) - top.value_or(0); +} + void BlockFormattingContext::compute_height(Box& box) { auto& computed_values = box.computed_values(); diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index dfeeaa3f93..412ad77b59 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -160,7 +160,7 @@ static Gfx::FloatSize solve_replaced_size_constraint(float w, float h, const Rep return { w, h }; } -float FormattingContext::compute_auto_height_for_block_level_element(const Box& box) +static float compute_auto_height_for_block_level_element(const Box& box) { Optional<float> top; Optional<float> bottom; diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.h b/Userland/Libraries/LibWeb/Layout/FormattingContext.h index e49c1cf06e..e67799000f 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.h @@ -38,7 +38,6 @@ protected: float preferred_minimum_width { 0 }; }; - static float compute_auto_height_for_block_level_element(const Box& box); static float tentative_width_for_replaced_element(const ReplacedBox&, const CSS::Length& width); static float tentative_height_for_replaced_element(const ReplacedBox&, const CSS::Length& width); |