diff --git a/Libraries/LibHTML/Layout/LayoutNode.h b/Libraries/LibHTML/Layout/LayoutNode.h
index 507c14c2fe..e515de53d2 100644
--- a/Libraries/LibHTML/Layout/LayoutNode.h
+++ b/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
+ const U* next_sibling_of_type() const;
+
+ template
+ U* next_sibling_of_type();
+
+ template
+ const T* first_child_of_type() const;
+
+ template
+ T* first_child_of_type();
+
protected:
explicit LayoutNode(const Node*);
@@ -196,3 +208,43 @@ inline T& to(LayoutNode& node)
ASSERT(is(node));
return static_cast(node);
}
+
+template
+inline const T* LayoutNode::next_sibling_of_type() const
+{
+ for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
+ if (is(*sibling))
+ return &to(*sibling);
+ }
+ return nullptr;
+}
+
+template
+inline T* LayoutNode::next_sibling_of_type()
+{
+ for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
+ if (is(*sibling))
+ return &to(*sibling);
+ }
+ return nullptr;
+}
+
+template
+inline const T* LayoutNode::first_child_of_type() const
+{
+ for (auto* child = first_child(); child; child = child->next_sibling()) {
+ if (is(*child))
+ return &to(*child);
+ }
+ return nullptr;
+}
+
+template
+inline T* LayoutNode::first_child_of_type()
+{
+ for (auto* child = first_child(); child; child = child->next_sibling()) {
+ if (is(*child))
+ return &to(*child);
+ }
+ return nullptr;
+}
diff --git a/Libraries/LibHTML/Layout/LayoutTable.cpp b/Libraries/LibHTML/Layout/LayoutTable.cpp
index b2f48c622d..6928a211b8 100644
--- a/Libraries/LibHTML/Layout/LayoutTable.cpp
+++ b/Libraries/LibHTML/Layout/LayoutTable.cpp
@@ -1,5 +1,6 @@
#include
#include
+#include
LayoutTable::LayoutTable(const Element& element, NonnullRefPtr 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();
+}
+
+const LayoutTableRow* LayoutTable::first_row() const
+{
+ return first_child_of_type();
+}
diff --git a/Libraries/LibHTML/Layout/LayoutTable.h b/Libraries/LibHTML/Layout/LayoutTable.h
index e5cab92c39..05d56962bf 100644
--- a/Libraries/LibHTML/Layout/LayoutTable.h
+++ b/Libraries/LibHTML/Layout/LayoutTable.h
@@ -2,6 +2,8 @@
#include
+class LayoutTableRow;
+
class LayoutTable final : public LayoutBlock {
public:
LayoutTable(const Element&, NonnullRefPtr);
@@ -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"; }
diff --git a/Libraries/LibHTML/Layout/LayoutTableCell.h b/Libraries/LibHTML/Layout/LayoutTableCell.h
index 3334f31cda..19f4f0543c 100644
--- a/Libraries/LibHTML/Layout/LayoutTableCell.h
+++ b/Libraries/LibHTML/Layout/LayoutTableCell.h
@@ -7,6 +7,9 @@ public:
LayoutTableCell(const Element&, NonnullRefPtr);
virtual ~LayoutTableCell() override;
+ LayoutTableCell* next_cell() { return next_sibling_of_type(); }
+ const LayoutTableCell* next_cell() const { return next_sibling_of_type(); }
+
private:
virtual bool is_table_cell() const override { return true; }
virtual const char* class_name() const override { return "LayoutTableCell"; }
diff --git a/Libraries/LibHTML/Layout/LayoutTableRow.cpp b/Libraries/LibHTML/Layout/LayoutTableRow.cpp
index 6fc7c755c5..98e29394cb 100644
--- a/Libraries/LibHTML/Layout/LayoutTableRow.cpp
+++ b/Libraries/LibHTML/Layout/LayoutTableRow.cpp
@@ -1,4 +1,5 @@
#include
+#include
#include
LayoutTableRow::LayoutTableRow(const Element& element, NonnullRefPtr style)
@@ -14,3 +15,23 @@ void LayoutTableRow::layout()
{
LayoutBox::layout();
}
+
+LayoutTableCell* LayoutTableRow::first_cell()
+{
+ return first_child_of_type();
+}
+
+const LayoutTableCell* LayoutTableRow::first_cell() const
+{
+ return first_child_of_type();
+}
+
+LayoutTableRow* LayoutTableRow::next_row()
+{
+ return next_sibling_of_type();
+}
+
+const LayoutTableRow* LayoutTableRow::next_row() const
+{
+ return next_sibling_of_type();
+}
diff --git a/Libraries/LibHTML/Layout/LayoutTableRow.h b/Libraries/LibHTML/Layout/LayoutTableRow.h
index 4da426de36..ee7ea51366 100644
--- a/Libraries/LibHTML/Layout/LayoutTableRow.h
+++ b/Libraries/LibHTML/Layout/LayoutTableRow.h
@@ -2,6 +2,8 @@
#include
+class LayoutTableCell;
+
class LayoutTableRow final : public LayoutBox {
public:
LayoutTableRow(const Element&, NonnullRefPtr);
@@ -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"; }