Kaynağa Gözat

LibHTML: Make "children are inline" flag imperative

Instead of computing whether a block's children are inline based on the
first child, make it an imperatively-set flag.

This gives us some flexibility to ignore things like text nodes inside
a <table>, for example. I'm still unsure what the "correct" way to deal
with those will be. We'll find out sooner or later. :^)
Andreas Kling 5 yıl önce
ebeveyn
işleme
5e29238a49

+ 4 - 6
Libraries/LibHTML/Layout/LayoutBlock.cpp

@@ -18,6 +18,7 @@ LayoutNode& LayoutBlock::inline_wrapper()
 {
 {
     if (!last_child() || !last_child()->is_block() || last_child()->node() != nullptr) {
     if (!last_child() || !last_child()->is_block() || last_child()->node() != nullptr) {
         append_child(adopt(*new LayoutBlock(nullptr, style_for_anonymous_block())));
         append_child(adopt(*new LayoutBlock(nullptr, style_for_anonymous_block())));
+        last_child()->set_children_are_inline(true);
     }
     }
     return *last_child();
     return *last_child();
 }
 }
@@ -40,7 +41,9 @@ void LayoutBlock::layout_block_children()
     ASSERT(!children_are_inline());
     ASSERT(!children_are_inline());
     int content_height = 0;
     int content_height = 0;
     for_each_child([&](auto& child) {
     for_each_child([&](auto& child) {
-        ASSERT(is<LayoutBlock>(child));
+        // FIXME: What should we do here? Something like a <table> might have a bunch of useless text children..
+        if (child.is_inline())
+            return;
         auto& child_block = static_cast<LayoutBlock&>(child);
         auto& child_block = static_cast<LayoutBlock&>(child);
         child_block.layout();
         child_block.layout();
         content_height = child_block.rect().bottom() + child_block.box_model().full_margin().bottom - rect().top();
         content_height = child_block.rect().bottom() + child_block.box_model().full_margin().bottom - rect().top();
@@ -238,11 +241,6 @@ void LayoutBlock::render(RenderingContext& context)
     }
     }
 }
 }
 
 
-bool LayoutBlock::children_are_inline() const
-{
-    return first_child() && first_child()->is_inline();
-}
-
 HitTestResult LayoutBlock::hit_test(const Point& position) const
 HitTestResult LayoutBlock::hit_test(const Point& position) const
 {
 {
     if (!children_are_inline())
     if (!children_are_inline())

+ 0 - 2
Libraries/LibHTML/Layout/LayoutBlock.h

@@ -17,8 +17,6 @@ public:
 
 
     virtual LayoutNode& inline_wrapper() override;
     virtual LayoutNode& inline_wrapper() override;
 
 
-    bool children_are_inline() const;
-
     Vector<LineBox>& line_boxes() { return m_line_boxes; }
     Vector<LineBox>& line_boxes() { return m_line_boxes; }
     const Vector<LineBox>& line_boxes() const { return m_line_boxes; }
     const Vector<LineBox>& line_boxes() const { return m_line_boxes; }
 
 

+ 4 - 0
Libraries/LibHTML/Layout/LayoutNode.h

@@ -79,6 +79,9 @@ public:
     template<typename Callback>
     template<typename Callback>
     void for_each_fragment_of_this(Callback);
     void for_each_fragment_of_this(Callback);
 
 
+    bool children_are_inline() const { return m_children_are_inline; }
+    void set_children_are_inline(bool value) { m_children_are_inline = value; }
+
 protected:
 protected:
     explicit LayoutNode(const Node*);
     explicit LayoutNode(const Node*);
 
 
@@ -90,6 +93,7 @@ private:
     bool m_inline { false };
     bool m_inline { false };
     bool m_has_style { false };
     bool m_has_style { false };
     bool m_visible { true };
     bool m_visible { true };
+    bool m_children_are_inline { false };
 };
 };
 
 
 class LayoutNodeWithStyle : public LayoutNode {
 class LayoutNodeWithStyle : public LayoutNode {

+ 3 - 0
Libraries/LibHTML/Layout/LayoutTreeBuilder.cpp

@@ -42,6 +42,9 @@ static RefPtr<LayoutNode> create_layout_tree(Node& node, const StyleProperties*
         }
         }
     }
     }
 
 
+    if (have_inline_children && !have_block_children)
+        layout_node->set_children_are_inline(true);
+
     return layout_node;
     return layout_node;
 }
 }