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:
parent
ceb055a75e
commit
c1f0d21bbe
10 changed files with 43 additions and 32 deletions
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()); }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue