diff --git a/Libraries/LibWeb/Bindings/NodeWrapperFactory.cpp b/Libraries/LibWeb/Bindings/NodeWrapperFactory.cpp index 576deeaa118..d34f6068ec7 100644 --- a/Libraries/LibWeb/Bindings/NodeWrapperFactory.cpp +++ b/Libraries/LibWeb/Bindings/NodeWrapperFactory.cpp @@ -41,17 +41,17 @@ namespace Bindings { NodeWrapper* wrap(JS::GlobalObject& global_object, Node& node) { if (is(node)) - return static_cast(wrap_impl(global_object, to(node))); + return static_cast(wrap_impl(global_object, downcast(node))); if (is(node)) - return static_cast(wrap_impl(global_object, to(node))); + return static_cast(wrap_impl(global_object, downcast(node))); if (is(node)) - return static_cast(wrap_impl(global_object, to(node))); + return static_cast(wrap_impl(global_object, downcast(node))); if (is(node)) - return static_cast(wrap_impl(global_object, to(node))); + return static_cast(wrap_impl(global_object, downcast(node))); if (is(node)) - return static_cast(wrap_impl(global_object, to(node))); + return static_cast(wrap_impl(global_object, downcast(node))); if (is(node)) - return static_cast(wrap_impl(global_object, to(node))); + return static_cast(wrap_impl(global_object, downcast(node))); return static_cast(wrap_impl(global_object, node)); } diff --git a/Libraries/LibWeb/CSS/SelectorEngine.cpp b/Libraries/LibWeb/CSS/SelectorEngine.cpp index b080c37edc2..862d5abb3b6 100644 --- a/Libraries/LibWeb/CSS/SelectorEngine.cpp +++ b/Libraries/LibWeb/CSS/SelectorEngine.cpp @@ -131,7 +131,7 @@ bool matches(const Selector& selector, int component_list_index, const Element& for (auto* ancestor = element.parent(); ancestor; ancestor = ancestor->parent()) { if (!is(*ancestor)) continue; - if (matches(selector, component_list_index - 1, to(*ancestor))) + if (matches(selector, component_list_index - 1, downcast(*ancestor))) return true; } return false; @@ -139,7 +139,7 @@ bool matches(const Selector& selector, int component_list_index, const Element& ASSERT(component_list_index != 0); if (!element.parent() || !is(*element.parent())) return false; - return matches(selector, component_list_index - 1, to(*element.parent())); + return matches(selector, component_list_index - 1, downcast(*element.parent())); case Selector::ComplexSelector::Relation::AdjacentSibling: ASSERT(component_list_index != 0); if (auto* sibling = element.previous_element_sibling()) diff --git a/Libraries/LibWeb/DOM/CharacterData.h b/Libraries/LibWeb/DOM/CharacterData.h index 3589069db53..89ec53b48b1 100644 --- a/Libraries/LibWeb/DOM/CharacterData.h +++ b/Libraries/LibWeb/DOM/CharacterData.h @@ -47,10 +47,8 @@ private: String m_data; }; -template<> -inline bool is(const Node& node) -{ - return node.is_character_data(); } -} +AK_BEGIN_TYPE_TRAITS(Web::CharacterData) +static bool is_type(const Web::Node& node) { return node.is_character_data(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/DOM/Comment.h b/Libraries/LibWeb/DOM/Comment.h index 13336833ffb..c05f7887541 100644 --- a/Libraries/LibWeb/DOM/Comment.h +++ b/Libraries/LibWeb/DOM/Comment.h @@ -39,10 +39,8 @@ public: virtual FlyString node_name() const override { return "#comment"; } }; -template<> -inline bool is(const Node& node) -{ - return node.is_comment(); } -} +AK_BEGIN_TYPE_TRAITS(Web::Comment) +static bool is_type(const Web::Node& node) { return node.is_comment(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/DOM/Document.h b/Libraries/LibWeb/DOM/Document.h index ce198415f50..6caa5a06dcd 100644 --- a/Libraries/LibWeb/DOM/Document.h +++ b/Libraries/LibWeb/DOM/Document.h @@ -188,10 +188,9 @@ private: QuirksMode m_quirks_mode { QuirksMode::No }; }; -template<> -inline bool is(const Node& node) -{ - return node.is_document(); } -} +AK_BEGIN_TYPE_TRAITS(Web::Document) +static bool is_type(const Web::Node& node) { return node.is_document(); } +AK_END_TYPE_TRAITS() + diff --git a/Libraries/LibWeb/DOM/DocumentFragment.h b/Libraries/LibWeb/DOM/DocumentFragment.h index d01704338c6..a92207b5c03 100644 --- a/Libraries/LibWeb/DOM/DocumentFragment.h +++ b/Libraries/LibWeb/DOM/DocumentFragment.h @@ -44,10 +44,8 @@ public: virtual FlyString node_name() const override { return "#document-fragment"; } }; -template<> -inline bool is(const Node& node) -{ - return node.is_document_fragment(); } -} +AK_BEGIN_TYPE_TRAITS(Web::DocumentFragment) +static bool is_type(const Web::Node& node) { return node.is_document_fragment(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/DOM/DocumentType.h b/Libraries/LibWeb/DOM/DocumentType.h index 0d538efe2f0..940204329fd 100644 --- a/Libraries/LibWeb/DOM/DocumentType.h +++ b/Libraries/LibWeb/DOM/DocumentType.h @@ -55,10 +55,8 @@ private: String m_system_id; }; -template<> -inline bool is(const Node& node) -{ - return node.type() == NodeType::DOCUMENT_TYPE_NODE; } -} +AK_BEGIN_TYPE_TRAITS(Web::DocumentType) +static bool is_type(const Web::Node& node) { return node.type() == Web::NodeType::DOCUMENT_TYPE_NODE; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp index 21dc1b0d7b4..ec52e4b79a5 100644 --- a/Libraries/LibWeb/DOM/Element.cpp +++ b/Libraries/LibWeb/DOM/Element.cpp @@ -271,17 +271,17 @@ String Element::inner_html() const for (auto* child = node.first_child(); child; child = child->next_sibling()) { if (child->is_element()) { builder.append('<'); - builder.append(to(*child).local_name()); + builder.append(downcast(*child).local_name()); builder.append('>'); recurse(*child); builder.append("(*child).local_name()); + builder.append(downcast(*child).local_name()); builder.append('>'); } if (child->is_text()) { - builder.append(to(*child).data()); + builder.append(downcast(*child).data()); } } }; diff --git a/Libraries/LibWeb/DOM/Element.h b/Libraries/LibWeb/DOM/Element.h index f9b6f3e70c9..2c6fecb2d7c 100644 --- a/Libraries/LibWeb/DOM/Element.h +++ b/Libraries/LibWeb/DOM/Element.h @@ -99,10 +99,8 @@ private: Vector m_classes; }; -template<> -inline bool is(const Node& node) -{ - return node.is_element(); } -} +AK_BEGIN_TYPE_TRAITS(Web::Element) +static bool is_type(const Web::Node& node) { return node.is_element(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/DOM/Node.cpp b/Libraries/LibWeb/DOM/Node.cpp index fe03ed2cb6d..3dcc40ad2a9 100644 --- a/Libraries/LibWeb/DOM/Node.cpp +++ b/Libraries/LibWeb/DOM/Node.cpp @@ -65,8 +65,8 @@ Node::~Node() const HTMLAnchorElement* Node::enclosing_link_element() const { for (auto* node = this; node; node = node->parent()) { - if (is(*node) && to(*node).has_attribute(HTML::AttributeNames::href)) - return to(node); + if (is(*node) && downcast(*node).has_attribute(HTML::AttributeNames::href)) + return downcast(node); } return nullptr; } @@ -160,9 +160,9 @@ String Node::child_text_content() const return String::empty(); StringBuilder builder; - to(*this).for_each_child([&](auto& child) { + downcast(*this).for_each_child([&](auto& child) { if (is(child)) - builder.append(to(child).text_content()); + builder.append(downcast(child).text_content()); }); return builder.build(); } @@ -184,14 +184,14 @@ Element* Node::parent_element() { if (!parent() || !is(parent())) return nullptr; - return to(parent()); + return downcast(parent()); } const Element* Node::parent_element() const { if (!parent() || !is(parent())) return nullptr; - return to(parent()); + return downcast(parent()); } RefPtr Node::append_child(NonnullRefPtr node, bool notify) diff --git a/Libraries/LibWeb/DOM/Node.h b/Libraries/LibWeb/DOM/Node.h index 4e1da6b0e1c..b97c5c6da3b 100644 --- a/Libraries/LibWeb/DOM/Node.h +++ b/Libraries/LibWeb/DOM/Node.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -116,9 +117,9 @@ public: template const T* first_ancestor_of_type() const; - virtual void inserted_into(Node&) {} - virtual void removed_from(Node&) {} - virtual void children_changed() {} + virtual void inserted_into(Node&) { } + virtual void removed_from(Node&) { } + virtual void children_changed() { } const LayoutNode* layout_node() const { return m_layout_node; } LayoutNode* layout_node() { return m_layout_node; } @@ -137,8 +138,8 @@ public: bool is_link() const; - virtual void document_did_attach_to_frame(Frame&) {} - virtual void document_will_detach_from_frame(Frame&) {} + virtual void document_did_attach_to_frame(Frame&) { } + virtual void document_will_detach_from_frame(Frame&) { } void set_document(Badge, Document&); @@ -151,64 +152,12 @@ protected: bool m_needs_style_update { true }; }; -template -inline bool is(const Node&) -{ - return false; -} - -template -inline bool is(const Node* node) -{ - return !node || is(*node); -} - -template<> -inline bool is(const Node&) -{ - return true; -} - -template<> -inline bool is(const Node& node) -{ - return node.is_parent_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* 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 downcast(child); } return nullptr; } @@ -218,7 +167,7 @@ inline const T* Node::first_ancestor_of_type() const { for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { if (is(*ancestor)) - return to(ancestor); + return downcast(ancestor); } return nullptr; } diff --git a/Libraries/LibWeb/DOM/ParentNode.h b/Libraries/LibWeb/DOM/ParentNode.h index cc86505a8e0..0f3fafab1f5 100644 --- a/Libraries/LibWeb/DOM/ParentNode.h +++ b/Libraries/LibWeb/DOM/ParentNode.h @@ -59,3 +59,7 @@ inline void ParentNode::for_each_child(Callback callback) } } + +AK_BEGIN_TYPE_TRAITS(Web::ParentNode) +static bool is_type(const Web::Node& node) { return node.is_parent_node(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/DOM/Text.h b/Libraries/LibWeb/DOM/Text.h index c1425adba35..241da5cbf39 100644 --- a/Libraries/LibWeb/DOM/Text.h +++ b/Libraries/LibWeb/DOM/Text.h @@ -43,10 +43,8 @@ private: virtual RefPtr create_layout_node(const StyleProperties* parent_style) override; }; -template<> -inline bool is(const Node& node) -{ - return node.is_text(); } -} +AK_BEGIN_TYPE_TRAITS(Web::Text) +static bool is_type(const Web::Node& node) { return node.is_text(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/DOMTreeModel.cpp b/Libraries/LibWeb/DOMTreeModel.cpp index c87f48f7c82..e31503fabb9 100644 --- a/Libraries/LibWeb/DOMTreeModel.cpp +++ b/Libraries/LibWeb/DOMTreeModel.cpp @@ -128,10 +128,10 @@ GUI::Variant DOMTreeModel::data(const GUI::ModelIndex& index, Role role) const } if (role == Role::Display) { if (node.is_text()) - return String::format("%s", with_whitespace_collapsed(to(node).data()).characters()); + return String::format("%s", with_whitespace_collapsed(downcast(node).data()).characters()); if (!node.is_element()) return node.node_name(); - auto& element = to(node); + auto& element = downcast(node); StringBuilder builder; builder.append('<'); builder.append(element.local_name()); diff --git a/Libraries/LibWeb/Dump.cpp b/Libraries/LibWeb/Dump.cpp index 1225027e505..8704827dd73 100644 --- a/Libraries/LibWeb/Dump.cpp +++ b/Libraries/LibWeb/Dump.cpp @@ -51,8 +51,8 @@ void dump_tree(const Node& node) if (is(node)) { dbgprintf("*Document*\n"); } else if (is(node)) { - dbgprintf("<%s", to(node).local_name().characters()); - to(node).for_each_attribute([](auto& name, auto& value) { + dbgprintf("<%s", downcast(node).local_name().characters()); + downcast(node).for_each_attribute([](auto& name, auto& value) { dbgprintf(" %s=%s", name.characters(), value.characters()); }); dbgprintf(">\n"); @@ -61,7 +61,7 @@ void dump_tree(const Node& node) } else if (is(node)) { dbgprintf("\n"); } else if (is(node)) { - dbgprintf("\n", to(node).data().characters()); + dbgprintf("\n", downcast(node).data().characters()); } else if (is(node)) { dbgprintf("#document-fragment\n"); } @@ -88,13 +88,13 @@ void dump_tree(const LayoutNode& layout_node) else if (is(layout_node.node())) tag_name = "#document"; else if (is(layout_node.node())) - tag_name = to(*layout_node.node()).local_name(); + tag_name = downcast(*layout_node.node()).local_name(); else tag_name = "???"; String identifier = ""; if (layout_node.node() && is(*layout_node.node())) { - auto& element = to(*layout_node.node()); + auto& element = downcast(*layout_node.node()); StringBuilder builder; auto id = element.attribute(HTML::AttributeNames::id); if (!id.is_empty()) { @@ -111,7 +111,7 @@ void dump_tree(const LayoutNode& layout_node) if (!layout_node.is_box()) { dbgprintf("%s {\033[33m%s\033[0m%s}\n", layout_node.class_name(), tag_name.characters(), identifier.characters()); } else { - auto& layout_box = to(layout_node); + auto& layout_box = downcast(layout_node); dbgprintf("%s {\033[34m%s\033[0m%s} at (%g,%g) size %gx%g", layout_box.class_name(), tag_name.characters(), diff --git a/Libraries/LibWeb/Frame/EventHandler.cpp b/Libraries/LibWeb/Frame/EventHandler.cpp index 11f461a46fa..f95661e31f4 100644 --- a/Libraries/LibWeb/Frame/EventHandler.cpp +++ b/Libraries/LibWeb/Frame/EventHandler.cpp @@ -80,7 +80,7 @@ bool EventHandler::handle_mouseup(const Gfx::IntPoint& position, unsigned button if (result.layout_node && result.layout_node->node()) { RefPtr node = result.layout_node->node(); if (is(*node)) { - if (auto* subframe = to(*node).hosted_frame()) + if (auto* subframe = downcast(*node).hosted_frame()) return subframe->event_handler().handle_mouseup(position.translated(compute_mouse_event_offset({}, *result.layout_node)), button, modifiers); return false; } @@ -113,7 +113,7 @@ bool EventHandler::handle_mousedown(const Gfx::IntPoint& position, unsigned butt return false; if (is(*node)) { - if (auto* subframe = to(*node).hosted_frame()) + if (auto* subframe = downcast(*node).hosted_frame()) return subframe->event_handler().handle_mousedown(position.translated(compute_mouse_event_offset({}, *result.layout_node)), button, modifiers); return false; } @@ -176,7 +176,7 @@ bool EventHandler::handle_mousemove(const Gfx::IntPoint& position, unsigned butt RefPtr node = result.layout_node->node(); if (node && is(*node)) { - if (auto* subframe = to(*node).hosted_frame()) + if (auto* subframe = downcast(*node).hosted_frame()) return subframe->event_handler().handle_mousemove(position.translated(compute_mouse_event_offset({}, *result.layout_node)), buttons, modifiers); return false; } diff --git a/Libraries/LibWeb/Frame/Frame.cpp b/Libraries/LibWeb/Frame/Frame.cpp index 4faef43d497..0631a205955 100644 --- a/Libraries/LibWeb/Frame/Frame.cpp +++ b/Libraries/LibWeb/Frame/Frame.cpp @@ -125,7 +125,7 @@ void Frame::scroll_to_anchor(const String& fragment) auto candidates = document()->get_elements_by_name(fragment); for (auto* candidate : candidates) { if (is(*candidate)) { - element = to(candidate); + element = downcast(candidate); break; } } @@ -138,7 +138,7 @@ void Frame::scroll_to_anchor(const String& fragment) Gfx::FloatRect float_rect { layout_node.box_type_agnostic_position(), { (float)viewport_rect().width(), (float)viewport_rect().height() } }; if (is(layout_node)) { - auto& layout_box = to(layout_node); + auto& layout_box = downcast(layout_node); auto padding_box = layout_box.box_model().padding_box(layout_box); float_rect.move_by(-padding_box.left, -padding_box.top); } diff --git a/Libraries/LibWeb/HTML/HTMLAnchorElement.h b/Libraries/LibWeb/HTML/HTMLAnchorElement.h index a7973040a1f..66432a8e5df 100644 --- a/Libraries/LibWeb/HTML/HTMLAnchorElement.h +++ b/Libraries/LibWeb/HTML/HTMLAnchorElement.h @@ -39,10 +39,8 @@ public: String target() const { return attribute(HTML::AttributeNames::target); } }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::a; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLAnchorElement) +static bool is_type(const Web::Node& node) { return node.is_element() && downcast(node).local_name() == Web::HTML::TagNames::a; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLBRElement.h b/Libraries/LibWeb/HTML/HTMLBRElement.h index 7d2aa8ffd34..051e4d5cc78 100644 --- a/Libraries/LibWeb/HTML/HTMLBRElement.h +++ b/Libraries/LibWeb/HTML/HTMLBRElement.h @@ -38,10 +38,8 @@ public: virtual RefPtr create_layout_node(const StyleProperties* parent_style) override; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::br; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLBRElement) +static bool is_type(const Web::Node& node) { return node.is_element() && downcast(node).local_name() == Web::HTML::TagNames::br; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLBlinkElement.h b/Libraries/LibWeb/HTML/HTMLBlinkElement.h index 23773a4bc2e..ca442766974 100644 --- a/Libraries/LibWeb/HTML/HTMLBlinkElement.h +++ b/Libraries/LibWeb/HTML/HTMLBlinkElement.h @@ -42,10 +42,8 @@ private: NonnullRefPtr m_timer; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::blink; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLBlinkElement) +static bool is_type(const Web::Node& node) { return node.is_element() && downcast(node).local_name() == Web::HTML::TagNames::blink; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLBodyElement.h b/Libraries/LibWeb/HTML/HTMLBodyElement.h index 4c872cefdaa..66b3fe2133d 100644 --- a/Libraries/LibWeb/HTML/HTMLBodyElement.h +++ b/Libraries/LibWeb/HTML/HTMLBodyElement.h @@ -42,10 +42,8 @@ private: RefPtr m_background_style_value; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::body; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLBodyElement) +static bool is_type(const Web::Node& node) { return node.is_element() && downcast(node).local_name() == Web::HTML::TagNames::body; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLCanvasElement.h b/Libraries/LibWeb/HTML/HTMLCanvasElement.h index b074d01452f..1e2721f2b61 100644 --- a/Libraries/LibWeb/HTML/HTMLCanvasElement.h +++ b/Libraries/LibWeb/HTML/HTMLCanvasElement.h @@ -57,10 +57,8 @@ private: RefPtr m_context; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::canvas; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLCanvasElement) +static bool is_type(const Web::Node& node) { return node.is_element() && downcast(node).local_name() == Web::HTML::TagNames::canvas; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLElement.h b/Libraries/LibWeb/HTML/HTMLElement.h index 3323f7e821d..91af28ace8c 100644 --- a/Libraries/LibWeb/HTML/HTMLElement.h +++ b/Libraries/LibWeb/HTML/HTMLElement.h @@ -43,10 +43,8 @@ private: virtual bool is_html_element() const final { return true; } }; -template<> -inline bool is(const Node& node) -{ - return node.is_html_element(); } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLElement) +static bool is_type(const Web::Node& node) { return node.is_html_element(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLFontElement.h b/Libraries/LibWeb/HTML/HTMLFontElement.h index 9397f757ca5..7b453989c23 100644 --- a/Libraries/LibWeb/HTML/HTMLFontElement.h +++ b/Libraries/LibWeb/HTML/HTMLFontElement.h @@ -38,10 +38,8 @@ public: virtual void apply_presentational_hints(StyleProperties&) const override; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::font; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLFontElement) +static bool is_type(const Web::Node& node) { return node.is_element() && downcast(node).local_name() == Web::HTML::TagNames::font; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLFormElement.cpp b/Libraries/LibWeb/HTML/HTMLFormElement.cpp index e63ad4bcdaf..3fca0f4a676 100644 --- a/Libraries/LibWeb/HTML/HTMLFormElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLFormElement.cpp @@ -63,7 +63,7 @@ void HTMLFormElement::submit(RefPtr submitter) Vector parameters; for_each_in_subtree_of_type([&](auto& node) { - auto& input = to(node); + auto& input = downcast(node); if (!input.name().is_null() && (input.type() != "submit" || &input == submitter)) parameters.append({ input.name(), input.value() }); return IterationDecision::Continue; diff --git a/Libraries/LibWeb/HTML/HTMLFormElement.h b/Libraries/LibWeb/HTML/HTMLFormElement.h index 056d6095ac7..68fb24e07d9 100644 --- a/Libraries/LibWeb/HTML/HTMLFormElement.h +++ b/Libraries/LibWeb/HTML/HTMLFormElement.h @@ -42,10 +42,8 @@ public: void submit(RefPtr submitter); }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::form; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLFormElement) +static bool is_type(const Web::Node& node) { return node.is_html_element() && downcast(node).local_name() == Web::HTML::TagNames::form; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLHRElement.h b/Libraries/LibWeb/HTML/HTMLHRElement.h index 04d2cbe2175..0cbef63841a 100644 --- a/Libraries/LibWeb/HTML/HTMLHRElement.h +++ b/Libraries/LibWeb/HTML/HTMLHRElement.h @@ -36,10 +36,8 @@ public: virtual ~HTMLHRElement() override; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::hr; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLHRElement) +static bool is_type(const Web::Node& node) { return node.is_html_element() && downcast(node).local_name() == Web::HTML::TagNames::hr; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLHeadElement.h b/Libraries/LibWeb/HTML/HTMLHeadElement.h index 9498749c324..050d4db3449 100644 --- a/Libraries/LibWeb/HTML/HTMLHeadElement.h +++ b/Libraries/LibWeb/HTML/HTMLHeadElement.h @@ -36,10 +36,8 @@ public: virtual ~HTMLHeadElement() override; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name().equals_ignoring_case("head"); } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLHeadElement) +static bool is_type(const Web::Node& node) { return node.is_element() && downcast(node).local_name() == Web::HTML::TagNames::head; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLHtmlElement.h b/Libraries/LibWeb/HTML/HTMLHtmlElement.h index 85996a51baa..14b28ec11a2 100644 --- a/Libraries/LibWeb/HTML/HTMLHtmlElement.h +++ b/Libraries/LibWeb/HTML/HTMLHtmlElement.h @@ -36,10 +36,8 @@ public: virtual ~HTMLHtmlElement() override; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name().equals_ignoring_case("html"); } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLHtmlElement) +static bool is_type(const Web::Node& node) { return node.is_html_element() && downcast(node).local_name() == Web::HTML::TagNames::html; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLIFrameElement.h b/Libraries/LibWeb/HTML/HTMLIFrameElement.h index e33af818e3d..27ff1ca43cf 100644 --- a/Libraries/LibWeb/HTML/HTMLIFrameElement.h +++ b/Libraries/LibWeb/HTML/HTMLIFrameElement.h @@ -51,10 +51,8 @@ private: RefPtr m_hosted_frame; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::iframe; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLIFrameElement) +static bool is_type(const Web::Node& node) { return node.is_html_element() && downcast(node).local_name() == Web::HTML::TagNames::iframe; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLImageElement.h b/Libraries/LibWeb/HTML/HTMLImageElement.h index a5625e16a57..432df2fc89b 100644 --- a/Libraries/LibWeb/HTML/HTMLImageElement.h +++ b/Libraries/LibWeb/HTML/HTMLImageElement.h @@ -60,10 +60,8 @@ private: ImageLoader m_image_loader; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::img; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLImageElement) +static bool is_type(const Web::Node& node) { return node.is_element() && downcast(node).local_name() == Web::HTML::TagNames::img; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 0dff7eab8d1..8d80808f6d0 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -83,7 +83,7 @@ RefPtr HTMLInputElement::create_layout_node(const StyleProperties* p auto& text_box = page_view.add(); text_box.set_text(value()); text_box.on_change = [this] { - auto& widget = to(layout_node())->widget(); + auto& widget = downcast(layout_node())->widget(); const_cast(this)->set_attribute(HTML::AttributeNames::value, static_cast(widget).text()); }; int text_width = Gfx::Font::default_font().width(value()); diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.h b/Libraries/LibWeb/HTML/HTMLInputElement.h index f695d1355a5..4b438357c40 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.h +++ b/Libraries/LibWeb/HTML/HTMLInputElement.h @@ -42,10 +42,8 @@ public: String name() const { return attribute(HTML::AttributeNames::name); } }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::input; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLInputElement) +static bool is_type(const Web::Node& node) { return node.is_html_element() && downcast(node).local_name() == Web::HTML::TagNames::input; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLLinkElement.h b/Libraries/LibWeb/HTML/HTMLLinkElement.h index 57eddf30828..42b6f9ac751 100644 --- a/Libraries/LibWeb/HTML/HTMLLinkElement.h +++ b/Libraries/LibWeb/HTML/HTMLLinkElement.h @@ -64,10 +64,8 @@ private: RefPtr m_style_sheet; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::link; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLLinkElement) +static bool is_type(const Web::Node& node) { return node.is_html_element() && downcast(node).local_name() == Web::HTML::TagNames::link; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLObjectElement.h b/Libraries/LibWeb/HTML/HTMLObjectElement.h index b5711de3a9b..6b05b5e5036 100644 --- a/Libraries/LibWeb/HTML/HTMLObjectElement.h +++ b/Libraries/LibWeb/HTML/HTMLObjectElement.h @@ -52,10 +52,8 @@ private: bool m_should_show_fallback_content { false }; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::object; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLObjectElement) +static bool is_type(const Web::Node& node) { return node.is_element() && downcast(node).local_name() == Web::HTML::TagNames::object; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLScriptElement.h b/Libraries/LibWeb/HTML/HTMLScriptElement.h index 0b056eb18bf..8d941b270d0 100644 --- a/Libraries/LibWeb/HTML/HTMLScriptElement.h +++ b/Libraries/LibWeb/HTML/HTMLScriptElement.h @@ -65,10 +65,8 @@ private: String m_script_source; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::script; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLScriptElement) +static bool is_type(const Web::Node& node) { return node.is_html_element() && downcast(node).local_name() == Web::HTML::TagNames::script; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLStyleElement.cpp b/Libraries/LibWeb/HTML/HTMLStyleElement.cpp index c90a8eede9d..841203dfc6a 100644 --- a/Libraries/LibWeb/HTML/HTMLStyleElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLStyleElement.cpp @@ -46,7 +46,7 @@ void HTMLStyleElement::children_changed() StringBuilder builder; for_each_child([&](auto& child) { if (is(child)) - builder.append(to(child).text_content()); + builder.append(downcast(child).text_content()); }); m_stylesheet = parse_css(CSS::ParsingContext(document()), builder.to_string()); if (m_stylesheet) diff --git a/Libraries/LibWeb/HTML/HTMLStyleElement.h b/Libraries/LibWeb/HTML/HTMLStyleElement.h index 390c60dab17..217d277e7f5 100644 --- a/Libraries/LibWeb/HTML/HTMLStyleElement.h +++ b/Libraries/LibWeb/HTML/HTMLStyleElement.h @@ -44,11 +44,8 @@ private: RefPtr m_stylesheet; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::style; } - -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLStyleElement) +static bool is_type(const Web::Node& node) { return node.is_html_element() && downcast(node).local_name() == Web::HTML::TagNames::style; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLTableCellElement.h b/Libraries/LibWeb/HTML/HTMLTableCellElement.h index 09c11e059d5..06bde35ffb0 100644 --- a/Libraries/LibWeb/HTML/HTMLTableCellElement.h +++ b/Libraries/LibWeb/HTML/HTMLTableCellElement.h @@ -39,10 +39,8 @@ private: virtual void apply_presentational_hints(StyleProperties&) const override; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name().is_one_of(HTML::TagNames::td, HTML::TagNames::th); } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLTableCellElement) +static bool is_type(const Web::Node& node) { return node.is_html_element() && downcast(node).local_name() == Web::HTML::TagNames::td; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLTableElement.h b/Libraries/LibWeb/HTML/HTMLTableElement.h index 3a664ba42d8..c26504eff8c 100644 --- a/Libraries/LibWeb/HTML/HTMLTableElement.h +++ b/Libraries/LibWeb/HTML/HTMLTableElement.h @@ -39,10 +39,8 @@ private: virtual void apply_presentational_hints(StyleProperties&) const override; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::table; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLTableElement) +static bool is_type(const Web::Node& node) { return node.is_html_element() && downcast(node).local_name() == Web::HTML::TagNames::table; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLTableRowElement.h b/Libraries/LibWeb/HTML/HTMLTableRowElement.h index 0eebd6d36cf..af81083c271 100644 --- a/Libraries/LibWeb/HTML/HTMLTableRowElement.h +++ b/Libraries/LibWeb/HTML/HTMLTableRowElement.h @@ -36,10 +36,8 @@ public: virtual ~HTMLTableRowElement() override; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name() == HTML::TagNames::tr; } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLTableRowElement) +static bool is_type(const Web::Node& node) { return node.is_html_element() && downcast(node).local_name() == Web::HTML::TagNames::tr; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/HTML/HTMLTitleElement.h b/Libraries/LibWeb/HTML/HTMLTitleElement.h index 8bf1aaf97db..da2ba1dfdef 100644 --- a/Libraries/LibWeb/HTML/HTMLTitleElement.h +++ b/Libraries/LibWeb/HTML/HTMLTitleElement.h @@ -36,10 +36,8 @@ public: virtual ~HTMLTitleElement() override; }; -template<> -inline bool is(const Node& node) -{ - return is(node) && to(node).local_name().equals_ignoring_case("title"); } -} +AK_BEGIN_TYPE_TRAITS(Web::HTMLTitleElement) +static bool is_type(const Web::Node& node) { return node.is_html_element() && downcast(node).local_name() == Web::HTML::TagNames::title; } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutBlock.cpp b/Libraries/LibWeb/Layout/LayoutBlock.cpp index d475fc37a97..686662f3ef8 100644 --- a/Libraries/LibWeb/Layout/LayoutBlock.cpp +++ b/Libraries/LibWeb/Layout/LayoutBlock.cpp @@ -155,13 +155,13 @@ void LayoutBlock::layout_contained_boxes(LayoutMode layout_mode) return IterationDecision::Continue; box.layout(layout_mode); if (box.is_replaced()) - place_block_level_replaced_element_in_normal_flow(to(box)); + place_block_level_replaced_element_in_normal_flow(downcast(box)); else if (box.is_block()) - place_block_level_non_replaced_element_in_normal_flow(to(box)); + place_block_level_non_replaced_element_in_normal_flow(downcast(box)); else dbg() << "FIXME: LayoutBlock::layout_contained_boxes doesn't know how to place a " << box.class_name(); content_height = max(content_height, box.effective_offset().y() + box.height() + box.box_model().margin_box(*this).bottom); - content_width = max(content_width, to(box).width()); + content_width = max(content_width, downcast(box).width()); return IterationDecision::Continue; }); @@ -257,7 +257,7 @@ void LayoutBlock::layout_inline_children(LayoutMode layout_mode) } if (fragment.layout_node().is_inline_block()) { - auto& inline_block = const_cast(to(fragment.layout_node())); + auto& inline_block = const_cast(downcast(fragment.layout_node())); inline_block.set_size(fragment.size()); inline_block.layout(layout_mode); } @@ -587,7 +587,7 @@ LayoutBlock::ShrinkToFitResult LayoutBlock::calculate_shrink_to_fit_width() } else { for_each_child([&](auto& child) { if (child.is_box()) - max_width = max(max_width, to(child).width()); + max_width = max(max_width, downcast(child).width()); }); } return max_width; @@ -725,11 +725,11 @@ HitTestResult LayoutBlock::hit_test(const Gfx::IntPoint& position) const HitTestResult last_good_candidate; for (auto& line_box : m_line_boxes) { for (auto& fragment : line_box.fragments()) { - if (is(fragment.layout_node()) && to(fragment.layout_node()).stacking_context()) + if (is(fragment.layout_node()) && downcast(fragment.layout_node()).stacking_context()) continue; if (enclosing_int_rect(fragment.absolute_rect()).contains(position)) { if (fragment.layout_node().is_block()) - return to(fragment.layout_node()).hit_test(position); + return downcast(fragment.layout_node()).hit_test(position); return { fragment.layout_node(), fragment.text_index_at(position.x()) }; } if (fragment.absolute_rect().top() <= position.y()) diff --git a/Libraries/LibWeb/Layout/LayoutBlock.h b/Libraries/LibWeb/Layout/LayoutBlock.h index 7c174aa7711..563588bba34 100644 --- a/Libraries/LibWeb/Layout/LayoutBlock.h +++ b/Libraries/LibWeb/Layout/LayoutBlock.h @@ -53,10 +53,10 @@ public: virtual HitTestResult hit_test(const Gfx::IntPoint&) const override; - LayoutBlock* previous_sibling() { return to(LayoutNode::previous_sibling()); } - const LayoutBlock* previous_sibling() const { return to(LayoutNode::previous_sibling()); } - LayoutBlock* next_sibling() { return to(LayoutNode::next_sibling()); } - const LayoutBlock* next_sibling() const { return to(LayoutNode::next_sibling()); } + LayoutBlock* previous_sibling() { return downcast(LayoutNode::previous_sibling()); } + const LayoutBlock* previous_sibling() const { return downcast(LayoutNode::previous_sibling()); } + LayoutBlock* next_sibling() { return downcast(LayoutNode::next_sibling()); } + const LayoutBlock* next_sibling() const { return downcast(LayoutNode::next_sibling()); } template void for_each_fragment(Callback); @@ -119,10 +119,8 @@ void LayoutBlock::for_each_fragment(Callback callback) const } } -template<> -ALWAYS_INLINE bool is(const LayoutNode& node) -{ - return node.is_block(); } -} +AK_BEGIN_TYPE_TRAITS(Web::LayoutBlock) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_block(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutBox.cpp b/Libraries/LibWeb/Layout/LayoutBox.cpp index 25c6c34e572..128f0e1fca7 100644 --- a/Libraries/LibWeb/Layout/LayoutBox.cpp +++ b/Libraries/LibWeb/Layout/LayoutBox.cpp @@ -231,7 +231,7 @@ HitTestResult LayoutBox::hit_test(const Gfx::IntPoint& position) const // m_rect.contains() since inline text rects can't be trusted.. HitTestResult result { absolute_rect().contains(position.x(), position.y()) ? this : nullptr }; for_each_child([&](auto& child) { - if (is(child) && to(child).stacking_context()) + if (is(child) && downcast(child).stacking_context()) return; auto child_result = child.hit_test(position); if (child_result.layout_node) @@ -297,7 +297,7 @@ StackingContext* LayoutBox::enclosing_stacking_context() for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { if (!ancestor->is_box()) continue; - auto& ancestor_box = to(*ancestor); + auto& ancestor_box = downcast(*ancestor); if (!ancestor_box.establishes_stacking_context()) continue; ASSERT(ancestor_box.stacking_context()); diff --git a/Libraries/LibWeb/Layout/LayoutBox.h b/Libraries/LibWeb/Layout/LayoutBox.h index 1387a9ad0db..77eea22fd91 100644 --- a/Libraries/LibWeb/Layout/LayoutBox.h +++ b/Libraries/LibWeb/Layout/LayoutBox.h @@ -98,10 +98,8 @@ private: OwnPtr m_stacking_context; }; -template<> -ALWAYS_INLINE bool is(const LayoutNode& node) -{ - return node.is_box(); } -} +AK_BEGIN_TYPE_TRAITS(Web::LayoutBox) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_box(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutBreak.h b/Libraries/LibWeb/Layout/LayoutBreak.h index 1d52acaf4cc..cfb6e1ce8c7 100644 --- a/Libraries/LibWeb/Layout/LayoutBreak.h +++ b/Libraries/LibWeb/Layout/LayoutBreak.h @@ -36,11 +36,16 @@ public: LayoutBreak(Document&, const HTMLBRElement&); virtual ~LayoutBreak() override; - const HTMLBRElement& node() const { return to(*LayoutNode::node()); } + const HTMLBRElement& node() const { return downcast(*LayoutNode::node()); } private: + virtual bool is_break() const override { return true; } virtual const char* class_name() const override { return "LayoutBreak"; } virtual void split_into_lines(LayoutBlock&, LayoutMode) override; }; } + +AK_BEGIN_TYPE_TRAITS(Web::LayoutBreak) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_break(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutCanvas.h b/Libraries/LibWeb/Layout/LayoutCanvas.h index 1808e217864..e6174fdc51a 100644 --- a/Libraries/LibWeb/Layout/LayoutCanvas.h +++ b/Libraries/LibWeb/Layout/LayoutCanvas.h @@ -48,10 +48,9 @@ private: virtual bool is_canvas() const override { return true; } }; -template<> -inline bool is(const LayoutNode& node) -{ - return node.is_canvas(); -} } + +AK_BEGIN_TYPE_TRAITS(Web::LayoutCanvas) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_canvas(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutDocument.cpp b/Libraries/LibWeb/Layout/LayoutDocument.cpp index b30b6486ef2..566a4375cc8 100644 --- a/Libraries/LibWeb/Layout/LayoutDocument.cpp +++ b/Libraries/LibWeb/Layout/LayoutDocument.cpp @@ -76,7 +76,7 @@ void LayoutDocument::layout(LayoutMode layout_mode) float lowest_bottom = 0; for_each_child([&](auto& child) { ASSERT(is(child)); - auto& child_block = to(child); + auto& child_block = downcast(child); lowest_bottom = max(lowest_bottom, child_block.absolute_rect().bottom()); }); set_height(lowest_bottom); diff --git a/Libraries/LibWeb/Layout/LayoutDocument.h b/Libraries/LibWeb/Layout/LayoutDocument.h index eb37187e654..cf81ca2c7e9 100644 --- a/Libraries/LibWeb/Layout/LayoutDocument.h +++ b/Libraries/LibWeb/Layout/LayoutDocument.h @@ -58,11 +58,8 @@ private: LayoutRange m_selection; }; -template<> -inline bool is(const LayoutNode& node) -{ - return node.is_root(); } - -} +AK_BEGIN_TYPE_TRAITS(Web::LayoutDocument) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_root(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutFrame.h b/Libraries/LibWeb/Layout/LayoutFrame.h index 10f5d62b6b1..eda86fe4a8e 100644 --- a/Libraries/LibWeb/Layout/LayoutFrame.h +++ b/Libraries/LibWeb/Layout/LayoutFrame.h @@ -48,10 +48,8 @@ private: virtual void did_set_rect() override; }; -template<> -inline bool is(const LayoutNode& node) -{ - return node.is_frame(); } -} +AK_BEGIN_TYPE_TRAITS(Web::LayoutFrame) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_frame(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutImage.cpp b/Libraries/LibWeb/Layout/LayoutImage.cpp index b61e0c94737..a8025d49188 100644 --- a/Libraries/LibWeb/Layout/LayoutImage.cpp +++ b/Libraries/LibWeb/Layout/LayoutImage.cpp @@ -71,7 +71,7 @@ void LayoutImage::layout(LayoutMode layout_mode) } if (renders_as_alt_text()) { - auto& image_element = to(node()); + auto& image_element = downcast(node()); auto& font = Gfx::Font::default_font(); auto alt = image_element.alt(); if (alt.is_empty()) @@ -101,7 +101,7 @@ void LayoutImage::paint(PaintContext& context, PaintPhase phase) if (phase == PaintPhase::Foreground) { if (renders_as_alt_text()) { - auto& image_element = to(node()); + auto& image_element = downcast(node()); context.painter().set_font(Gfx::Font::default_font()); Gfx::StylePainter::paint_frame(context.painter(), enclosing_int_rect(absolute_rect()), context.palette(), Gfx::FrameShape::Container, Gfx::FrameShadow::Sunken, 2); auto alt = image_element.alt(); diff --git a/Libraries/LibWeb/Layout/LayoutImage.h b/Libraries/LibWeb/Layout/LayoutImage.h index 7e639fda2bb..2ef47279c76 100644 --- a/Libraries/LibWeb/Layout/LayoutImage.h +++ b/Libraries/LibWeb/Layout/LayoutImage.h @@ -57,10 +57,8 @@ private: const ImageLoader& m_image_loader; }; -template<> -inline bool is(const LayoutNode& node) -{ - return node.is_image(); } -} +AK_BEGIN_TYPE_TRAITS(Web::LayoutImage) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_image(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutNode.cpp b/Libraries/LibWeb/Layout/LayoutNode.cpp index 0e6647de1ea..2b46cbe9e17 100644 --- a/Libraries/LibWeb/Layout/LayoutNode.cpp +++ b/Libraries/LibWeb/Layout/LayoutNode.cpp @@ -67,7 +67,7 @@ const LayoutBlock* LayoutNode::containing_block() const auto* ancestor = parent(); while (ancestor && !is(*ancestor)) ancestor = ancestor->parent(); - return to(ancestor); + return downcast(ancestor); }; if (is_text()) @@ -81,7 +81,7 @@ const LayoutBlock* LayoutNode::containing_block() const ancestor = ancestor->parent(); while (ancestor && (!is(ancestor) || ancestor->is_anonymous())) ancestor = ancestor->containing_block(); - return to(ancestor); + return downcast(ancestor); } if (position == CSS::Position::Fixed) @@ -96,7 +96,7 @@ void LayoutNode::paint(PaintContext& context, PaintPhase phase) return; for_each_child([&](auto& child) { - if (child.is_box() && to(child).stacking_context()) + if (child.is_box() && downcast(child).stacking_context()) return; child.paint(context, phase); }); @@ -108,7 +108,7 @@ HitTestResult LayoutNode::hit_test(const Gfx::IntPoint& position) const for_each_child([&](auto& child) { // Skip over children that establish their own stacking context. // The outer loop who called us will take care of those. - if (is(child) && to(child).stacking_context()) + if (is(child) && downcast(child).stacking_context()) return; auto child_result = child.hit_test(position); if (child_result.layout_node) @@ -170,7 +170,7 @@ float LayoutNode::font_size() const Gfx::FloatPoint LayoutNode::box_type_agnostic_position() const { if (is_box()) - return to(*this).absolute_position(); + return downcast(*this).absolute_position(); ASSERT(is_inline()); Gfx::FloatPoint position; if (auto* block = containing_block()) { diff --git a/Libraries/LibWeb/Layout/LayoutNode.h b/Libraries/LibWeb/Layout/LayoutNode.h index cb5ccc08e6e..571584baeb5 100644 --- a/Libraries/LibWeb/Layout/LayoutNode.h +++ b/Libraries/LibWeb/Layout/LayoutNode.h @@ -27,6 +27,7 @@ #pragma once #include +#include #include #include #include @@ -40,52 +41,6 @@ namespace Web { -template -inline bool is(const LayoutNode&) -{ - return false; -} - -template -inline bool is(const LayoutNode* node) -{ - return !node || is(*node); -} - -template<> -inline bool is(const LayoutNode&) -{ - return true; -} - -template -inline const T& to(const LayoutNode& node) -{ - ASSERT(is(node)); - return static_cast(node); -} - -template -inline T* to(LayoutNode* node) -{ - ASSERT(is(node)); - return static_cast(node); -} - -template -inline const T* to(const LayoutNode* node) -{ - ASSERT(is(node)); - return static_cast(node); -} - -template -inline T& to(LayoutNode& node) -{ - ASSERT(is(node)); - return static_cast(node); -} - struct HitTestResult { RefPtr layout_node; int index_in_node { 0 }; @@ -130,7 +85,7 @@ public: for (auto* node = first_child(); node; node = node->next_sibling()) { if (!is(node)) continue; - callback(to(*node)); + callback(downcast(*node)); } } @@ -140,7 +95,7 @@ public: for (auto* node = first_child(); node; node = node->next_sibling()) { if (!is(node)) continue; - callback(to(*node)); + callback(downcast(*node)); } } @@ -158,6 +113,7 @@ public: virtual bool is_table_row() const { return false; } virtual bool is_table_cell() const { return false; } virtual bool is_table_row_group() const { return false; } + virtual bool is_break() const { return false; } bool has_style() const { return m_has_style; } bool is_inline() const { return m_inline; } @@ -269,7 +225,6 @@ protected: LayoutNodeWithStyle(Document&, const Node*, NonnullRefPtr); private: - LayoutStyle m_style; NonnullRefPtr m_specified_style; @@ -321,7 +276,7 @@ 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 &downcast(*sibling); } return nullptr; } @@ -331,7 +286,7 @@ inline T* LayoutNode::next_sibling_of_type() { for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) { if (is(*sibling)) - return &to(*sibling); + return &downcast(*sibling); } return nullptr; } @@ -341,7 +296,7 @@ inline const T* LayoutNode::previous_sibling_of_type() const { for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) { if (is(*sibling)) - return &to(*sibling); + return &downcast(*sibling); } return nullptr; } @@ -351,7 +306,7 @@ inline T* LayoutNode::previous_sibling_of_type() { for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) { if (is(*sibling)) - return &to(*sibling); + return &downcast(*sibling); } return nullptr; } @@ -361,7 +316,7 @@ 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 &downcast(*child); } return nullptr; } @@ -371,7 +326,7 @@ inline T* LayoutNode::first_child_of_type() { for (auto* child = first_child(); child; child = child->next_sibling()) { if (is(*child)) - return &to(*child); + return &downcast(*child); } return nullptr; } @@ -381,7 +336,7 @@ inline const T* LayoutNode::first_ancestor_of_type() const { for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { if (is(*ancestor)) - return &to(*ancestor); + return &downcast(*ancestor); } return nullptr; } @@ -391,15 +346,13 @@ inline T* LayoutNode::first_ancestor_of_type() { for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { if (is(*ancestor)) - return &to(*ancestor); + return &downcast(*ancestor); } return nullptr; } -template<> -inline bool is(const LayoutNode& node) -{ - return node.has_style(); } -} +AK_BEGIN_TYPE_TRAITS(Web::LayoutNodeWithStyle) +static bool is_type(const Web::LayoutNode& node) { return node.has_style(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutReplaced.h b/Libraries/LibWeb/Layout/LayoutReplaced.h index 3f4319daade..6b315ffdf4b 100644 --- a/Libraries/LibWeb/Layout/LayoutReplaced.h +++ b/Libraries/LibWeb/Layout/LayoutReplaced.h @@ -36,8 +36,8 @@ public: LayoutReplaced(Document&, const Element&, NonnullRefPtr); virtual ~LayoutReplaced() override; - const Element& node() const { return to(*LayoutNode::node()); } - Element& node() { return to(*LayoutNode::node()); } + const Element& node() const { return downcast(*LayoutNode::node()); } + Element& node() { return downcast(*LayoutNode::node()); } virtual bool is_replaced() const final { return true; } @@ -75,10 +75,8 @@ private: float m_intrinsic_ratio { 0 }; }; -template<> -inline bool is(const LayoutNode& node) -{ - return node.is_replaced(); } -} +AK_BEGIN_TYPE_TRAITS(Web::LayoutReplaced) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_replaced(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutTable.h b/Libraries/LibWeb/Layout/LayoutTable.h index 58af376c4c9..d8bc7492c3a 100644 --- a/Libraries/LibWeb/Layout/LayoutTable.h +++ b/Libraries/LibWeb/Layout/LayoutTable.h @@ -44,10 +44,8 @@ private: virtual const char* class_name() const override { return "LayoutTable"; } }; -template<> -inline bool is(const LayoutNode& node) -{ - return node.is_table(); } -} +AK_BEGIN_TYPE_TRAITS(Web::LayoutTable) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_table(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutTableCell.cpp b/Libraries/LibWeb/Layout/LayoutTableCell.cpp index 9621271843a..ab9fa8990cf 100644 --- a/Libraries/LibWeb/Layout/LayoutTableCell.cpp +++ b/Libraries/LibWeb/Layout/LayoutTableCell.cpp @@ -42,7 +42,7 @@ LayoutTableCell::~LayoutTableCell() size_t LayoutTableCell::colspan() const { ASSERT(node()); - return to(*node()).attribute(HTML::AttributeNames::colspan).to_uint().value_or(1); + return downcast(*node()).attribute(HTML::AttributeNames::colspan).to_uint().value_or(1); } float LayoutTableCell::width_of_logical_containing_block() const diff --git a/Libraries/LibWeb/Layout/LayoutTableCell.h b/Libraries/LibWeb/Layout/LayoutTableCell.h index 3edf83352a8..1103a3f9678 100644 --- a/Libraries/LibWeb/Layout/LayoutTableCell.h +++ b/Libraries/LibWeb/Layout/LayoutTableCell.h @@ -46,10 +46,8 @@ private: virtual float width_of_logical_containing_block() const override; }; -template<> -inline bool is(const LayoutNode& node) -{ - return node.is_table_cell(); } -} +AK_BEGIN_TYPE_TRAITS(Web::LayoutTableCell) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_table_cell(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutTableRow.h b/Libraries/LibWeb/Layout/LayoutTableRow.h index 819d1d33c78..8915dfb07e1 100644 --- a/Libraries/LibWeb/Layout/LayoutTableRow.h +++ b/Libraries/LibWeb/Layout/LayoutTableRow.h @@ -46,10 +46,8 @@ private: virtual const char* class_name() const override { return "LayoutTableRow"; } }; -template<> -inline bool is(const LayoutNode& node) -{ - return node.is_table_row(); } -} +AK_BEGIN_TYPE_TRAITS(Web::LayoutTableRow) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_table_row(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutTableRowGroup.h b/Libraries/LibWeb/Layout/LayoutTableRowGroup.h index 00d0689a878..8c79c894d53 100644 --- a/Libraries/LibWeb/Layout/LayoutTableRowGroup.h +++ b/Libraries/LibWeb/Layout/LayoutTableRowGroup.h @@ -44,10 +44,8 @@ private: virtual const char* class_name() const override { return "LayoutTableRowGroup"; } }; -template<> -inline bool is(const LayoutNode& node) -{ - return node.is_table_row_group(); } -} +AK_BEGIN_TYPE_TRAITS(Web::LayoutTableRowGroup) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_table_row_group(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutText.h b/Libraries/LibWeb/Layout/LayoutText.h index b764c7fbec2..3df9fd90355 100644 --- a/Libraries/LibWeb/Layout/LayoutText.h +++ b/Libraries/LibWeb/Layout/LayoutText.h @@ -61,10 +61,8 @@ private: String m_text_for_rendering; }; -template<> -inline bool is(const LayoutNode& node) -{ - return node.is_text(); } -} +AK_BEGIN_TYPE_TRAITS(Web::LayoutText) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_text(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LayoutTreeBuilder.cpp b/Libraries/LibWeb/Layout/LayoutTreeBuilder.cpp index 313d98e39b7..8d20c1f5ccf 100644 --- a/Libraries/LibWeb/Layout/LayoutTreeBuilder.cpp +++ b/Libraries/LibWeb/Layout/LayoutTreeBuilder.cpp @@ -50,7 +50,7 @@ static RefPtr create_layout_tree(Node& node, const StyleProperties* bool have_inline_children = false; bool have_noninline_children = false; - to(node).for_each_child([&](Node& child) { + downcast(node).for_each_child([&](Node& child) { auto layout_child = create_layout_tree(child, &layout_node->specified_style()); if (!layout_child) return; @@ -63,7 +63,7 @@ static RefPtr create_layout_tree(Node& node, const StyleProperties* for (auto& layout_child : layout_children) { if (have_noninline_children && have_inline_children && layout_child.is_inline()) { - if (is(layout_child) && to(layout_child).text_for_style(*parent_style) == " ") + if (is(layout_child) && downcast(layout_child).text_for_style(*parent_style) == " ") continue; layout_node->inline_wrapper().append_child(layout_child); } else { diff --git a/Libraries/LibWeb/Layout/LayoutWidget.h b/Libraries/LibWeb/Layout/LayoutWidget.h index b9646286227..1928c336170 100644 --- a/Libraries/LibWeb/Layout/LayoutWidget.h +++ b/Libraries/LibWeb/Layout/LayoutWidget.h @@ -50,10 +50,8 @@ private: NonnullRefPtr m_widget; }; -template<> -inline bool is(const LayoutNode& node) -{ - return node.is_widget(); } -} +AK_BEGIN_TYPE_TRAITS(Web::LayoutWidget) +static bool is_type(const Web::LayoutNode& layout_node) { return layout_node.is_widget(); } +AK_END_TYPE_TRAITS() diff --git a/Libraries/LibWeb/Layout/LineBox.cpp b/Libraries/LibWeb/Layout/LineBox.cpp index 9e49c0b6bf0..5ecaa93d016 100644 --- a/Libraries/LibWeb/Layout/LineBox.cpp +++ b/Libraries/LibWeb/Layout/LineBox.cpp @@ -47,7 +47,7 @@ void LineBox::add_fragment(const LayoutNode& layout_node, int start, int length, m_width += width; if (is(layout_node)) - const_cast(to(layout_node)).set_containing_line_box_fragment(m_fragments.last()); + const_cast(downcast(layout_node)).set_containing_line_box_fragment(m_fragments.last()); } void LineBox::trim_trailing_whitespace() diff --git a/Libraries/LibWeb/Layout/LineBoxFragment.cpp b/Libraries/LibWeb/Layout/LineBoxFragment.cpp index 7efbd698674..719ee8a5cde 100644 --- a/Libraries/LibWeb/Layout/LineBoxFragment.cpp +++ b/Libraries/LibWeb/Layout/LineBoxFragment.cpp @@ -42,7 +42,7 @@ void LineBoxFragment::paint(PaintContext& context) } if (is(layout_node())) { - to(layout_node()).paint_fragment(context, *this); + downcast(layout_node()).paint_fragment(context, *this); } } @@ -63,7 +63,7 @@ StringView LineBoxFragment::text() const { if (!is(layout_node())) return {}; - return to(layout_node()).text_for_rendering().substring_view(m_start, m_length); + return downcast(layout_node()).text_for_rendering().substring_view(m_start, m_length); } const Gfx::FloatRect LineBoxFragment::absolute_rect() const @@ -78,7 +78,7 @@ int LineBoxFragment::text_index_at(float x) const { if (!layout_node().is_text()) return 0; - auto& layout_text = to(layout_node()); + auto& layout_text = downcast(layout_node()); auto& font = layout_text.specified_style().font(); Utf8View view(text()); diff --git a/Libraries/LibWeb/LayoutTreeModel.cpp b/Libraries/LibWeb/LayoutTreeModel.cpp index 6a3444d2254..23bce12fc9a 100644 --- a/Libraries/LibWeb/LayoutTreeModel.cpp +++ b/Libraries/LibWeb/LayoutTreeModel.cpp @@ -127,7 +127,7 @@ GUI::Variant LayoutTreeModel::data(const GUI::ModelIndex& index, Role role) cons } if (role == Role::Display) { if (node.is_text()) - return String::format("LayoutText: %s", with_whitespace_collapsed(to(node).text_for_rendering()).characters()); + return String::format("LayoutText: %s", with_whitespace_collapsed(downcast(node).text_for_rendering()).characters()); StringBuilder builder; builder.append(node.class_name()); builder.append(' '); @@ -136,7 +136,7 @@ GUI::Variant LayoutTreeModel::data(const GUI::ModelIndex& index, Role role) cons } else if (!node.node()->is_element()) { builder.append(node.node()->node_name()); } else { - auto& element = to(*node.node()); + auto& element = downcast(*node.node()); builder.append('<'); builder.append(element.local_name()); element.for_each_attribute([&](auto& name, auto& value) { diff --git a/Libraries/LibWeb/PageView.cpp b/Libraries/LibWeb/PageView.cpp index fbf49d87709..26e2ce49fca 100644 --- a/Libraries/LibWeb/PageView.cpp +++ b/Libraries/LibWeb/PageView.cpp @@ -107,7 +107,7 @@ void PageView::select_all() int last_layout_node_index_in_node = 0; if (is(*last_layout_node)) - last_layout_node_index_in_node = to(*last_layout_node).text_for_rendering().length() - 1; + last_layout_node_index_in_node = downcast(*last_layout_node).text_for_rendering().length() - 1; layout_root->selection().set({ first_layout_node, 0 }, { last_layout_node, last_layout_node_index_in_node }); update(); @@ -127,13 +127,13 @@ String PageView::selected_text() const if (selection.start().layout_node == selection.end().layout_node) { if (!is(*selection.start().layout_node)) return ""; - return to(*selection.start().layout_node).text_for_rendering().substring(selection.start().index_in_node, selection.end().index_in_node - selection.start().index_in_node + 1); + return downcast(*selection.start().layout_node).text_for_rendering().substring(selection.start().index_in_node, selection.end().index_in_node - selection.start().index_in_node + 1); } // Start node auto layout_node = selection.start().layout_node; if (is(*layout_node)) { - auto& text = to(*layout_node).text_for_rendering(); + auto& text = downcast(*layout_node).text_for_rendering(); builder.append(text.substring(selection.start().index_in_node, text.length() - selection.start().index_in_node)); } @@ -141,7 +141,7 @@ String PageView::selected_text() const layout_node = layout_node->next_in_pre_order(); while (layout_node && layout_node != selection.end().layout_node) { if (is(*layout_node)) - builder.append(to(*layout_node).text_for_rendering()); + builder.append(downcast(*layout_node).text_for_rendering()); else if (is(*layout_node) || is(*layout_node)) builder.append('\n'); @@ -151,7 +151,7 @@ String PageView::selected_text() const // End node ASSERT(layout_node == selection.end().layout_node); if (is(*layout_node)) { - auto& text = to(*layout_node).text_for_rendering(); + auto& text = downcast(*layout_node).text_for_rendering(); builder.append(text.substring(0, selection.end().index_in_node + 1)); } diff --git a/Libraries/LibWeb/Painting/StackingContext.cpp b/Libraries/LibWeb/Painting/StackingContext.cpp index 8cae2c81edf..ed66da46a6b 100644 --- a/Libraries/LibWeb/Painting/StackingContext.cpp +++ b/Libraries/LibWeb/Painting/StackingContext.cpp @@ -54,7 +54,7 @@ void StackingContext::paint(PaintContext& context, LayoutNode::PaintPhase phase) } else { // NOTE: LayoutDocument::paint() merely calls StackingContext::paint() // so we call its base class instead. - to(m_box).LayoutBlock::paint(context, phase); + downcast(m_box).LayoutBlock::paint(context, phase); } for (auto* child : m_children) { child->paint(context, phase); @@ -69,7 +69,7 @@ HitTestResult StackingContext::hit_test(const Gfx::IntPoint& position) const } else { // NOTE: LayoutDocument::hit_test() merely calls StackingContext::hit_test() // so we call its base class instead. - result = to(m_box).LayoutBlock::hit_test(position); + result = downcast(m_box).LayoutBlock::hit_test(position); } for (auto* child : m_children) { diff --git a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp index c360b1f8e1b..3ee8eb3acba 100644 --- a/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp +++ b/Libraries/LibWeb/Parser/HTMLDocumentParser.cpp @@ -441,7 +441,7 @@ void HTMLDocumentParser::handle_before_head(HTMLToken& token) if (token.is_start_tag() && token.tag_name() == HTML::TagNames::head) { auto element = insert_html_element(token); - m_head_element = to(element); + m_head_element = downcast(*element); m_insertion_mode = InsertionMode::InHead; return; } @@ -456,7 +456,7 @@ void HTMLDocumentParser::handle_before_head(HTMLToken& token) } AnythingElse: - m_head_element = to(insert_html_element(HTMLToken::make_start_tag(HTML::TagNames::head))); + m_head_element = downcast(*insert_html_element(HTMLToken::make_start_tag(HTML::TagNames::head))); m_insertion_mode = InsertionMode::InHead; process_using_the_rules_for(InsertionMode::InHead, token); return; @@ -527,7 +527,7 @@ void HTMLDocumentParser::handle_in_head(HTMLToken& token) if (token.is_start_tag() && token.tag_name() == HTML::TagNames::script) { auto adjusted_insertion_location = find_appropriate_place_for_inserting_node(); auto element = create_element_for(token); - auto& script_element = to(*element); + auto& script_element = downcast(*element); script_element.set_parser_document({}, document()); script_element.set_non_blocking({}, false); @@ -636,7 +636,7 @@ Text* HTMLDocumentParser::find_character_insertion_node() if (adjusted_insertion_location.parent->is_document()) return nullptr; if (adjusted_insertion_location.parent->last_child() && adjusted_insertion_location.parent->last_child()->is_text()) - return to(adjusted_insertion_location.parent->last_child()); + return downcast(adjusted_insertion_location.parent->last_child()); auto new_text_node = adopt(*new Text(document(), "")); adjusted_insertion_location.parent->append_child(new_text_node); return new_text_node; @@ -1179,7 +1179,7 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token) close_a_p_element(); auto element = insert_html_element(token); if (!m_stack_of_open_elements.contains(HTML::TagNames::template_)) - m_form_element = to(*element); + m_form_element = downcast(*element); return; } @@ -1756,7 +1756,7 @@ void HTMLDocumentParser::handle_text(HTMLToken& token) if (token.is_end_of_file()) { PARSE_ERROR(); if (current_node().local_name() == HTML::TagNames::script) - to(current_node()).set_already_started({}, true); + downcast(current_node()).set_already_started({}, true); m_stack_of_open_elements.pop(); m_insertion_mode = m_original_insertion_mode; process_using_the_rules_for(m_insertion_mode, token); @@ -1766,7 +1766,7 @@ void HTMLDocumentParser::handle_text(HTMLToken& token) // Make sure the