diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index e563cd0d26b..1d0a6785c9f 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -1134,7 +1134,7 @@ void Document::update_layout() Layout::LayoutState layout_state; { - Layout::BlockFormattingContext root_formatting_context(layout_state, *m_layout_root, nullptr); + Layout::BlockFormattingContext root_formatting_context(layout_state, Layout::LayoutMode::Normal, *m_layout_root, nullptr); auto& viewport = static_cast(*m_layout_root); auto& viewport_state = layout_state.get_mutable(viewport); @@ -1147,7 +1147,6 @@ void Document::update_layout() } root_formatting_context.run( - Layout::LayoutMode::Normal, Layout::AvailableSpace( Layout::AvailableSize::make_definite(viewport_rect.width()), Layout::AvailableSize::make_definite(viewport_rect.height()))); diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp index 0f93c03abdd..e2e89fd48e4 100644 --- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp @@ -23,8 +23,8 @@ namespace Web::Layout { -BlockFormattingContext::BlockFormattingContext(LayoutState& state, BlockContainer const& root, FormattingContext* parent) - : FormattingContext(Type::Block, state, root, parent) +BlockFormattingContext::BlockFormattingContext(LayoutState& state, LayoutMode layout_mode, BlockContainer const& root, FormattingContext* parent) + : FormattingContext(Type::Block, layout_mode, state, root, parent) { } @@ -66,17 +66,17 @@ static bool margins_collapse_through(Box const& box, LayoutState& state) return state.get(box).border_box_height() == 0; } -void BlockFormattingContext::run(LayoutMode layout_mode, AvailableSpace const& available_space) +void BlockFormattingContext::run(AvailableSpace const& available_space) { if (is(root())) { - layout_viewport(layout_mode, available_space); + layout_viewport(available_space); return; } if (root().children_are_inline()) - layout_inline_children(root(), layout_mode, available_space); + layout_inline_children(root(), available_space); else - layout_block_level_children(root(), layout_mode, available_space); + layout_block_level_children(root(), available_space); // Assign collapsed margin left after children layout of formatting context to the last child box if (m_margin_state.current_collapsed_margin() != 0) { @@ -130,7 +130,7 @@ bool BlockFormattingContext::box_should_avoid_floats_because_it_establishes_fc(B return false; } -void BlockFormattingContext::compute_width(Box const& box, AvailableSpace const& available_space, LayoutMode) +void BlockFormattingContext::compute_width(Box const& box, AvailableSpace const& available_space) { if (box.is_absolutely_positioned()) { compute_width_for_absolutely_positioned_element(box, available_space); @@ -466,16 +466,14 @@ void BlockFormattingContext::compute_height(Box const& box, AvailableSpace const box_used_values.set_content_height(height); } -void BlockFormattingContext::layout_inline_children(BlockContainer const& block_container, LayoutMode layout_mode, AvailableSpace const& available_space) +void BlockFormattingContext::layout_inline_children(BlockContainer const& block_container, AvailableSpace const& available_space) { VERIFY(block_container.children_are_inline()); auto& block_container_state = m_state.get_mutable(block_container); - InlineFormattingContext context(m_state, block_container, block_container_state, *this); - context.run( - layout_mode, - available_space); + InlineFormattingContext context(m_state, m_layout_mode, block_container, block_container_state, *this); + context.run(available_space); if (!block_container_state.has_definite_width()) { // NOTE: min-width or max-width for boxes with inline children can only be applied after inside layout @@ -579,7 +577,7 @@ CSSPixels BlockFormattingContext::compute_auto_height_for_block_level_element(Bo return 0; } -void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContainer const& block_container, LayoutMode layout_mode, CSSPixels& bottom_of_lowest_margin_box, AvailableSpace const& available_space) +void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContainer const& block_container, CSSPixels& bottom_of_lowest_margin_box, AvailableSpace const& available_space) { auto& box_state = m_state.get_mutable(box); @@ -598,7 +596,7 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain if (box.is_floating()) { auto const y = m_y_offset_of_current_block_container.value(); auto margin_top = !m_margin_state.has_block_container_waiting_for_final_y_position() ? m_margin_state.current_collapsed_margin() : 0; - layout_floating_box(box, block_container, layout_mode, available_space, margin_top + y); + layout_floating_box(box, block_container, available_space, margin_top + y); bottom_of_lowest_margin_box = max(bottom_of_lowest_margin_box, box_state.offset.y() + box_state.content_height() + box_state.margin_box_bottom()); return; } @@ -620,7 +618,7 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain compute_height(box, available_space); } - auto independent_formatting_context = create_independent_formatting_context_if_needed(m_state, box); + auto independent_formatting_context = create_independent_formatting_context_if_needed(m_state, m_layout_mode, box); // NOTE: It is possible to encounter SVGMaskBox nodes while doing layout of formatting context established by with a mask. // We should skip and let SVGFormattingContext take care of them. @@ -647,7 +645,7 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain place_block_level_element_in_normal_flow_vertically(box, y + margin_top); - compute_width(box, available_space, layout_mode); + compute_width(box, available_space); place_block_level_element_in_normal_flow_horizontally(box, available_space); @@ -677,11 +675,11 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain if (independent_formatting_context) { // This box establishes a new formatting context. Pass control to it. - independent_formatting_context->run(layout_mode, box_state.available_inner_space_or_constraints_from(available_space)); + independent_formatting_context->run(box_state.available_inner_space_or_constraints_from(available_space)); } else { // This box participates in the current block container's flow. if (box.children_are_inline()) { - layout_inline_children(verify_cast(box), layout_mode, box_state.available_inner_space_or_constraints_from(available_space)); + layout_inline_children(verify_cast(box), box_state.available_inner_space_or_constraints_from(available_space)); } else { if (box_state.border_top > 0 || box_state.padding_top > 0) { // margin-top of block container can't collapse with it's children if it has non zero border or padding @@ -695,7 +693,7 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain }); } - layout_block_level_children(verify_cast(box), layout_mode, box_state.available_inner_space_or_constraints_from(available_space)); + layout_block_level_children(verify_cast(box), box_state.available_inner_space_or_constraints_from(available_space)); } } @@ -729,7 +727,7 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain independent_formatting_context->parent_context_did_dimension_child_root_box(); } -void BlockFormattingContext::layout_block_level_children(BlockContainer const& block_container, LayoutMode layout_mode, AvailableSpace const& available_space) +void BlockFormattingContext::layout_block_level_children(BlockContainer const& block_container, AvailableSpace const& available_space) { VERIFY(!block_container.children_are_inline()); @@ -737,13 +735,13 @@ void BlockFormattingContext::layout_block_level_children(BlockContainer const& b TemporaryChange> change { m_y_offset_of_current_block_container, CSSPixels(0) }; block_container.for_each_child_of_type([&](Box& box) { - layout_block_level_box(box, block_container, layout_mode, bottom_of_lowest_margin_box, available_space); + layout_block_level_box(box, block_container, bottom_of_lowest_margin_box, available_space); return IterationDecision::Continue; }); m_margin_state.block_container_y_position_update_callback = {}; - if (layout_mode == LayoutMode::IntrinsicSizing) { + if (m_layout_mode == LayoutMode::IntrinsicSizing) { auto& block_container_state = m_state.get_mutable(block_container); if (!block_container_state.has_definite_width()) { auto width = greatest_child_width(block_container); @@ -910,7 +908,7 @@ void BlockFormattingContext::place_block_level_element_in_normal_flow_horizontal box_state.set_content_offset({ x, box_state.offset.y() }); } -void BlockFormattingContext::layout_viewport(LayoutMode layout_mode, AvailableSpace const& available_space) +void BlockFormattingContext::layout_viewport(AvailableSpace const& available_space) { // NOTE: If we are laying out a standalone SVG document, we give it some special treatment: // The root container gets the same size as the viewport, @@ -919,17 +917,17 @@ void BlockFormattingContext::layout_viewport(LayoutMode layout_mode, AvailableSp auto const& svg_root = verify_cast(*root().first_child()); auto content_height = m_state.get(*svg_root.containing_block()).content_height(); m_state.get_mutable(svg_root).set_content_height(content_height); - auto svg_formatting_context = create_independent_formatting_context_if_needed(m_state, svg_root); - svg_formatting_context->run(layout_mode, available_space); + auto svg_formatting_context = create_independent_formatting_context_if_needed(m_state, m_layout_mode, svg_root); + svg_formatting_context->run(available_space); } else { if (root().children_are_inline()) - layout_inline_children(root(), layout_mode, available_space); + layout_inline_children(root(), available_space); else - layout_block_level_children(root(), layout_mode, available_space); + layout_block_level_children(root(), available_space); } } -void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer const&, LayoutMode layout_mode, AvailableSpace const& available_space, CSSPixels y, LineBuilder* line_builder) +void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer const&, AvailableSpace const& available_space, CSSPixels y, LineBuilder* line_builder) { VERIFY(box.is_floating()); @@ -938,13 +936,13 @@ void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer resolve_vertical_box_model_metrics(box); - compute_width(box, available_space, layout_mode); + compute_width(box, available_space); // 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); - auto independent_formatting_context = layout_inside(box, layout_mode, box_state.available_inner_space_or_constraints_from(available_space)); + auto independent_formatting_context = layout_inside(box, m_layout_mode, box_state.available_inner_space_or_constraints_from(available_space)); compute_height(box, available_space); // First we place the box normally (to get the right y coordinate.) diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h index 291c2c22859..09d3a1a0a71 100644 --- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.h @@ -19,10 +19,10 @@ class LineBuilder; // https://www.w3.org/TR/css-display/#block-formatting-context class BlockFormattingContext : public FormattingContext { public: - explicit BlockFormattingContext(LayoutState&, BlockContainer const&, FormattingContext* parent); + explicit BlockFormattingContext(LayoutState&, LayoutMode layout_mode, BlockContainer const&, FormattingContext* parent); ~BlockFormattingContext(); - virtual void run(LayoutMode, AvailableSpace const&) override; + virtual void run(AvailableSpace const&) override; virtual CSSPixels automatic_content_width() const override; virtual CSSPixels automatic_content_height() const override; @@ -30,7 +30,7 @@ public: auto const& right_side_floats() const { return m_right_floats; } bool box_should_avoid_floats_because_it_establishes_fc(Box const&); - void compute_width(Box const&, AvailableSpace const&, LayoutMode = LayoutMode::Normal); + void compute_width(Box const&, AvailableSpace const&); // https://www.w3.org/TR/css-display/#block-formatting-context-root BlockContainer const& root() const { return static_cast(context_box()); } @@ -47,9 +47,9 @@ public: virtual CSSPixels greatest_child_width(Box const&) const override; - void layout_floating_box(Box const& child, BlockContainer const& containing_block, LayoutMode, AvailableSpace const&, CSSPixels y, LineBuilder* = nullptr); + void layout_floating_box(Box const& child, BlockContainer const& containing_block, AvailableSpace const&, CSSPixels y, LineBuilder* = nullptr); - void layout_block_level_box(Box const&, BlockContainer const&, LayoutMode, CSSPixels& bottom_of_lowest_margin_box, AvailableSpace const&); + void layout_block_level_box(Box const&, BlockContainer const&, CSSPixels& bottom_of_lowest_margin_box, AvailableSpace const&); void resolve_vertical_box_model_metrics(Box const&); @@ -69,10 +69,10 @@ private: void compute_width_for_block_level_replaced_element_in_normal_flow(Box const&, AvailableSpace const&); - void layout_viewport(LayoutMode, AvailableSpace const&); + void layout_viewport(AvailableSpace const&); - void layout_block_level_children(BlockContainer const&, LayoutMode, AvailableSpace const&); - void layout_inline_children(BlockContainer const&, LayoutMode, AvailableSpace const&); + void layout_block_level_children(BlockContainer const&, AvailableSpace const&); + void layout_inline_children(BlockContainer const&, AvailableSpace const&); void place_block_level_element_in_normal_flow_horizontally(Box const& child_box, AvailableSpace const&); void place_block_level_element_in_normal_flow_vertically(Box const&, CSSPixels y); diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 1033853c62f..eeaf75e6f1c 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -28,8 +28,8 @@ CSSPixels FlexFormattingContext::get_pixel_height(Box const& box, CSS::Size cons return calculate_inner_height(box, containing_block_height_as_available_size(box), size); } -FlexFormattingContext::FlexFormattingContext(LayoutState& state, Box const& flex_container, FormattingContext* parent) - : FormattingContext(Type::Flex, state, flex_container, parent) +FlexFormattingContext::FlexFormattingContext(LayoutState& state, LayoutMode layout_mode, Box const& flex_container, FormattingContext* parent) + : FormattingContext(Type::Flex, layout_mode, state, flex_container, parent) , m_flex_container_state(m_state.get_mutable(flex_container)) , m_flex_direction(flex_container.computed_values().flex_direction()) { @@ -47,7 +47,7 @@ CSSPixels FlexFormattingContext::automatic_content_height() const return m_flex_container_state.content_height(); } -void FlexFormattingContext::run(LayoutMode, AvailableSpace const& available_space) +void FlexFormattingContext::run(AvailableSpace const& available_space) { // This implements https://www.w3.org/TR/css-flexbox-1/#layout-algorithm @@ -1126,14 +1126,14 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem& } // Item has definite main size, layout with that as the used main size. - auto independent_formatting_context = create_independent_formatting_context_if_needed(throwaway_state, item.box); + auto independent_formatting_context = create_independent_formatting_context_if_needed(throwaway_state, LayoutMode::Normal, item.box); // NOTE: Flex items should always create an independent formatting context! VERIFY(independent_formatting_context); auto available_width = is_row_layout() ? AvailableSize::make_definite(item.main_size.value()) : AvailableSize::make_indefinite(); auto available_height = is_row_layout() ? AvailableSize::make_indefinite() : AvailableSize::make_definite(item.main_size.value()); - independent_formatting_context->run(LayoutMode::Normal, AvailableSpace(available_width, available_height)); + independent_formatting_context->run(AvailableSpace(available_width, available_height)); auto automatic_cross_size = is_row_layout() ? independent_formatting_context->automatic_content_height() : independent_formatting_context->automatic_content_width(); diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h index a78e5646671..041e6353ad2 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h @@ -13,12 +13,12 @@ namespace Web::Layout { class FlexFormattingContext final : public FormattingContext { public: - FlexFormattingContext(LayoutState&, Box const& flex_container, FormattingContext* parent); + FlexFormattingContext(LayoutState&, LayoutMode, Box const& flex_container, FormattingContext* parent); ~FlexFormattingContext(); virtual bool inhibits_floating() const override { return true; } - virtual void run(LayoutMode, AvailableSpace const&) override; + virtual void run(AvailableSpace const&) override; virtual CSSPixels automatic_content_width() const override; virtual CSSPixels automatic_content_height() const override; diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index 011f52cb093..6b9eb1d145b 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -18,8 +18,9 @@ namespace Web::Layout { -FormattingContext::FormattingContext(Type type, LayoutState& state, Box const& context_box, FormattingContext* parent) +FormattingContext::FormattingContext(Type type, LayoutMode layout_mode, LayoutState& state, Box const& context_box, FormattingContext* parent) : m_type(type) + , m_layout_mode(layout_mode) , m_parent(parent) , m_context_box(context_box) , m_state(state) @@ -154,27 +155,27 @@ Optional FormattingContext::formatting_context_type_cre // FIXME: This is a hack. Get rid of it. struct ReplacedFormattingContext : public FormattingContext { - ReplacedFormattingContext(LayoutState& state, Box const& box) - : FormattingContext(Type::Block, state, box) + ReplacedFormattingContext(LayoutState& state, LayoutMode layout_mode, Box const& box) + : FormattingContext(Type::Block, layout_mode, state, box) { } virtual CSSPixels automatic_content_width() const override { return 0; } virtual CSSPixels automatic_content_height() const override { return 0; } - virtual void run(LayoutMode, AvailableSpace const&) override { } + virtual void run(AvailableSpace const&) override { } }; // FIXME: This is a hack. Get rid of it. struct DummyFormattingContext : public FormattingContext { - DummyFormattingContext(LayoutState& state, Box const& box) - : FormattingContext(Type::Block, state, box) + DummyFormattingContext(LayoutState& state, LayoutMode layout_mode, Box const& box) + : FormattingContext(Type::Block, layout_mode, state, box) { } virtual CSSPixels automatic_content_width() const override { return 0; } virtual CSSPixels automatic_content_height() const override { return 0; } - virtual void run(LayoutMode, AvailableSpace const&) override { } + virtual void run(AvailableSpace const&) override { } }; -OwnPtr FormattingContext::create_independent_formatting_context_if_needed(LayoutState& state, Box const& child_box) +OwnPtr FormattingContext::create_independent_formatting_context_if_needed(LayoutState& state, LayoutMode layout_mode, Box const& child_box) { auto type = formatting_context_type_created_by_box(child_box); if (!type.has_value()) @@ -182,19 +183,19 @@ OwnPtr FormattingContext::create_independent_formatting_conte switch (type.value()) { case Type::Block: - return make(state, verify_cast(child_box), this); + return make(state, layout_mode, verify_cast(child_box), this); case Type::SVG: - return make(state, child_box, this); + return make(state, layout_mode, child_box, this); case Type::Flex: - return make(state, child_box, this); + return make(state, layout_mode, child_box, this); case Type::Grid: - return make(state, child_box, this); + return make(state, layout_mode, child_box, this); case Type::Table: - return make(state, child_box, this); + return make(state, layout_mode, child_box, this); case Type::InternalReplaced: - return make(state, child_box); + return make(state, layout_mode, child_box); case Type::InternalDummy: - return make(state, child_box); + return make(state, layout_mode, child_box); case Type::Inline: // IFC should always be created by a parent BFC directly. VERIFY_NOT_REACHED(); @@ -223,11 +224,11 @@ OwnPtr FormattingContext::layout_inside(Box const& child_box, if (!child_box.can_have_children()) return {}; - auto independent_formatting_context = create_independent_formatting_context_if_needed(m_state, child_box); + auto independent_formatting_context = create_independent_formatting_context_if_needed(m_state, layout_mode, child_box); if (independent_formatting_context) - independent_formatting_context->run(layout_mode, available_space); + independent_formatting_context->run(available_space); else - run(layout_mode, available_space); + run(available_space); return independent_formatting_context; } @@ -423,7 +424,7 @@ CSSPixels FormattingContext::compute_table_box_width_inside_table_wrapper(Box co table_box_state.border_left = table_box_computed_values.border_left().width; table_box_state.border_right = table_box_computed_values.border_right().width; - auto context = make(throwaway_state, *table_box, this); + auto context = make(throwaway_state, LayoutMode::IntrinsicSizing, *table_box, this); context->run_until_width_calculation(m_state.get(*table_box).available_inner_space_or_constraints_from(available_space)); auto table_used_width = throwaway_state.get(*table_box).border_box_width(); @@ -456,9 +457,9 @@ CSSPixels FormattingContext::compute_table_box_height_inside_table_wrapper(Box c auto available_height = height_of_containing_block - margin_top.to_px(box) - margin_bottom.to_px(box); LayoutState throwaway_state(&m_state); - auto context = create_independent_formatting_context_if_needed(throwaway_state, box); + auto context = create_independent_formatting_context_if_needed(throwaway_state, LayoutMode::IntrinsicSizing, box); VERIFY(context); - context->run(LayoutMode::IntrinsicSizing, m_state.get(box).available_inner_space_or_constraints_from(available_space)); + context->run(m_state.get(box).available_inner_space_or_constraints_from(available_space)); Optional table_box; box.for_each_in_subtree_of_type([&](Box const& child_box) { @@ -1453,14 +1454,14 @@ CSSPixels FormattingContext::calculate_min_content_width(Layout::Box const& box) box_state.set_indefinite_content_width(); box_state.set_indefinite_content_height(); - auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, box); + auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, LayoutMode::IntrinsicSizing, box); if (!context) { - context = make(throwaway_state, verify_cast(box), nullptr); + context = make(throwaway_state, LayoutMode::IntrinsicSizing, verify_cast(box), nullptr); } auto available_width = AvailableSize::make_min_content(); auto available_height = AvailableSize::make_indefinite(); - context->run(LayoutMode::IntrinsicSizing, AvailableSpace(available_width, available_height)); + context->run(AvailableSpace(available_width, available_height)); cache.min_content_width = context->automatic_content_width(); @@ -1491,14 +1492,14 @@ CSSPixels FormattingContext::calculate_max_content_width(Layout::Box const& box) box_state.set_indefinite_content_width(); box_state.set_indefinite_content_height(); - auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, box); + auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, LayoutMode::IntrinsicSizing, box); if (!context) { - context = make(throwaway_state, verify_cast(box), nullptr); + context = make(throwaway_state, LayoutMode::IntrinsicSizing, verify_cast(box), nullptr); } auto available_width = AvailableSize::make_max_content(); auto available_height = AvailableSize::make_indefinite(); - context->run(LayoutMode::IntrinsicSizing, AvailableSpace(available_width, available_height)); + context->run(AvailableSpace(available_width, available_height)); cache.max_content_width = context->automatic_content_width(); @@ -1537,12 +1538,12 @@ CSSPixels FormattingContext::calculate_min_content_height(Layout::Box const& box box_state.set_indefinite_content_height(); box_state.set_content_width(width); - auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, box); + auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, LayoutMode::IntrinsicSizing, box); if (!context) { - context = make(throwaway_state, verify_cast(box), nullptr); + context = make(throwaway_state, LayoutMode::IntrinsicSizing, verify_cast(box), nullptr); } - context->run(LayoutMode::IntrinsicSizing, AvailableSpace(AvailableSize::make_definite(width), AvailableSize::make_min_content())); + context->run(AvailableSpace(AvailableSize::make_definite(width), AvailableSize::make_min_content())); auto min_content_height = context->automatic_content_height(); if (min_content_height.might_be_saturated()) { @@ -1581,12 +1582,12 @@ CSSPixels FormattingContext::calculate_max_content_height(Layout::Box const& box box_state.set_indefinite_content_height(); box_state.set_content_width(width); - auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, box); + auto context = const_cast(this)->create_independent_formatting_context_if_needed(throwaway_state, LayoutMode::IntrinsicSizing, box); if (!context) { - context = make(throwaway_state, verify_cast(box), nullptr); + context = make(throwaway_state, LayoutMode::IntrinsicSizing, verify_cast(box), nullptr); } - context->run(LayoutMode::IntrinsicSizing, AvailableSpace(AvailableSize::make_definite(width), AvailableSize::make_max_content())); + context->run(AvailableSpace(AvailableSize::make_definite(width), AvailableSize::make_max_content())); auto max_content_height = context->automatic_content_height(); diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.h b/Userland/Libraries/LibWeb/Layout/FormattingContext.h index 82e9dad46ae..cf64a952d16 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.h @@ -36,7 +36,7 @@ public: InternalDummy, // Internal hack formatting context for unimplemented things. FIXME: Get rid of this. }; - virtual void run(LayoutMode, AvailableSpace const&) = 0; + virtual void run(AvailableSpace const&) = 0; // This function returns the automatic content height of the context's root box. virtual CSSPixels automatic_content_width() const = 0; @@ -64,7 +64,7 @@ public: CSSPixels compute_width_for_replaced_element(Box const&, AvailableSpace const&) const; CSSPixels compute_height_for_replaced_element(Box const&, AvailableSpace const&) const; - OwnPtr create_independent_formatting_context_if_needed(LayoutState&, Box const& child_box); + OwnPtr create_independent_formatting_context_if_needed(LayoutState&, LayoutMode, Box const& child_box); virtual void parent_context_did_dimension_child_root_box() { } @@ -113,7 +113,7 @@ public: void compute_inset(NodeWithStyleAndBoxModelMetrics const&); protected: - FormattingContext(Type, LayoutState&, Box const&, FormattingContext* parent = nullptr); + FormattingContext(Type, LayoutMode, LayoutState&, Box const&, FormattingContext* parent = nullptr); static bool should_treat_width_as_auto(Box const&, AvailableSpace const&); static bool should_treat_height_as_auto(Box const&, AvailableSpace const&); @@ -170,6 +170,7 @@ protected: [[nodiscard]] Box const* box_child_to_derive_baseline_from(Box const&) const; Type m_type {}; + LayoutMode m_layout_mode; FormattingContext* m_parent { nullptr }; JS::NonnullGCPtr m_context_box; diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp index abfcc5041ae..dda7e706aaf 100644 --- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -65,8 +65,8 @@ GridFormattingContext::GridTrack GridFormattingContext::GridTrack::create_gap(CS }; } -GridFormattingContext::GridFormattingContext(LayoutState& state, Box const& grid_container, FormattingContext* parent) - : FormattingContext(Type::Grid, state, grid_container, parent) +GridFormattingContext::GridFormattingContext(LayoutState& state, LayoutMode layout_mode, Box const& grid_container, FormattingContext* parent) + : FormattingContext(Type::Grid, layout_mode, state, grid_container, parent) { } @@ -1771,7 +1771,7 @@ CSSPixelRect GridFormattingContext::get_grid_area_rect(GridItem const& grid_item return { x_start, y_start, x_end - x_start, y_end - y_start }; } -void GridFormattingContext::run(LayoutMode, AvailableSpace const& available_space) +void GridFormattingContext::run(AvailableSpace const& available_space) { m_available_space = available_space; diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h index 6977e60282f..61e4c0c6e73 100644 --- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h @@ -101,12 +101,12 @@ private: class GridFormattingContext final : public FormattingContext { public: - explicit GridFormattingContext(LayoutState&, Box const& grid_container, FormattingContext* parent); + explicit GridFormattingContext(LayoutState&, LayoutMode, Box const& grid_container, FormattingContext* parent); ~GridFormattingContext(); virtual bool inhibits_floating() const override { return true; } - virtual void run(LayoutMode, AvailableSpace const& available_space) override; + virtual void run(AvailableSpace const& available_space) override; virtual CSSPixels automatic_content_width() const override; virtual CSSPixels automatic_content_height() const override; diff --git a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index 97909cc18b4..d681fe3bd5a 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -20,10 +20,11 @@ namespace Web::Layout { InlineFormattingContext::InlineFormattingContext( LayoutState& state, + LayoutMode layout_mode, BlockContainer const& containing_block, LayoutState::UsedValues& containing_block_used_values, BlockFormattingContext& parent) - : FormattingContext(Type::Inline, state, containing_block, &parent) + : FormattingContext(Type::Inline, layout_mode, state, containing_block, &parent) , m_containing_block_used_values(containing_block_used_values) { } @@ -77,11 +78,11 @@ CSSPixels InlineFormattingContext::automatic_content_height() const return m_automatic_content_height; } -void InlineFormattingContext::run(LayoutMode layout_mode, AvailableSpace const& available_space) +void InlineFormattingContext::run(AvailableSpace const& available_space) { VERIFY(containing_block().children_are_inline()); m_available_space = available_space; - generate_line_boxes(layout_mode); + generate_line_boxes(); CSSPixels content_height = 0; @@ -244,14 +245,14 @@ void InlineFormattingContext::apply_justification_to_fragments(CSS::TextJustify } } -void InlineFormattingContext::generate_line_boxes(LayoutMode layout_mode) +void InlineFormattingContext::generate_line_boxes() { auto& line_boxes = m_containing_block_used_values.line_boxes; line_boxes.clear_with_capacity(); auto direction = m_context_box->computed_values().direction(); - InlineLevelIterator iterator(*this, m_state, containing_block(), m_containing_block_used_values, layout_mode); + InlineLevelIterator iterator(*this, m_state, containing_block(), m_containing_block_used_values, m_layout_mode); LineBuilder line_builder(*this, m_state, m_containing_block_used_values, direction); // NOTE: When we ignore collapsible whitespace chunks at the start of a line, @@ -313,7 +314,7 @@ void InlineFormattingContext::generate_line_boxes(LayoutMode layout_mode) auto introduce_clearance = parent().clear_floating_boxes(*item.node, *this); if (introduce_clearance == BlockFormattingContext::DidIntroduceClearance::Yes) parent().reset_margin_state(); - parent().layout_floating_box(static_cast(*item.node), containing_block(), layout_mode, *m_available_space, 0, &line_builder); + parent().layout_floating_box(static_cast(*item.node), containing_block(), *m_available_space, 0, &line_builder); } break; diff --git a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h index f7e40f53599..d80e694de1d 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/InlineFormattingContext.h @@ -15,7 +15,7 @@ namespace Web::Layout { class InlineFormattingContext final : public FormattingContext { public: - InlineFormattingContext(LayoutState&, BlockContainer const& containing_block, LayoutState::UsedValues& containing_block_used_values, BlockFormattingContext& parent); + InlineFormattingContext(LayoutState&, LayoutMode, BlockContainer const& containing_block, LayoutState::UsedValues& containing_block_used_values, BlockFormattingContext& parent); ~InlineFormattingContext(); BlockFormattingContext& parent(); @@ -23,7 +23,7 @@ public: BlockContainer const& containing_block() const { return static_cast(context_box()); } - virtual void run(LayoutMode, AvailableSpace const&) override; + virtual void run(AvailableSpace const&) override; virtual CSSPixels automatic_content_height() const override; virtual CSSPixels automatic_content_width() const override; @@ -38,7 +38,7 @@ public: void set_vertical_float_clearance(CSSPixels); private: - void generate_line_boxes(LayoutMode); + void generate_line_boxes(); void apply_justification_to_fragments(CSS::TextJustify, LineBox&, bool is_last_line); LayoutState::UsedValues& m_containing_block_used_values; diff --git a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp index b991cd82af7..fca87711090 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp @@ -30,8 +30,8 @@ namespace Web::Layout { -SVGFormattingContext::SVGFormattingContext(LayoutState& state, Box const& box, FormattingContext* parent, Gfx::AffineTransform parent_viewbox_transform) - : FormattingContext(Type::SVG, state, box, parent) +SVGFormattingContext::SVGFormattingContext(LayoutState& state, LayoutMode layout_mode, Box const& box, FormattingContext* parent, Gfx::AffineTransform parent_viewbox_transform) + : FormattingContext(Type::SVG, layout_mode, state, box, parent) , m_parent_viewbox_transform(parent_viewbox_transform) { } @@ -171,7 +171,7 @@ static bool is_container_element(Node const& node) return false; } -void SVGFormattingContext::run(LayoutMode, AvailableSpace const& available_space) +void SVGFormattingContext::run(AvailableSpace const& available_space) { // NOTE: SVG doesn't have a "formatting context" in the spec, but this is the most // obvious way to drive SVG layout in our engine at the moment. @@ -265,8 +265,8 @@ void SVGFormattingContext::layout_svg_element(Box const& child) if (is(child.dom_node())) { layout_nested_viewport(child); } else if (is(child.dom_node()) && is(child)) { - Layout::BlockFormattingContext bfc(m_state, static_cast(child), this); - bfc.run(LayoutMode::Normal, *m_available_space); + Layout::BlockFormattingContext bfc(m_state, LayoutMode::Normal, static_cast(child), this); + bfc.run(*m_available_space); auto& child_state = m_state.get_mutable(child); child_state.set_content_offset(child_state.offset.translated(m_svg_offset)); child.for_each_child_of_type([&](SVGMaskBox const& child) { @@ -282,7 +282,7 @@ void SVGFormattingContext::layout_nested_viewport(Box const& viewport) { // Layout for a nested SVG viewport. // https://svgwg.org/svg2-draft/coords.html#EstablishingANewSVGViewport. - SVGFormattingContext nested_context(m_state, viewport, this, m_current_viewbox_transform); + SVGFormattingContext nested_context(m_state, LayoutMode::Normal, viewport, this, m_current_viewbox_transform); auto& nested_viewport_state = m_state.get_mutable(viewport); auto resolve_dimension = [](auto& node, auto size, auto reference_value) { // The value auto for width and height on the ‘svg’ element is treated as 100%. @@ -301,7 +301,7 @@ void SVGFormattingContext::layout_nested_viewport(Box const& viewport) nested_viewport_state.set_content_height(nested_viewport_height); nested_viewport_state.set_has_definite_width(true); nested_viewport_state.set_has_definite_height(true); - nested_context.run(LayoutMode::Normal, *m_available_space); + nested_context.run(*m_available_space); } Gfx::Path SVGFormattingContext::compute_path_for_text(SVGTextBox const& text_box) @@ -456,10 +456,10 @@ void SVGFormattingContext::layout_mask_or_clip(SVGBox const& mask_or_clip) layout_state.set_content_height(m_viewport_size.height()); } // Pretend masks/clips are a viewport so we can scale the contents depending on the `contentUnits`. - SVGFormattingContext nested_context(m_state, mask_or_clip, this, parent_viewbox_transform); + SVGFormattingContext nested_context(m_state, LayoutMode::Normal, mask_or_clip, this, parent_viewbox_transform); layout_state.set_has_definite_width(true); layout_state.set_has_definite_height(true); - nested_context.run(LayoutMode::Normal, *m_available_space); + nested_context.run(*m_available_space); } void SVGFormattingContext::layout_container_element(SVGBox const& container) diff --git a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h index 051870ecbbb..b220c907139 100644 --- a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.h @@ -18,10 +18,10 @@ namespace Web::Layout { class SVGFormattingContext : public FormattingContext { public: - explicit SVGFormattingContext(LayoutState&, Box const&, FormattingContext* parent, Gfx::AffineTransform parent_viewbox_transform = {}); + explicit SVGFormattingContext(LayoutState&, LayoutMode, Box const&, FormattingContext* parent, Gfx::AffineTransform parent_viewbox_transform = {}); ~SVGFormattingContext(); - virtual void run(LayoutMode, AvailableSpace const&) override; + virtual void run(AvailableSpace const&) override; virtual CSSPixels automatic_content_width() const override; virtual CSSPixels automatic_content_height() const override; diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp index 007c2948116..2e6923e990f 100644 --- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp @@ -14,8 +14,8 @@ namespace Web::Layout { -TableFormattingContext::TableFormattingContext(LayoutState& state, Box const& root, FormattingContext* parent) - : FormattingContext(Type::Table, state, root, parent) +TableFormattingContext::TableFormattingContext(LayoutState& state, LayoutMode layout_mode, Box const& root, FormattingContext* parent) + : FormattingContext(Type::Table, layout_mode, state, root, parent) { } @@ -31,7 +31,7 @@ static inline bool is_table_column(Box const& box) return box.display().is_table_column(); } -CSSPixels TableFormattingContext::run_caption_layout(LayoutMode layout_mode, CSS::CaptionSide phase) +CSSPixels TableFormattingContext::run_caption_layout(CSS::CaptionSide phase) { CSSPixels caption_height = 0; for (auto* child = table_box().first_child(); child; child = child->next_sibling()) { @@ -40,8 +40,8 @@ CSSPixels TableFormattingContext::run_caption_layout(LayoutMode layout_mode, CSS } // The caption boxes are principal block-level boxes that retain their own content, padding, margin, and border areas, // and are rendered as normal block boxes inside the table wrapper box, as described in https://www.w3.org/TR/CSS22/tables.html#model - auto caption_context = make(m_state, *verify_cast(child), this); - caption_context->run(layout_mode, *m_available_space); + auto caption_context = make(m_state, m_layout_mode, *verify_cast(child), this); + caption_context->run(*m_available_space); VERIFY(child->is_box()); auto const& child_box = static_cast(*child); // FIXME: Since caption only has inline children, BlockFormattingContext doesn't resolve the vertical metrics. @@ -828,7 +828,7 @@ void TableFormattingContext::distribute_excess_width_to_columns_fixed_mode(CSSPi distribute_excess_width_equally(excess_width, [](auto const& column) { return column.used_width == 0; }); } -void TableFormattingContext::compute_table_height(LayoutMode layout_mode) +void TableFormattingContext::compute_table_height() { // First pass of row height calculation: for (auto& row : m_rows) { @@ -878,7 +878,7 @@ void TableFormattingContext::compute_table_height(LayoutMode layout_mode) // - the horizontal/vertical border-spacing times the amount of spanned visible columns/rows minus one // FIXME: Account for visibility. cell_state.set_content_width(span_width - cell_state.border_box_left() - cell_state.border_box_right() + (cell.column_span - 1) * border_spacing_horizontal()); - if (auto independent_formatting_context = layout_inside(cell.box, layout_mode, cell_state.available_inner_space_or_constraints_from(*m_available_space))) { + if (auto independent_formatting_context = layout_inside(cell.box, m_layout_mode, cell_state.available_inner_space_or_constraints_from(*m_available_space))) { cell_state.set_content_height(independent_formatting_context->automatic_content_height()); independent_formatting_context->parent_context_did_dimension_child_root_box(); } @@ -961,7 +961,7 @@ void TableFormattingContext::compute_table_height(LayoutMode layout_mode) } cell_state.set_content_width(span_width - cell_state.border_box_left() - cell_state.border_box_right() + (cell.column_span - 1) * border_spacing_horizontal()); - if (auto independent_formatting_context = layout_inside(cell.box, layout_mode, cell_state.available_inner_space_or_constraints_from(*m_available_space))) { + if (auto independent_formatting_context = layout_inside(cell.box, m_layout_mode, cell_state.available_inner_space_or_constraints_from(*m_available_space))) { independent_formatting_context->parent_context_did_dimension_child_root_box(); } @@ -1607,11 +1607,11 @@ void TableFormattingContext::run_until_width_calculation(AvailableSpace const& a compute_table_width(); } -void TableFormattingContext::run(LayoutMode layout_mode, AvailableSpace const& available_space) +void TableFormattingContext::run(AvailableSpace const& available_space) { m_available_space = available_space; - auto total_captions_height = run_caption_layout(layout_mode, CSS::CaptionSide::Top); + auto total_captions_height = run_caption_layout(CSS::CaptionSide::Top); run_until_width_calculation(available_space); @@ -1622,7 +1622,7 @@ void TableFormattingContext::run(LayoutMode layout_mode, AvailableSpace const& a // Distribute the width of the table among columns. distribute_width_to_columns(); - compute_table_height(layout_mode); + compute_table_height(); distribute_height_to_rows(); @@ -1631,7 +1631,7 @@ void TableFormattingContext::run(LayoutMode layout_mode, AvailableSpace const& a m_state.get_mutable(table_box()).set_content_height(m_table_height); - total_captions_height += run_caption_layout(layout_mode, CSS::CaptionSide::Bottom); + total_captions_height += run_caption_layout(CSS::CaptionSide::Bottom); // Table captions are positioned between the table margins and its borders (outside the grid box borders) as described in // https://www.w3.org/TR/css-tables-3/#bounding-box-assignment diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h index 6c01d6f86aa..e8c9ae8754e 100644 --- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.h @@ -20,12 +20,12 @@ enum class TableDimension { class TableFormattingContext final : public FormattingContext { public: - explicit TableFormattingContext(LayoutState&, Box const&, FormattingContext* parent); + explicit TableFormattingContext(LayoutState&, LayoutMode, Box const&, FormattingContext* parent); ~TableFormattingContext(); void run_until_width_calculation(AvailableSpace const& available_space); - virtual void run(LayoutMode, AvailableSpace const&) override; + virtual void run(AvailableSpace const&) override; virtual CSSPixels automatic_content_width() const override; virtual CSSPixels automatic_content_height() const override; @@ -38,7 +38,7 @@ public: static bool border_is_less_specific(const CSS::BorderData& a, const CSS::BorderData& b); private: - CSSPixels run_caption_layout(LayoutMode, CSS::CaptionSide); + CSSPixels run_caption_layout(CSS::CaptionSide); CSSPixels compute_capmin(); void compute_constrainedness(); void compute_cell_measures(); @@ -53,7 +53,7 @@ private: void distribute_width_to_columns(); void distribute_excess_width_to_columns(CSSPixels available_width); void distribute_excess_width_to_columns_fixed_mode(CSSPixels excess_width); - void compute_table_height(LayoutMode layout_mode); + void compute_table_height(); void distribute_height_to_rows(); void position_row_boxes(); void position_cell_boxes();