1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 03:08:13 +00:00

LibWeb: Rename the LayoutMode enum values and explain them

The old mode names, while mechanically accurate, didn't really reflect
their relationship to the CSS specifications.

This patch renames them as follows:

    Default => Normal
    AllPossibleLineBreaks => MinContent
    OnlyRequiredLineBreaks => MaxContent

There's also now an explainer comment with the LayoutMode enum about the
specific implications of layout in each mode.
This commit is contained in:
Andreas Kling 2022-03-19 15:44:02 +01:00
parent ceb055a75e
commit c1f0d21bbe
10 changed files with 43 additions and 32 deletions

View file

@ -577,7 +577,7 @@ void Document::update_layout()
icb.set_has_definite_width(true);
icb.set_has_definite_height(true);
root_formatting_context.run(*m_layout_root, Layout::LayoutMode::Default);
root_formatting_context.run(*m_layout_root, Layout::LayoutMode::Normal);
formatting_state.commit();
m_layout_root->build_stacking_context_tree();

View file

@ -224,13 +224,13 @@ void BlockFormattingContext::compute_width_for_floating_box(Box const& box, Layo
float width_of_containing_block = 0;
switch (layout_mode) {
case LayoutMode::Default:
case LayoutMode::Normal:
width_of_containing_block = m_state.get(containing_block).content_width;
break;
case LayoutMode::AllPossibleLineBreaks:
case LayoutMode::MinContent:
width_of_containing_block = 0;
break;
case LayoutMode::OnlyRequiredLineBreaks:
case LayoutMode::MaxContent:
width_of_containing_block = INFINITY;
break;
}
@ -408,7 +408,7 @@ void BlockFormattingContext::layout_block_level_children(BlockContainer const& b
return IterationDecision::Continue;
});
if (layout_mode != LayoutMode::Default) {
if (layout_mode != LayoutMode::Normal) {
auto& width = block_container.computed_values().width();
if (!width.has_value() || (width->is_length() && width->length().is_auto())) {
auto& block_container_state = m_state.get_mutable(block_container);
@ -559,13 +559,13 @@ void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer
float width_of_containing_block = 0;
switch (layout_mode) {
case LayoutMode::Default:
case LayoutMode::Normal:
width_of_containing_block = m_state.get(containing_block).content_width;
break;
case LayoutMode::AllPossibleLineBreaks:
case LayoutMode::MinContent:
width_of_containing_block = 0;
break;
case LayoutMode::OnlyRequiredLineBreaks:
case LayoutMode::MaxContent:
width_of_containing_block = INFINITY;
break;
}

View file

@ -27,7 +27,7 @@ public:
auto const& right_side_floats() const { return m_right_floats; }
static float compute_theoretical_height(FormattingState const&, Box const&);
void compute_width(Box const&, LayoutMode = LayoutMode::Default);
void compute_width(Box const&, LayoutMode = LayoutMode::Normal);
// https://www.w3.org/TR/css-display/#block-formatting-context-root
BlockContainer const& root() const { return static_cast<BlockContainer const&>(context_box()); }

View file

@ -112,7 +112,7 @@ void FlexFormattingContext::run(Box const& run_box, LayoutMode)
// AD-HOC: Layout the inside of all flex items.
copy_dimensions_from_flex_items_to_boxes();
for (auto& flex_item : m_flex_items) {
auto independent_formatting_context = layout_inside(flex_item.box, LayoutMode::Default);
auto independent_formatting_context = layout_inside(flex_item.box, LayoutMode::Normal);
independent_formatting_context->parent_context_did_dimension_child_root_box();
}
@ -451,7 +451,7 @@ float FlexFormattingContext::calculate_indefinite_main_size(FlexItem const& item
} else {
box_state.content_width = resolved_definite_cross_size(item.box);
}
independent_formatting_context->run(item.box, LayoutMode::Default);
independent_formatting_context->run(item.box, LayoutMode::Normal);
if (is_row_layout())
return box_state.content_width;
@ -477,7 +477,7 @@ float FlexFormattingContext::calculate_indefinite_main_size(FlexItem const& item
VERIFY(independent_formatting_context);
box_state.content_width = fit_content_cross_size;
independent_formatting_context->run(item.box, LayoutMode::Default);
independent_formatting_context->run(item.box, LayoutMode::Normal);
return BlockFormattingContext::compute_theoretical_height(throwaway_state, item.box);
}
@ -825,7 +825,7 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem&
} else {
box_state.content_height = resolved_definite_main_size(item.box);
}
independent_formatting_context->run(item.box, LayoutMode::Default);
independent_formatting_context->run(item.box, LayoutMode::Normal);
if (is_row_layout())
item.hypothetical_cross_size = BlockFormattingContext::compute_theoretical_height(throwaway_state, item.box);
@ -854,7 +854,7 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem&
VERIFY(independent_formatting_context);
box_state.content_width = fit_content_main_size;
independent_formatting_context->run(item.box, LayoutMode::Default);
independent_formatting_context->run(item.box, LayoutMode::Normal);
item.hypothetical_cross_size = BlockFormattingContext::compute_theoretical_height(throwaway_state, item.box);
}

View file

@ -692,7 +692,7 @@ void FormattingContext::layout_absolutely_positioned_element(Box const& box)
auto specified_width = box.computed_values().width().has_value() ? box.computed_values().width()->resolved(box, width_of_containing_block).resolved(box) : CSS::Length::make_auto();
compute_width_for_absolutely_positioned_element(box);
auto independent_formatting_context = layout_inside(box, LayoutMode::Default);
auto independent_formatting_context = layout_inside(box, LayoutMode::Normal);
compute_height_for_absolutely_positioned_element(box);
box_state.margin_left = box.computed_values().margin().left.resolved(box, width_of_containing_block).to_px(box);
@ -824,7 +824,7 @@ FormattingState::IntrinsicSizes FormattingContext::calculate_intrinsic_sizes(Lay
auto independent_formatting_context = const_cast<FormattingContext*>(this)->create_independent_formatting_context_if_needed(throwaway_state, box);
VERIFY(independent_formatting_context);
independent_formatting_context->run(box, LayoutMode::OnlyRequiredLineBreaks);
independent_formatting_context->run(box, LayoutMode::MaxContent);
cached_box_sizes.max_content_size.set_width(independent_formatting_context->greatest_child_width(box));
cached_box_sizes.max_content_size.set_height(BlockFormattingContext::compute_theoretical_height(throwaway_state, box));
}
@ -836,7 +836,7 @@ FormattingState::IntrinsicSizes FormattingContext::calculate_intrinsic_sizes(Lay
containing_block_state.content_height = 0;
auto independent_formatting_context = const_cast<FormattingContext*>(this)->create_independent_formatting_context_if_needed(throwaway_state, box);
VERIFY(independent_formatting_context);
independent_formatting_context->run(box, LayoutMode::AllPossibleLineBreaks);
independent_formatting_context->run(box, LayoutMode::MinContent);
cached_box_sizes.min_content_size.set_width(independent_formatting_context->greatest_child_width(box));
cached_box_sizes.min_content_size.set_height(BlockFormattingContext::compute_theoretical_height(throwaway_state, box));
}

View file

@ -84,7 +84,7 @@ void InlineFormattingContext::run(Box const&, LayoutMode layout_mode)
auto& containing_block_state = m_state.get_mutable(containing_block());
if (layout_mode != LayoutMode::Default) {
if (layout_mode != LayoutMode::Normal) {
containing_block_state.content_width = max_line_width;
}

View file

@ -37,13 +37,13 @@ void LineBuilder::begin_new_line(bool increment_y)
m_current_y += max(m_max_height_on_current_line, m_context.containing_block().line_height());
switch (m_layout_mode) {
case LayoutMode::Default:
case LayoutMode::Normal:
m_available_width_for_current_line = m_context.available_space_for_line(m_current_y);
break;
case LayoutMode::AllPossibleLineBreaks:
case LayoutMode::MinContent:
m_available_width_for_current_line = 0;
break;
case LayoutMode::OnlyRequiredLineBreaks:
case LayoutMode::MaxContent:
m_available_width_for_current_line = INFINITY;
break;
}
@ -81,11 +81,11 @@ void LineBuilder::append_text_chunk(TextNode const& text_node, size_t offset_in_
bool LineBuilder::should_break(LayoutMode layout_mode, float next_item_width, bool should_force_break)
{
if (layout_mode == LayoutMode::AllPossibleLineBreaks)
if (layout_mode == LayoutMode::MinContent)
return true;
if (should_force_break)
return true;
if (layout_mode == LayoutMode::OnlyRequiredLineBreaks)
if (layout_mode == LayoutMode::MaxContent)
return false;
auto const& line_boxes = m_containing_block_state.line_boxes;
if (line_boxes.is_empty() || line_boxes.last().is_empty())

View file

@ -21,9 +21,20 @@
namespace Web::Layout {
enum class LayoutMode {
Default,
AllPossibleLineBreaks,
OnlyRequiredLineBreaks,
// Normal layout.
// - We use the containing block's used width.
// - Content flows into the available space, line breaks inserted where necessary.
Normal,
// MinContent layout is used for discovering the min-content intrinsic size of a box.
// - We act as if the containing block has 0 used width.
// - Every line-breaking opportunity is taken.
MinContent,
// MaxContent layout is used for discovering the max-content intrinsic size of a box.
// - We act as if the containing block has infinite used width.
// - Only forced line-breaking opportunities are taken.
MaxContent,
};
class Node : public TreeNode<Node> {

View file

@ -81,9 +81,9 @@ void TableFormattingContext::calculate_column_widths(Box const& row, Vector<floa
auto& cell_state = m_state.get_mutable(cell);
compute_width(cell);
if (use_auto_layout) {
(void)layout_inside(cell, LayoutMode::OnlyRequiredLineBreaks);
(void)layout_inside(cell, LayoutMode::MaxContent);
} else {
(void)layout_inside(cell, LayoutMode::Default);
(void)layout_inside(cell, LayoutMode::Normal);
}
column_widths[column_index] = max(column_widths[column_index], cell_state.content_width);
column_index += cell.colspan();
@ -105,9 +105,9 @@ void TableFormattingContext::layout_row(Box const& row, Vector<float>& column_wi
// Layout the cell contents a second time, now that we know its final width.
if (use_auto_layout) {
(void)layout_inside(cell, LayoutMode::OnlyRequiredLineBreaks);
(void)layout_inside(cell, LayoutMode::MaxContent);
} else {
(void)layout_inside(cell, LayoutMode::Default);
(void)layout_inside(cell, LayoutMode::Normal);
}
BlockFormattingContext::compute_height(cell, m_state);

View file

@ -141,7 +141,7 @@ Optional<TextNode::Chunk> TextNode::ChunkIterator::next()
}
}
if (m_wrap_lines || m_layout_mode == LayoutMode::AllPossibleLineBreaks) {
if (m_wrap_lines || m_layout_mode == LayoutMode::MinContent) {
bool is_space = is_ascii_space(*m_iterator);
if (is_space != m_last_was_space) {
m_last_was_space = is_space;
@ -163,7 +163,7 @@ Optional<TextNode::Chunk> TextNode::ChunkIterator::next()
Optional<TextNode::Chunk> TextNode::ChunkIterator::try_commit_chunk(Utf8View::Iterator const& start, Utf8View::Iterator const& end, bool has_breaking_newline, bool must_commit) const
{
if (m_layout_mode == LayoutMode::OnlyRequiredLineBreaks && !must_commit)
if (m_layout_mode == LayoutMode::MaxContent && !must_commit)
return {};
auto byte_offset = m_utf8_view.byte_offset_of(start);