summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibWeb/DOM/Document.cpp4
-rw-r--r--Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp6
-rw-r--r--Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp14
-rw-r--r--Userland/Libraries/LibWeb/Layout/FormattingContext.cpp12
-rw-r--r--Userland/Libraries/LibWeb/Layout/LayoutState.cpp47
-rw-r--r--Userland/Libraries/LibWeb/Layout/LayoutState.h14
-rw-r--r--Userland/Libraries/LibWeb/Layout/Node.cpp35
-rw-r--r--Userland/Libraries/LibWeb/Layout/Node.h9
8 files changed, 71 insertions, 70 deletions
diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp
index d6aa84af5c..d783433cf9 100644
--- a/Userland/Libraries/LibWeb/DOM/Document.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Document.cpp
@@ -622,8 +622,8 @@ void Document::update_layout()
auto& icb = static_cast<Layout::InitialContainingBlock&>(*m_layout_root);
auto& icb_state = layout_state.get_mutable(icb);
- icb.set_has_definite_width(true);
- icb.set_has_definite_height(true);
+ icb_state.set_has_definite_width(true);
+ icb_state.set_has_definite_height(true);
icb_state.set_content_width(viewport_rect.width());
icb_state.set_content_height(viewport_rect.height());
diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
index 5145357d09..bd5235dae0 100644
--- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp
@@ -418,7 +418,7 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain
if (is<ReplacedBox>(box) || is<BlockContainer>(box))
place_block_level_element_in_normal_flow_vertically(box, block_container);
- if (box.has_definite_height()) {
+ if (box_state.has_definite_height()) {
compute_height(box, m_state);
}
@@ -456,10 +456,10 @@ void BlockFormattingContext::run_intrinsic_size_determination(Box const& box)
{
auto& box_state = m_state.get_mutable(box);
- if (box.has_definite_width())
+ if (box_state.has_definite_width())
box_state.set_content_width(box.computed_values().width().resolved(box, CSS::Length::make_px(containing_block_width_for(box))).to_px(box));
- if (box.has_definite_height())
+ if (box_state.has_definite_height())
box_state.set_content_height(box.computed_values().height().resolved(box, CSS::Length::make_px(containing_block_height_for(box))).to_px(box));
run(box, LayoutMode::IntrinsicSizeDetermination);
diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
index 6a7b1fba78..d1d0f51095 100644
--- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
@@ -275,7 +275,8 @@ void FlexFormattingContext::generate_anonymous_flex_items()
bool FlexFormattingContext::has_definite_main_size(Box const& box) const
{
- return is_row_layout() ? box.has_definite_width() : box.has_definite_height();
+ auto const& used_values = m_state.get(box);
+ return is_row_layout() ? used_values.has_definite_width() : used_values.has_definite_height();
}
float FlexFormattingContext::specified_main_size(Box const& box) const
@@ -292,10 +293,6 @@ float FlexFormattingContext::specified_cross_size(Box const& box) const
float FlexFormattingContext::resolved_definite_cross_size(Box const& box) const
{
- if (is_row_layout())
- VERIFY(box.has_definite_height());
- else
- VERIFY(box.has_definite_width());
auto const& cross_value = is_row_layout() ? box.computed_values().height() : box.computed_values().width();
if (cross_value.is_length())
return cross_value.length().to_px(box);
@@ -304,10 +301,6 @@ float FlexFormattingContext::resolved_definite_cross_size(Box const& box) const
float FlexFormattingContext::resolved_definite_main_size(Box const& box) const
{
- if (is_row_layout())
- VERIFY(box.has_definite_width());
- else
- VERIFY(box.has_definite_height());
auto const& cross_value = is_row_layout() ? box.computed_values().width() : box.computed_values().height();
if (cross_value.is_length())
return cross_value.length().to_px(box);
@@ -328,7 +321,8 @@ bool FlexFormattingContext::has_cross_min_size(Box const& box) const
bool FlexFormattingContext::has_definite_cross_size(Box const& box) const
{
- return is_row_layout() ? box.has_definite_height() : box.has_definite_width();
+ auto const& used_values = m_state.get(box);
+ return is_row_layout() ? used_values.has_definite_height() : used_values.has_definite_width();
}
float FlexFormattingContext::specified_main_size_of_child_box(Box const& child_box) const
diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
index cfdc57ed22..a8221c1738 100644
--- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
@@ -32,10 +32,10 @@ void FormattingContext::run_intrinsic_size_determination(Box const& box)
{
auto& box_state = m_state.get_mutable(box);
- if (box.has_definite_width())
+ if (box_state.has_definite_width())
box_state.set_content_width(box.computed_values().width().resolved(box, CSS::Length::make_px(containing_block_width_for(box))).to_px(box));
- if (box.has_definite_height())
+ if (box_state.has_definite_height())
box_state.set_content_height(box.computed_values().height().resolved(box, CSS::Length::make_px(containing_block_height_for(box))).to_px(box));
run(box, LayoutMode::IntrinsicSizeDetermination);
@@ -866,7 +866,7 @@ float FormattingContext::calculate_min_content_width(Layout::Box const& box) con
auto& containing_block_state = throwaway_state.get_mutable(containing_block);
containing_block_state.set_content_width(0);
- if (!containing_block.has_definite_height())
+ if (!containing_block_state.has_definite_height())
containing_block_state.set_content_height(INFINITY);
else if (containing_block.computed_values().height().is_auto())
containing_block_state.set_content_height(containing_block_height_for(containing_block));
@@ -908,7 +908,7 @@ float FormattingContext::calculate_max_content_width(Layout::Box const& box) con
auto& containing_block_state = throwaway_state.get_mutable(containing_block);
containing_block_state.set_content_width(INFINITY);
- if (!containing_block.has_definite_height())
+ if (!containing_block_state.has_definite_height())
containing_block_state.set_content_height(INFINITY);
else if (containing_block.computed_values().height().is_auto())
containing_block_state.set_content_height(containing_block_height_for(containing_block));
@@ -950,7 +950,7 @@ float FormattingContext::calculate_min_content_height(Layout::Box const& box) co
auto& containing_block_state = throwaway_state.get_mutable(containing_block);
containing_block_state.set_content_height(0);
- if (!containing_block.has_definite_width())
+ if (!containing_block_state.has_definite_width())
containing_block_state.set_content_width(INFINITY);
else if (containing_block.computed_values().width().is_auto())
containing_block_state.set_content_width(containing_block_width_for(containing_block));
@@ -992,7 +992,7 @@ float FormattingContext::calculate_max_content_height(Layout::Box const& box) co
auto& containing_block_state = throwaway_state.get_mutable(containing_block);
containing_block_state.set_content_height(INFINITY);
- if (!containing_block.has_definite_width())
+ if (!containing_block_state.has_definite_width())
containing_block_state.set_content_width(INFINITY);
else if (containing_block.computed_values().width().is_auto())
containing_block_state.set_content_width(containing_block_width_for(containing_block));
diff --git a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp
index 7d67780a02..8d153a73c1 100644
--- a/Userland/Libraries/LibWeb/Layout/LayoutState.cpp
+++ b/Userland/Libraries/LibWeb/Layout/LayoutState.cpp
@@ -25,8 +25,10 @@ LayoutState::UsedValues& LayoutState::get_mutable(NodeWithStyleAndBoxModelMetric
}
}
+ auto const* containing_block_used_values = box.is_initial_containing_block_box() ? nullptr : &get(*box.containing_block());
+
used_values_per_layout_node[serial_id] = adopt_own(*new UsedValues);
- used_values_per_layout_node[serial_id]->node = const_cast<NodeWithStyleAndBoxModelMetrics*>(&box);
+ used_values_per_layout_node[serial_id]->set_node(const_cast<NodeWithStyleAndBoxModelMetrics&>(box), containing_block_used_values);
return *used_values_per_layout_node[serial_id];
}
@@ -40,8 +42,11 @@ LayoutState::UsedValues const& LayoutState::get(NodeWithStyleAndBoxModelMetrics
if (ancestor->used_values_per_layout_node[serial_id])
return *ancestor->used_values_per_layout_node[serial_id];
}
+
+ auto const* containing_block_used_values = box.is_initial_containing_block_box() ? nullptr : &get(*box.containing_block());
+
const_cast<LayoutState*>(this)->used_values_per_layout_node[serial_id] = adopt_own(*new UsedValues);
- const_cast<LayoutState*>(this)->used_values_per_layout_node[serial_id]->node = const_cast<NodeWithStyleAndBoxModelMetrics*>(&box);
+ const_cast<LayoutState*>(this)->used_values_per_layout_node[serial_id]->set_node(const_cast<NodeWithStyleAndBoxModelMetrics&>(box), containing_block_used_values);
return *used_values_per_layout_node[serial_id];
}
@@ -56,7 +61,7 @@ void LayoutState::commit()
if (!used_values_ptr)
continue;
auto& used_values = *used_values_ptr;
- auto& node = *used_values.node;
+ auto& node = const_cast<NodeWithStyleAndBoxModelMetrics&>(used_values.node());
// Transfer box model metrics.
node.box_model().inset = { used_values.inset_top, used_values.inset_right, used_values.inset_bottom, used_values.inset_left };
@@ -68,7 +73,7 @@ void LayoutState::commit()
// For boxes, transfer all the state needed for painting.
if (is<Layout::Box>(node)) {
- auto& box = static_cast<Layout::Box&>(node);
+ auto& box = static_cast<Layout::Box const&>(node);
auto& paint_box = const_cast<Painting::PaintableBox&>(*box.paint_box());
paint_box.set_offset(used_values.offset);
paint_box.set_content_size(used_values.content_width(), used_values.content_height());
@@ -125,6 +130,40 @@ Gfx::FloatRect absolute_content_rect(Box const& box, LayoutState const& state)
return rect;
}
+void LayoutState::UsedValues::set_node(NodeWithStyleAndBoxModelMetrics& node, UsedValues const* containing_block_used_values)
+{
+ m_node = &node;
+
+ auto const& computed_values = node.computed_values();
+
+ auto is_definite_size = [&](CSS::LengthPercentage const& size, bool width) {
+ // A size that can be determined without performing layout; that is,
+ // a <length>,
+ // a measure of text (without consideration of line-wrapping),
+ // a size of the initial containing block,
+ // or a <percentage> or other formula (such as the “stretch-fit” sizing of non-replaced blocks [CSS2]) that is resolved solely against definite sizes.
+
+ auto containing_block_has_definite_size = containing_block_used_values ? (width ? containing_block_used_values->has_definite_width() : containing_block_used_values->has_definite_height()) : false;
+
+ if (size.is_auto()) {
+ // NOTE: The width of a non-flex-item block is considered definite if it's auto and the containing block has definite width.
+ if (width && node.parent() && !node.parent()->computed_values().display().is_flex_inside())
+ return containing_block_has_definite_size;
+ return false;
+ }
+
+ if (size.is_length())
+ return true;
+ if (size.is_percentage())
+ return containing_block_has_definite_size;
+ // FIXME: Determine if calc() value is definite.
+ return false;
+ };
+
+ m_has_definite_width = is_definite_size(computed_values.width(), true);
+ m_has_definite_height = is_definite_size(computed_values.height(), false);
+}
+
void LayoutState::UsedValues::set_content_width(float width)
{
m_content_width = width;
diff --git a/Userland/Libraries/LibWeb/Layout/LayoutState.h b/Userland/Libraries/LibWeb/Layout/LayoutState.h
index 837845554e..b315068348 100644
--- a/Userland/Libraries/LibWeb/Layout/LayoutState.h
+++ b/Userland/Libraries/LibWeb/Layout/LayoutState.h
@@ -42,14 +42,19 @@ struct LayoutState {
}
struct UsedValues {
- Layout::NodeWithStyleAndBoxModelMetrics* node { nullptr };
+ NodeWithStyleAndBoxModelMetrics const& node() const { return *m_node; }
+ void set_node(NodeWithStyleAndBoxModelMetrics&, UsedValues const* containing_block_used_values);
float content_width() const { return m_content_width; }
float content_height() const { return m_content_height; }
-
void set_content_width(float);
void set_content_height(float);
+ bool has_definite_width() const { return m_has_definite_width && width_constraint == SizeConstraint::None; }
+ bool has_definite_height() const { return m_has_definite_height && height_constraint == SizeConstraint::None; }
+ void set_has_definite_width(bool value) { m_has_definite_width = value; }
+ void set_has_definite_height(bool value) { m_has_definite_height = value; }
+
Gfx::FloatPoint offset;
SizeConstraint width_constraint { SizeConstraint::None };
@@ -105,8 +110,13 @@ struct LayoutState {
Optional<LineBoxFragmentCoordinate> containing_line_box_fragment;
private:
+ Layout::NodeWithStyleAndBoxModelMetrics* m_node { nullptr };
+
float m_content_width { 0 };
float m_content_height { 0 };
+
+ bool m_has_definite_width { false };
+ bool m_has_definite_height { false };
};
void commit();
diff --git a/Userland/Libraries/LibWeb/Layout/Node.cpp b/Userland/Libraries/LibWeb/Layout/Node.cpp
index 78f8d4de52..30d78de036 100644
--- a/Userland/Libraries/LibWeb/Layout/Node.cpp
+++ b/Userland/Libraries/LibWeb/Layout/Node.cpp
@@ -192,41 +192,8 @@ NodeWithStyle::NodeWithStyle(DOM::Document& document, DOM::Node* node, CSS::Comp
m_font = Gfx::FontDatabase::default_font();
}
-void NodeWithStyle::did_insert_into_layout_tree(CSS::StyleProperties const& style)
+void NodeWithStyle::did_insert_into_layout_tree(CSS::StyleProperties const&)
{
- // https://drafts.csswg.org/css-sizing-3/#definite
- auto is_definite_size = [&](CSS::PropertyID property_id, bool width) {
- // A size that can be determined without performing layout; that is,
- // a <length>,
- // a measure of text (without consideration of line-wrapping),
- // a size of the initial containing block,
- // or a <percentage> or other formula (such as the “stretch-fit” sizing of non-replaced blocks [CSS2]) that is resolved solely against definite sizes.
- auto maybe_value = style.property(property_id);
-
- auto const* containing_block = this->containing_block();
- auto containing_block_has_definite_size = containing_block && (width ? containing_block->m_has_definite_width : containing_block->m_has_definite_height);
-
- if (maybe_value->has_auto()) {
- // NOTE: The width of a non-flex-item block is considered definite if it's auto and the containing block has definite width.
- if (width && is_block_container() && parent() && !parent()->computed_values().display().is_flex_inside())
- return containing_block_has_definite_size;
- return false;
- }
-
- auto maybe_length_percentage = style.length_percentage(property_id);
- if (!maybe_length_percentage.has_value())
- return false;
- auto length_percentage = maybe_length_percentage.release_value();
- if (length_percentage.is_length())
- return true;
- if (length_percentage.is_percentage())
- return containing_block_has_definite_size;
- // FIXME: Determine if calc() value is definite.
- return false;
- };
-
- m_has_definite_width = is_definite_size(CSS::PropertyID::Width, true);
- m_has_definite_height = is_definite_size(CSS::PropertyID::Height, false);
}
void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
diff --git a/Userland/Libraries/LibWeb/Layout/Node.h b/Userland/Libraries/LibWeb/Layout/Node.h
index 59a8efcdc4..70fbb42150 100644
--- a/Userland/Libraries/LibWeb/Layout/Node.h
+++ b/Userland/Libraries/LibWeb/Layout/Node.h
@@ -169,12 +169,6 @@ public:
NonnullRefPtr<NodeWithStyle> create_anonymous_wrapper() const;
- bool has_definite_height() const { return m_has_definite_height; }
- bool has_definite_width() const { return m_has_definite_width; }
-
- void set_has_definite_height(bool b) { m_has_definite_height = b; }
- void set_has_definite_width(bool b) { m_has_definite_width = b; }
-
void did_insert_into_layout_tree(CSS::StyleProperties const&);
protected:
@@ -186,9 +180,6 @@ private:
RefPtr<Gfx::Font> m_font;
float m_line_height { 0 };
RefPtr<CSS::ImageStyleValue> m_list_style_image;
-
- bool m_has_definite_height { false };
- bool m_has_definite_width { false };
};
class NodeWithStyleAndBoxModelMetrics : public NodeWithStyle {