diff --git a/Libraries/LibWeb/CSS/ComputedValues.h b/Libraries/LibWeb/CSS/ComputedValues.h index 35025f9b17..588468ced7 100644 --- a/Libraries/LibWeb/CSS/ComputedValues.h +++ b/Libraries/LibWeb/CSS/ComputedValues.h @@ -84,6 +84,13 @@ public: CSS::ListStyleType list_style_type() const { return m_inherited.list_style_type; } + ComputedValues clone_inherited_values() const + { + ComputedValues clone; + clone.m_inherited = m_inherited; + return clone; + } + protected: struct { Color color { InitialValues::color() }; diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp index 2746e67eb2..e23b5ccb66 100644 --- a/Libraries/LibWeb/DOM/Element.cpp +++ b/Libraries/LibWeb/DOM/Element.cpp @@ -220,7 +220,6 @@ void Element::recompute_style() diff = compute_style_difference(*old_specified_css_values, *new_specified_css_values, document()); if (diff == StyleDifference::None) return; - layout_node()->set_specified_style(*new_specified_css_values); layout_node()->apply_style(*new_specified_css_values); if (diff == StyleDifference::NeedsRelayout) { document().force_layout(); diff --git a/Libraries/LibWeb/Layout/BlockBox.cpp b/Libraries/LibWeb/Layout/BlockBox.cpp index b25a459886..aab1430afc 100644 --- a/Libraries/LibWeb/Layout/BlockBox.cpp +++ b/Libraries/LibWeb/Layout/BlockBox.cpp @@ -44,6 +44,11 @@ BlockBox::BlockBox(DOM::Document& document, DOM::Node* node, NonnullRefPtr); + BlockBox(DOM::Document&, DOM::Node*, CSS::ComputedValues); virtual ~BlockBox() override; virtual void paint(PaintContext&, PaintPhase) override; diff --git a/Libraries/LibWeb/Layout/Box.h b/Libraries/LibWeb/Layout/Box.h index a9517b6437..b43f969fad 100644 --- a/Libraries/LibWeb/Layout/Box.h +++ b/Libraries/LibWeb/Layout/Box.h @@ -113,6 +113,11 @@ protected: { } + Box(DOM::Document& document, DOM::Node* node, CSS::ComputedValues computed_values) + : NodeWithStyleAndBoxModelMetrics(document, node, move(computed_values)) + { + } + virtual void did_set_rect() { } Vector m_line_boxes; diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index 14e007a906..e447976bf6 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -205,10 +205,16 @@ bool Node::is_fixed_position() const NodeWithStyle::NodeWithStyle(DOM::Document& document, DOM::Node* node, NonnullRefPtr specified_style) : Node(document, node) - , m_specified_style(move(specified_style)) { m_has_style = true; - apply_style(*m_specified_style); + apply_style(*specified_style); +} + +NodeWithStyle::NodeWithStyle(DOM::Document& document, DOM::Node* node, CSS::ComputedValues computed_values) + : Node(document, node) + , m_computed_values(move(computed_values)) +{ + m_has_style = true; } void NodeWithStyle::apply_style(const CSS::StyleProperties& specified_style) @@ -315,4 +321,15 @@ bool Node::is_inline_block() const { return is_inline() && is(*this); } + +NonnullRefPtr NodeWithStyle::create_anonymous_wrapper() const +{ + auto wrapper = adopt(*new BlockBox(const_cast(document()), nullptr, m_computed_values.clone_inherited_values())); + wrapper->m_font = m_font; + wrapper->m_font_size = m_font_size; + wrapper->m_line_height = m_line_height; + wrapper->m_background_image = m_background_image; + return wrapper; +} + } diff --git a/Libraries/LibWeb/Layout/Node.h b/Libraries/LibWeb/Layout/Node.h index d59cec6ebe..de7ed3e7bf 100644 --- a/Libraries/LibWeb/Layout/Node.h +++ b/Libraries/LibWeb/Layout/Node.h @@ -126,7 +126,6 @@ public: bool can_contain_boxes_with_position_absolute() const; const Gfx::Font& font() const; - const CSS::StyleProperties& specified_style() const; const CSS::ImmutableComputedValues& computed_values() const; NodeWithStyle* parent(); @@ -198,9 +197,6 @@ class NodeWithStyle : public Node { public: virtual ~NodeWithStyle() override { } - const CSS::StyleProperties& specified_style() const { return m_specified_style; } - void set_specified_style(const CSS::StyleProperties& style) { m_specified_style = style; } - const CSS::ImmutableComputedValues& computed_values() const { return static_cast(m_computed_values); } void apply_style(const CSS::StyleProperties&); @@ -210,8 +206,11 @@ public: float font_size() const { return m_font_size; } const CSS::ImageStyleValue* background_image() const { return m_background_image; } + NonnullRefPtr create_anonymous_wrapper() const; + protected: NodeWithStyle(DOM::Document&, DOM::Node*, NonnullRefPtr); + NodeWithStyle(DOM::Document&, DOM::Node*, CSS::ComputedValues); private: CSS::ComputedValues m_computed_values; @@ -220,7 +219,6 @@ private: float m_font_size { 0 }; RefPtr m_background_image; - NonnullRefPtr m_specified_style; CSS::Position m_position; }; @@ -235,6 +233,11 @@ protected: { } + NodeWithStyleAndBoxModelMetrics(DOM::Document& document, DOM::Node* node, CSS::ComputedValues computed_values) + : NodeWithStyle(document, node, move(computed_values)) + { + } + private: BoxModelMetrics m_box_model; }; @@ -253,13 +256,6 @@ inline float Node::font_size() const return parent()->font_size(); } -inline const CSS::StyleProperties& Node::specified_style() const -{ - if (m_has_style) - return static_cast(this)->specified_style(); - return parent()->specified_style(); -} - inline const CSS::ImmutableComputedValues& Node::computed_values() const { if (m_has_style) diff --git a/Libraries/LibWeb/Layout/TextNode.h b/Libraries/LibWeb/Layout/TextNode.h index 85189a77b4..0752689cc0 100644 --- a/Libraries/LibWeb/Layout/TextNode.h +++ b/Libraries/LibWeb/Layout/TextNode.h @@ -47,8 +47,6 @@ public: virtual void split_into_lines(InlineFormattingContext&, LayoutMode) override; - const CSS::StyleProperties& specified_style() const { return parent()->specified_style(); } - private: void split_into_lines_by_rules(InlineFormattingContext&, LayoutMode, bool do_collapse, bool do_wrap_lines, bool do_wrap_breaks); void paint_cursor_if_needed(PaintContext&, const LineBoxFragment&) const; diff --git a/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Libraries/LibWeb/Layout/TreeBuilder.cpp index 2f3831f58d..e73507c140 100644 --- a/Libraries/LibWeb/Layout/TreeBuilder.cpp +++ b/Libraries/LibWeb/Layout/TreeBuilder.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -37,22 +38,10 @@ TreeBuilder::TreeBuilder() { } -static NonnullRefPtr style_for_anonymous_block(Node& parent_box) -{ - auto new_style = CSS::StyleProperties::create(); - - parent_box.specified_style().for_each_property([&](auto property_id, auto& value) { - if (CSS::StyleResolver::is_inherited_property(property_id)) - new_style->set_property(property_id, value); - }); - - return new_style; -} - // The insertion_parent_for_*() functions maintain the invariant that block-level boxes must have either // only block-level children or only inline-level children. -static Layout::Node& insertion_parent_for_inline_node(Layout::Node& layout_parent, Layout::Node& layout_node) +static Layout::Node& insertion_parent_for_inline_node(Layout::NodeWithStyle& layout_parent) { if (layout_parent.is_inline() && !layout_parent.is_inline_block()) return layout_parent; @@ -62,7 +51,7 @@ static Layout::Node& insertion_parent_for_inline_node(Layout::Node& layout_paren // Parent has block-level children, insert into an anonymous wrapper block (and create it first if needed) if (!layout_parent.last_child()->is_anonymous() || !layout_parent.last_child()->children_are_inline()) { - layout_parent.append_child(adopt(*new BlockBox(layout_node.document(), nullptr, style_for_anonymous_block(layout_parent)))); + layout_parent.append_child(layout_parent.create_anonymous_wrapper()); } return *layout_parent.last_child(); } @@ -86,7 +75,7 @@ static Layout::Node& insertion_parent_for_block_node(Layout::Node& layout_parent layout_parent.remove_child(*child); children.append(child.release_nonnull()); } - layout_parent.append_child(adopt(*new BlockBox(layout_node.document(), nullptr, style_for_anonymous_block(layout_parent)))); + layout_parent.append_child(adopt(*new BlockBox(layout_node.document(), nullptr, layout_parent.computed_values().clone_inherited_values()))); layout_parent.set_children_are_inline(false); for (auto& child : children) { layout_parent.last_child()->append_child(child); @@ -102,7 +91,9 @@ void TreeBuilder::create_layout_tree(DOM::Node& dom_node) if (dom_node.parent() && !dom_node.parent()->layout_node()) return; - const CSS::StyleProperties* parent_style = m_parent_stack.is_empty() ? nullptr : &m_parent_stack.last()->specified_style(); + const CSS::StyleProperties* parent_style = nullptr; + if (!m_parent_stack.is_empty() && m_parent_stack.last()->dom_node() && m_parent_stack.last()->dom_node()->is_element()) + parent_style = downcast(*m_parent_stack.last()->dom_node()).specified_css_values(); auto layout_node = dom_node.create_layout_node(parent_style); if (!layout_node) @@ -117,7 +108,7 @@ void TreeBuilder::create_layout_tree(DOM::Node& dom_node) } else { if (layout_node->is_inline()) { // Inlines can be inserted into the nearest ancestor. - auto& insertion_point = insertion_parent_for_inline_node(*m_parent_stack.last(), *layout_node); + auto& insertion_point = insertion_parent_for_inline_node(*m_parent_stack.last()); insertion_point.append_child(*layout_node); insertion_point.set_children_are_inline(true); } else { @@ -136,7 +127,7 @@ void TreeBuilder::create_layout_tree(DOM::Node& dom_node) } if (dom_node.has_children() && layout_node->can_have_children()) { - push_parent(*layout_node); + push_parent(downcast(*layout_node)); downcast(dom_node).for_each_child([&](auto& dom_child) { create_layout_tree(dom_child); }); @@ -149,7 +140,7 @@ RefPtr TreeBuilder::build(DOM::Node& dom_node) if (dom_node.parent()) { // We're building a partial layout tree, so start by building up the stack of parent layout nodes. for (auto* ancestor = dom_node.parent()->layout_node(); ancestor; ancestor = ancestor->parent()) - m_parent_stack.prepend(ancestor); + m_parent_stack.prepend(downcast(ancestor)); } create_layout_tree(dom_node); diff --git a/Libraries/LibWeb/Layout/TreeBuilder.h b/Libraries/LibWeb/Layout/TreeBuilder.h index 40c79bb3ad..563338a740 100644 --- a/Libraries/LibWeb/Layout/TreeBuilder.h +++ b/Libraries/LibWeb/Layout/TreeBuilder.h @@ -41,11 +41,11 @@ public: private: void create_layout_tree(DOM::Node&); - void push_parent(Layout::Node& node) { m_parent_stack.append(&node); } + void push_parent(Layout::NodeWithStyle& node) { m_parent_stack.append(&node); } void pop_parent() { m_parent_stack.take_last(); } RefPtr m_layout_root; - Vector m_parent_stack; + Vector m_parent_stack; }; }