From 3bee9d3d3cdd3a0c91484c7e5f489ee729fd64a8 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 6 Oct 2019 20:47:57 +0200 Subject: LibHTML: Templatize Node::first_child_of_type() This is a lot nicer than first_child_with_tag_name(...). The is(Node) functions are obviously unoptimized at the moment, and this is about establishing pleasant patterns right now. :^) --- Libraries/LibHTML/DOM/Document.cpp | 8 ++++---- Libraries/LibHTML/DOM/HTMLBodyElement.h | 6 ++++++ Libraries/LibHTML/DOM/HTMLHeadElement.h | 6 ++++++ Libraries/LibHTML/DOM/HTMLTitleElement.h | 6 ++++++ Libraries/LibHTML/DOM/Node.h | 34 ++++++++++++++++++++++++-------- 5 files changed, 48 insertions(+), 12 deletions(-) (limited to 'Libraries/LibHTML') diff --git a/Libraries/LibHTML/DOM/Document.cpp b/Libraries/LibHTML/DOM/Document.cpp index 0f8b1053ab..4543c897ae 100644 --- a/Libraries/LibHTML/DOM/Document.cpp +++ b/Libraries/LibHTML/DOM/Document.cpp @@ -41,7 +41,7 @@ void Document::normalize() const HTMLHtmlElement* Document::document_element() const { - return static_cast(first_child_with_tag_name("html")); + return first_child_of_type(); } 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(html->first_child_with_tag_name("head")); + return html->first_child_of_type(); } 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(html->first_child_with_tag_name("body")); + return html->first_child_of_type(); } String Document::title() const @@ -66,7 +66,7 @@ String Document::title() const if (!head_element) return {}; - auto* title_element = static_cast(head_element->first_child_with_tag_name("title")); + auto* title_element = head_element->first_child_of_type(); if (!title_element) return {}; diff --git a/Libraries/LibHTML/DOM/HTMLBodyElement.h b/Libraries/LibHTML/DOM/HTMLBodyElement.h index b00a12fc9d..774db5deea 100644 --- a/Libraries/LibHTML/DOM/HTMLBodyElement.h +++ b/Libraries/LibHTML/DOM/HTMLBodyElement.h @@ -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(const Node& node) +{ + return is(node) && to(node).tag_name().to_lowercase() == "body"; +} diff --git a/Libraries/LibHTML/DOM/HTMLHeadElement.h b/Libraries/LibHTML/DOM/HTMLHeadElement.h index 4586a26bf3..ad62b8a8e6 100644 --- a/Libraries/LibHTML/DOM/HTMLHeadElement.h +++ b/Libraries/LibHTML/DOM/HTMLHeadElement.h @@ -7,3 +7,9 @@ public: HTMLHeadElement(Document&, const String& tag_name); virtual ~HTMLHeadElement() override; }; + +template<> +inline bool is(const Node& node) +{ + return is(node) && to(node).tag_name().to_lowercase() == "head"; +} diff --git a/Libraries/LibHTML/DOM/HTMLTitleElement.h b/Libraries/LibHTML/DOM/HTMLTitleElement.h index 4b0edf803a..9b39366ddf 100644 --- a/Libraries/LibHTML/DOM/HTMLTitleElement.h +++ b/Libraries/LibHTML/DOM/HTMLTitleElement.h @@ -7,3 +7,9 @@ public: HTMLTitleElement(Document&, const String& tag_name); virtual ~HTMLTitleElement() override; }; + +template<> +inline bool is(const Node& node) +{ + return is(node) && to(node).tag_name().to_lowercase() == "title"; +} diff --git a/Libraries/LibHTML/DOM/Node.h b/Libraries/LibHTML/DOM/Node.h index 6a9208dd68..d4213f29a4 100644 --- a/Libraries/LibHTML/DOM/Node.h +++ b/Libraries/LibHTML/DOM/Node.h @@ -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 + 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(node); } +template +inline T* to(Node* node) +{ + ASSERT(is(node)); + return static_cast(node); +} + +template +inline const T* to(const Node* node) +{ + ASSERT(is(node)); + return static_cast(node); +} + template inline T& to(Node& node) { ASSERT(is(node)); return static_cast(node); } + +template +inline const T* Node::first_child_of_type() const +{ + for (auto* child = first_child(); child; child = child->next_sibling()) { + if (is(*child)) + return to(child); + } + return nullptr; +} -- cgit v1.2.3