diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-10-06 20:37:39 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-10-06 20:38:26 +0200 |
commit | f52f2736e181cc7f475d9509e0a52e427d251c6b (patch) | |
tree | dddc85059fb1baaaecbfb4d380cf5158e4c58a90 /Libraries/LibHTML | |
parent | bedb00603cc91219b09c43256132261fd18a9edd (diff) | |
download | serenity-f52f2736e181cc7f475d9509e0a52e427d251c6b.zip |
LibHTML: Add is<ElementType> and to<ElementType> helper functions
These will help us write node-type-aware template functions.
Diffstat (limited to 'Libraries/LibHTML')
-rw-r--r-- | Libraries/LibHTML/CSS/StyleResolver.cpp | 8 | ||||
-rw-r--r-- | Libraries/LibHTML/DOM/Document.cpp | 7 | ||||
-rw-r--r-- | Libraries/LibHTML/DOM/Document.h | 6 | ||||
-rw-r--r-- | Libraries/LibHTML/DOM/Element.h | 8 | ||||
-rw-r--r-- | Libraries/LibHTML/DOM/HTMLAnchorElement.h | 6 | ||||
-rw-r--r-- | Libraries/LibHTML/DOM/HTMLElement.h | 6 | ||||
-rw-r--r-- | Libraries/LibHTML/DOM/HTMLHtmlElement.h | 6 | ||||
-rw-r--r-- | Libraries/LibHTML/DOM/Node.cpp | 2 | ||||
-rw-r--r-- | Libraries/LibHTML/DOM/Node.h | 38 | ||||
-rw-r--r-- | Libraries/LibHTML/DOM/Text.h | 6 | ||||
-rw-r--r-- | Libraries/LibHTML/Dump.cpp | 20 | ||||
-rw-r--r-- | Libraries/LibHTML/Layout/LayoutReplaced.h | 2 |
12 files changed, 93 insertions, 22 deletions
diff --git a/Libraries/LibHTML/CSS/StyleResolver.cpp b/Libraries/LibHTML/CSS/StyleResolver.cpp index e9cc8356a2..28dd0f2534 100644 --- a/Libraries/LibHTML/CSS/StyleResolver.cpp +++ b/Libraries/LibHTML/CSS/StyleResolver.cpp @@ -40,17 +40,17 @@ static bool matches(const Selector& selector, int component_index, const Element case Selector::Component::Relation::Descendant: ASSERT(component_index != 0); for (auto* ancestor = element.parent(); ancestor; ancestor = ancestor->parent()) { - if (!ancestor->is_element()) + if (!is<Element>(*ancestor)) continue; - if (matches(selector, component_index - 1, static_cast<const Element&>(*ancestor))) + if (matches(selector, component_index - 1, to<Element>(*ancestor))) return true; } return false; case Selector::Component::Relation::ImmediateChild: ASSERT(component_index != 0); - if (!element.parent() || !element.parent()->is_element()) + if (!element.parent() || !is<Element>(*element.parent())) return false; - return matches(selector, component_index - 1, static_cast<const Element&>(*element.parent())); + return matches(selector, component_index - 1, to<Element>(*element.parent())); case Selector::Component::Relation::AdjacentSibling: ASSERT(component_index != 0); if (auto* sibling = element.previous_element_sibling()) diff --git a/Libraries/LibHTML/DOM/Document.cpp b/Libraries/LibHTML/DOM/Document.cpp index 5ba2665d65..0f8b1053ab 100644 --- a/Libraries/LibHTML/DOM/Document.cpp +++ b/Libraries/LibHTML/DOM/Document.cpp @@ -29,11 +29,8 @@ StyleResolver& Document::style_resolver() void Document::normalize() { - if (first_child() != nullptr && first_child()->is_element()) { - const Element& el = static_cast<const Element&>(*first_child()); - if (el.tag_name() == "html") - return; - } + if (is<HTMLHtmlElement>(first_child())) + return; NonnullRefPtr<Element> body = adopt(*new Element(*this, "body")); NonnullRefPtr<Element> html = adopt(*new Element(*this, "html")); diff --git a/Libraries/LibHTML/DOM/Document.h b/Libraries/LibHTML/DOM/Document.h index 00a3024b6f..1c54caae77 100644 --- a/Libraries/LibHTML/DOM/Document.h +++ b/Libraries/LibHTML/DOM/Document.h @@ -80,3 +80,9 @@ private: Color m_active_link_color { Color::Red }; Color m_visited_link_color { Color::Magenta }; }; + +template<> +inline bool is<Document>(const Node& node) +{ + return node.is_document(); +} diff --git a/Libraries/LibHTML/DOM/Element.h b/Libraries/LibHTML/DOM/Element.h index d6641e5496..2b0027d2e3 100644 --- a/Libraries/LibHTML/DOM/Element.h +++ b/Libraries/LibHTML/DOM/Element.h @@ -26,7 +26,7 @@ public: Element(Document&, const String& tag_name); virtual ~Element() override; - virtual String tag_name() const override { return m_tag_name; } + virtual String tag_name() const final { return m_tag_name; } String attribute(const String& name) const; void set_attribute(const String& name, const String& value); @@ -54,3 +54,9 @@ private: String m_tag_name; Vector<Attribute> m_attributes; }; + +template<> +inline bool is<Element>(const Node& node) +{ + return node.is_element(); +} diff --git a/Libraries/LibHTML/DOM/HTMLAnchorElement.h b/Libraries/LibHTML/DOM/HTMLAnchorElement.h index 588e89ca28..f5b3104a09 100644 --- a/Libraries/LibHTML/DOM/HTMLAnchorElement.h +++ b/Libraries/LibHTML/DOM/HTMLAnchorElement.h @@ -9,3 +9,9 @@ public: String href() const { return attribute("href"); } }; + +template<> +inline bool is<HTMLAnchorElement>(const Node& node) +{ + return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "a"; +} diff --git a/Libraries/LibHTML/DOM/HTMLElement.h b/Libraries/LibHTML/DOM/HTMLElement.h index a366eb9ea0..0c8a324895 100644 --- a/Libraries/LibHTML/DOM/HTMLElement.h +++ b/Libraries/LibHTML/DOM/HTMLElement.h @@ -12,3 +12,9 @@ public: private: virtual bool is_html_element() const final { return true; } }; + +template<> +inline bool is<HTMLElement>(const Node& node) +{ + return node.is_html_element(); +} diff --git a/Libraries/LibHTML/DOM/HTMLHtmlElement.h b/Libraries/LibHTML/DOM/HTMLHtmlElement.h index 4ab5b78af6..d750717635 100644 --- a/Libraries/LibHTML/DOM/HTMLHtmlElement.h +++ b/Libraries/LibHTML/DOM/HTMLHtmlElement.h @@ -7,3 +7,9 @@ public: HTMLHtmlElement(Document&, const String& tag_name); virtual ~HTMLHtmlElement() override; }; + +template<> +inline bool is<HTMLHtmlElement>(const Node& node) +{ + return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "html"; +} diff --git a/Libraries/LibHTML/DOM/Node.cpp b/Libraries/LibHTML/DOM/Node.cpp index ca9f874780..d1b70fe1cd 100644 --- a/Libraries/LibHTML/DOM/Node.cpp +++ b/Libraries/LibHTML/DOM/Node.cpp @@ -56,7 +56,7 @@ RefPtr<LayoutNode> Node::create_layout_tree(const StyleResolver& resolver, const const HTMLAnchorElement* Node::enclosing_link_element() const { - if (is_element() && tag_name().to_lowercase() == "a") + if (is<HTMLAnchorElement>(*this)) return static_cast<const HTMLAnchorElement*>(this); return parent() ? parent()->enclosing_link_element() : nullptr; } diff --git a/Libraries/LibHTML/DOM/Node.h b/Libraries/LibHTML/DOM/Node.h index e9771eeb99..6a9208dd68 100644 --- a/Libraries/LibHTML/DOM/Node.h +++ b/Libraries/LibHTML/DOM/Node.h @@ -74,3 +74,41 @@ protected: mutable LayoutNode* m_layout_node { nullptr }; NodeType m_type { NodeType::INVALID }; }; + +template<typename T> +inline bool is(const Node&) +{ + return false; +} + +template<typename T> +inline bool is(const Node* node) +{ + return node && is<T>(*node); +} + +template<> +inline bool is<Node>(const Node&) +{ + return true; +} + +template<> +inline bool is<ParentNode>(const Node& node) +{ + return node.is_parent_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); +} diff --git a/Libraries/LibHTML/DOM/Text.h b/Libraries/LibHTML/DOM/Text.h index 46e29ba0c6..b7b55f1f70 100644 --- a/Libraries/LibHTML/DOM/Text.h +++ b/Libraries/LibHTML/DOM/Text.h @@ -19,3 +19,9 @@ private: String m_data; }; + +template<> +inline bool is<Text>(const Node& node) +{ + return node.is_text(); +} diff --git a/Libraries/LibHTML/Dump.cpp b/Libraries/LibHTML/Dump.cpp index 0919263ae7..62619de074 100644 --- a/Libraries/LibHTML/Dump.cpp +++ b/Libraries/LibHTML/Dump.cpp @@ -14,19 +14,19 @@ void dump_tree(const Node& node) static int indent = 0; for (int i = 0; i < indent; ++i) dbgprintf(" "); - if (node.is_document()) { + if (is<Document>(node)) { dbgprintf("*Document*\n"); - } else if (node.is_element()) { - dbgprintf("<%s", static_cast<const Element&>(node).tag_name().characters()); - static_cast<const Element&>(node).for_each_attribute([](auto& name, auto& value) { + } else if (is<Element>(node)) { + dbgprintf("<%s", to<Element>(node).tag_name().characters()); + to<Element>(node).for_each_attribute([](auto& name, auto& value) { dbgprintf(" %s=%s", name.characters(), value.characters()); }); dbgprintf(">\n"); - } else if (node.is_text()) { + } else if (is<Text>(node)) { dbgprintf("\"%s\"\n", static_cast<const Text&>(node).data().characters()); } ++indent; - if (node.is_parent_node()) { + if (is<ParentNode>(node)) { static_cast<const ParentNode&>(node).for_each_child([](auto& child) { dump_tree(child); }); @@ -43,12 +43,12 @@ void dump_tree(const LayoutNode& layout_node) String tag_name; if (layout_node.is_anonymous()) tag_name = "(anonymous)"; - else if (layout_node.node()->is_text()) + else if (is<Text>(layout_node.node())) tag_name = "#text"; - else if (layout_node.node()->is_document()) + else if (is<Document>(layout_node.node())) tag_name = "#document"; - else if (layout_node.node()->is_element()) - tag_name = static_cast<const Element&>(*layout_node.node()).tag_name(); + else if (is<Element>(layout_node.node())) + tag_name = to<Element>(*layout_node.node()).tag_name(); else tag_name = "???"; diff --git a/Libraries/LibHTML/Layout/LayoutReplaced.h b/Libraries/LibHTML/Layout/LayoutReplaced.h index 0d76b7352b..c76fc3b930 100644 --- a/Libraries/LibHTML/Layout/LayoutReplaced.h +++ b/Libraries/LibHTML/Layout/LayoutReplaced.h @@ -6,7 +6,7 @@ public: LayoutReplaced(const Element&, NonnullRefPtr<StyleProperties>); virtual ~LayoutReplaced() override; - const Element& node() const { return static_cast<const Element&>(*LayoutNode::node()); } + const Element& node() const { return to<Element>(*LayoutNode::node()); } virtual bool is_replaced() const final { return true; } |