LibHTML: Templatize Node::first_child_of_type<T>()

This is a lot nicer than first_child_with_tag_name(...).

The is<T>(Node) functions are obviously unoptimized at the moment,
and this is about establishing pleasant patterns right now. :^)
This commit is contained in:
Andreas Kling 2019-10-06 20:47:57 +02:00
parent f52f2736e1
commit 3bee9d3d3c
Notes: sideshowbarker 2024-07-19 11:46:33 +09:00
5 changed files with 48 additions and 12 deletions

View File

@ -41,7 +41,7 @@ void Document::normalize()
const HTMLHtmlElement* Document::document_element() const
{
return static_cast<const HTMLHtmlElement*>(first_child_with_tag_name("html"));
return first_child_of_type<HTMLHtmlElement>();
}
const HTMLHeadElement* Document::head() const
@ -49,7 +49,7 @@ const HTMLHeadElement* Document::head() const
auto* html = document_element();
if (!html)
return nullptr;
return static_cast<const HTMLHeadElement*>(html->first_child_with_tag_name("head"));
return html->first_child_of_type<HTMLHeadElement>();
}
const HTMLBodyElement* Document::body() const
@ -57,7 +57,7 @@ const HTMLBodyElement* Document::body() const
auto* html = document_element();
if (!html)
return nullptr;
return static_cast<const HTMLBodyElement*>(html->first_child_with_tag_name("body"));
return html->first_child_of_type<HTMLBodyElement>();
}
String Document::title() const
@ -66,7 +66,7 @@ String Document::title() const
if (!head_element)
return {};
auto* title_element = static_cast<const HTMLTitleElement*>(head_element->first_child_with_tag_name("title"));
auto* title_element = head_element->first_child_of_type<HTMLTitleElement>();
if (!title_element)
return {};

View File

@ -10,3 +10,9 @@ public:
virtual void parse_attribute(const String&, const String&) override;
virtual void apply_presentational_hints(StyleProperties&) const override;
};
template<>
inline bool is<HTMLBodyElement>(const Node& node)
{
return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "body";
}

View File

@ -7,3 +7,9 @@ public:
HTMLHeadElement(Document&, const String& tag_name);
virtual ~HTMLHeadElement() override;
};
template<>
inline bool is<HTMLHeadElement>(const Node& node)
{
return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "head";
}

View File

@ -7,3 +7,9 @@ public:
HTMLTitleElement(Document&, const String& tag_name);
virtual ~HTMLTitleElement() override;
};
template<>
inline bool is<HTMLTitleElement>(const Node& node)
{
return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "title";
}

View File

@ -47,14 +47,8 @@ public:
virtual bool is_html_element() const { return false; }
const Node* first_child_with_tag_name(const StringView& tag_name) const
{
for (auto* child = first_child(); child; child = child->next_sibling()) {
if (child->tag_name() == tag_name)
return child;
}
return nullptr;
}
template<typename T>
const T* first_child_of_type() const;
virtual void inserted_into(Node&) {}
virtual void removed_from(Node&) {}
@ -106,9 +100,33 @@ inline const T& to(const Node& node)
return static_cast<const T&>(node);
}
template<typename T>
inline T* to(Node* node)
{
ASSERT(is<T>(node));
return static_cast<T*>(node);
}
template<typename T>
inline const T* to(const Node* node)
{
ASSERT(is<T>(node));
return static_cast<const T*>(node);
}
template<typename T>
inline T& to(Node& node)
{
ASSERT(is<T>(node));
return static_cast<T&>(node);
}
template<typename T>
inline const T* Node::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;
}