Kaynağa Gözat

LibHTML: Add typed child/sibling traversal helpers for LayoutNode

Also add some special variants for the table classes, to make it a bit
more pleasant to write table code. :^)
Andreas Kling 5 yıl önce
ebeveyn
işleme
65ad6c35f0

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

@@ -85,6 +85,18 @@ public:
     bool children_are_inline() const { return m_children_are_inline; }
     void set_children_are_inline(bool value) { m_children_are_inline = value; }
 
+    template<typename U>
+    const U* next_sibling_of_type() const;
+
+    template<typename U>
+    U* next_sibling_of_type();
+
+    template<typename T>
+    const T* first_child_of_type() const;
+
+    template<typename T>
+    T* first_child_of_type();
+
 protected:
     explicit LayoutNode(const Node*);
 
@@ -196,3 +208,43 @@ inline T& to(LayoutNode& node)
     ASSERT(is<T>(node));
     return static_cast<T&>(node);
 }
+
+template<typename T>
+inline const T* LayoutNode::next_sibling_of_type() const
+{
+    for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
+        if (is<T>(*sibling))
+            return &to<T>(*sibling);
+    }
+    return nullptr;
+}
+
+template<typename T>
+inline T* LayoutNode::next_sibling_of_type()
+{
+    for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
+        if (is<T>(*sibling))
+            return &to<T>(*sibling);
+    }
+    return nullptr;
+}
+
+template<typename T>
+inline const T* LayoutNode::first_child_of_type() const
+{
+    for (auto* child = first_child(); child; child = child->next_sibling()) {
+        if (is<T>(*child))
+            return &to<T>(*child);
+    }
+    return nullptr;
+}
+
+template<typename T>
+inline T* LayoutNode::first_child_of_type()
+{
+    for (auto* child = first_child(); child; child = child->next_sibling()) {
+        if (is<T>(*child))
+            return &to<T>(*child);
+    }
+    return nullptr;
+}

+ 12 - 0
Libraries/LibHTML/Layout/LayoutTable.cpp

@@ -1,5 +1,6 @@
 #include <LibHTML/DOM/Element.h>
 #include <LibHTML/Layout/LayoutTable.h>
+#include <LibHTML/Layout/LayoutTableRow.h>
 
 LayoutTable::LayoutTable(const Element& element, NonnullRefPtr<StyleProperties> style)
     : LayoutBlock(&element, move(style))
@@ -12,5 +13,16 @@ LayoutTable::~LayoutTable()
 
 void LayoutTable::layout()
 {
+
     LayoutBlock::layout();
 }
+
+LayoutTableRow* LayoutTable::first_row()
+{
+    return first_child_of_type<LayoutTableRow>();
+}
+
+const LayoutTableRow* LayoutTable::first_row() const
+{
+    return first_child_of_type<LayoutTableRow>();
+}

+ 5 - 0
Libraries/LibHTML/Layout/LayoutTable.h

@@ -2,6 +2,8 @@
 
 #include <LibHTML/Layout/LayoutBlock.h>
 
+class LayoutTableRow;
+
 class LayoutTable final : public LayoutBlock {
 public:
     LayoutTable(const Element&, NonnullRefPtr<StyleProperties>);
@@ -9,6 +11,9 @@ public:
 
     virtual void layout() override;
 
+    LayoutTableRow* first_row();
+    const LayoutTableRow* first_row() const;
+
 private:
     virtual bool is_table() const override { return true; }
     virtual const char* class_name() const override { return "LayoutTable"; }

+ 3 - 0
Libraries/LibHTML/Layout/LayoutTableCell.h

@@ -7,6 +7,9 @@ public:
     LayoutTableCell(const Element&, NonnullRefPtr<StyleProperties>);
     virtual ~LayoutTableCell() override;
 
+    LayoutTableCell* next_cell() { return next_sibling_of_type<LayoutTableCell>(); }
+    const LayoutTableCell* next_cell() const { return next_sibling_of_type<LayoutTableCell>(); }
+
 private:
     virtual bool is_table_cell() const override { return true; }
     virtual const char* class_name() const override { return "LayoutTableCell"; }

+ 21 - 0
Libraries/LibHTML/Layout/LayoutTableRow.cpp

@@ -1,4 +1,5 @@
 #include <LibHTML/DOM/Element.h>
+#include <LibHTML/Layout/LayoutTableCell.h>
 #include <LibHTML/Layout/LayoutTableRow.h>
 
 LayoutTableRow::LayoutTableRow(const Element& element, NonnullRefPtr<StyleProperties> style)
@@ -14,3 +15,23 @@ void LayoutTableRow::layout()
 {
     LayoutBox::layout();
 }
+
+LayoutTableCell* LayoutTableRow::first_cell()
+{
+    return first_child_of_type<LayoutTableCell>();
+}
+
+const LayoutTableCell* LayoutTableRow::first_cell() const
+{
+    return first_child_of_type<LayoutTableCell>();
+}
+
+LayoutTableRow* LayoutTableRow::next_row()
+{
+    return next_sibling_of_type<LayoutTableRow>();
+}
+
+const LayoutTableRow* LayoutTableRow::next_row() const
+{
+    return next_sibling_of_type<LayoutTableRow>();
+}

+ 8 - 0
Libraries/LibHTML/Layout/LayoutTableRow.h

@@ -2,6 +2,8 @@
 
 #include <LibHTML/Layout/LayoutBox.h>
 
+class LayoutTableCell;
+
 class LayoutTableRow final : public LayoutBox {
 public:
     LayoutTableRow(const Element&, NonnullRefPtr<StyleProperties>);
@@ -9,6 +11,12 @@ public:
 
     virtual void layout() override;
 
+    LayoutTableCell* first_cell();
+    const LayoutTableCell* first_cell() const;
+
+    LayoutTableRow* next_row();
+    const LayoutTableRow* next_row() const;
+
 private:
     virtual bool is_table_row() const override { return true; }
     virtual const char* class_name() const override { return "LayoutTableRow"; }