mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-20 17:58:18 +03:00
LibWeb: Introduce simple scrollable overflow, size ICB to viewport
Per spec, the initial containing block (ICB) should have the size of the viewport. We have only done this for the width until now, since we had no way to express scrollable overflow. This patch adds Layout::Box::m_overflow_data, an optional struct that can hold on to information about a box's overflow. Then we have BFC set the ICB up with some scrollable overflow instead of sizing it to fit its content vertically. This fixes a number of broken layouts where correctness depends on having the appropriate ICB height.
This commit is contained in:
parent
c94873806c
commit
27d4ac316f
Notes:
sideshowbarker
2024-07-18 02:22:27 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/27d4ac316fb
@ -571,20 +571,24 @@ void BlockFormattingContext::layout_initial_containing_block(LayoutMode layout_m
|
||||
icb.build_stacking_context_tree();
|
||||
|
||||
icb.set_width(viewport_rect.width());
|
||||
|
||||
layout_block_level_children(root(), layout_mode);
|
||||
icb.set_height(viewport_rect.height());
|
||||
|
||||
VERIFY(!icb.children_are_inline());
|
||||
layout_block_level_children(root(), layout_mode);
|
||||
|
||||
// FIXME: The ICB should have the height of the viewport.
|
||||
// Instead of auto-sizing the ICB, we should spill into overflow.
|
||||
// Compute scrollable overflow.
|
||||
float lowest_bottom = 0;
|
||||
icb.for_each_child_of_type<Box>([&](auto& child) {
|
||||
lowest_bottom = max(lowest_bottom, child.absolute_rect().bottom());
|
||||
});
|
||||
|
||||
// FIXME: This is a hack and should be managed by an overflow mechanism.
|
||||
icb.set_height(max(static_cast<float>(viewport_rect.height()), lowest_bottom));
|
||||
if (lowest_bottom >= viewport_rect.height()) {
|
||||
auto& overflow_data = icb.ensure_overflow_data();
|
||||
overflow_data.scrollable_overflow_rect = viewport_rect.to_type<float>();
|
||||
overflow_data.scrollable_overflow_rect.set_height(lowest_bottom);
|
||||
} else {
|
||||
icb.clear_overflow_data();
|
||||
}
|
||||
}
|
||||
|
||||
static Gfx::FloatRect rect_in_coordinate_space(const Box& box, const Box& context_box)
|
||||
|
@ -16,6 +16,11 @@ namespace Web::Layout {
|
||||
|
||||
class Box : public NodeWithStyleAndBoxModelMetrics {
|
||||
public:
|
||||
struct OverflowData {
|
||||
Gfx::FloatRect scrollable_overflow_rect;
|
||||
Gfx::FloatPoint scroll_offset;
|
||||
};
|
||||
|
||||
const Gfx::FloatRect absolute_rect() const;
|
||||
|
||||
Gfx::FloatPoint effective_offset() const;
|
||||
@ -129,6 +134,24 @@ public:
|
||||
bool has_intrinsic_height() const { return intrinsic_height().has_value(); }
|
||||
bool has_intrinsic_aspect_ratio() const { return intrinsic_aspect_ratio().has_value(); }
|
||||
|
||||
bool has_overflow() const { return m_overflow_data; }
|
||||
|
||||
Optional<Gfx::FloatRect> scrollable_overflow_rect() const
|
||||
{
|
||||
if (!m_overflow_data)
|
||||
return {};
|
||||
return m_overflow_data->scrollable_overflow_rect;
|
||||
}
|
||||
|
||||
OverflowData& ensure_overflow_data()
|
||||
{
|
||||
if (!m_overflow_data)
|
||||
m_overflow_data = make<OverflowData>();
|
||||
return *m_overflow_data;
|
||||
}
|
||||
|
||||
void clear_overflow_data() { m_overflow_data = nullptr; }
|
||||
|
||||
protected:
|
||||
Box(DOM::Document& document, DOM::Node* node, NonnullRefPtr<CSS::StyleProperties> style)
|
||||
: NodeWithStyleAndBoxModelMetrics(document, node, move(style))
|
||||
@ -152,6 +175,8 @@ private:
|
||||
WeakPtr<LineBoxFragment> m_containing_line_box_fragment;
|
||||
|
||||
OwnPtr<StackingContext> m_stacking_context;
|
||||
|
||||
OwnPtr<OverflowData> m_overflow_data;
|
||||
};
|
||||
|
||||
template<>
|
||||
|
@ -102,7 +102,11 @@ void PageHost::page_did_layout()
|
||||
{
|
||||
auto* layout_root = this->layout_root();
|
||||
VERIFY(layout_root);
|
||||
auto content_size = enclosing_int_rect(layout_root->absolute_rect()).size();
|
||||
Gfx::IntSize content_size;
|
||||
if (layout_root->has_overflow())
|
||||
content_size = enclosing_int_rect(layout_root->scrollable_overflow_rect().value()).size();
|
||||
else
|
||||
content_size = enclosing_int_rect(layout_root->absolute_rect()).size();
|
||||
m_client.async_did_layout(content_size);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user