mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 15:42:44 +00:00 
			
		
		
		
	LibWeb: Switch to using AK::is and AK::downcast
This commit is contained in:
		
							parent
							
								
									fe6474e692
								
							
						
					
					
						commit
						71556e39a4
					
				
					 73 changed files with 249 additions and 433 deletions
				
			
		|  | @ -41,17 +41,17 @@ namespace Bindings { | ||||||
| NodeWrapper* wrap(JS::GlobalObject& global_object, Node& node) | NodeWrapper* wrap(JS::GlobalObject& global_object, Node& node) | ||||||
| { | { | ||||||
|     if (is<Document>(node)) |     if (is<Document>(node)) | ||||||
|         return static_cast<NodeWrapper*>(wrap_impl(global_object, to<Document>(node))); |         return static_cast<NodeWrapper*>(wrap_impl(global_object, downcast<Document>(node))); | ||||||
|     if (is<DocumentType>(node)) |     if (is<DocumentType>(node)) | ||||||
|         return static_cast<NodeWrapper*>(wrap_impl(global_object, to<DocumentType>(node))); |         return static_cast<NodeWrapper*>(wrap_impl(global_object, downcast<DocumentType>(node))); | ||||||
|     if (is<HTMLCanvasElement>(node)) |     if (is<HTMLCanvasElement>(node)) | ||||||
|         return static_cast<NodeWrapper*>(wrap_impl(global_object, to<HTMLCanvasElement>(node))); |         return static_cast<NodeWrapper*>(wrap_impl(global_object, downcast<HTMLCanvasElement>(node))); | ||||||
|     if (is<HTMLImageElement>(node)) |     if (is<HTMLImageElement>(node)) | ||||||
|         return static_cast<NodeWrapper*>(wrap_impl(global_object, to<HTMLImageElement>(node))); |         return static_cast<NodeWrapper*>(wrap_impl(global_object, downcast<HTMLImageElement>(node))); | ||||||
|     if (is<HTMLElement>(node)) |     if (is<HTMLElement>(node)) | ||||||
|         return static_cast<NodeWrapper*>(wrap_impl(global_object, to<HTMLElement>(node))); |         return static_cast<NodeWrapper*>(wrap_impl(global_object, downcast<HTMLElement>(node))); | ||||||
|     if (is<Element>(node)) |     if (is<Element>(node)) | ||||||
|         return static_cast<NodeWrapper*>(wrap_impl(global_object, to<Element>(node))); |         return static_cast<NodeWrapper*>(wrap_impl(global_object, downcast<Element>(node))); | ||||||
|     return static_cast<NodeWrapper*>(wrap_impl(global_object, node)); |     return static_cast<NodeWrapper*>(wrap_impl(global_object, node)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -131,7 +131,7 @@ bool matches(const Selector& selector, int component_list_index, const Element& | ||||||
|         for (auto* ancestor = element.parent(); ancestor; ancestor = ancestor->parent()) { |         for (auto* ancestor = element.parent(); ancestor; ancestor = ancestor->parent()) { | ||||||
|             if (!is<Element>(*ancestor)) |             if (!is<Element>(*ancestor)) | ||||||
|                 continue; |                 continue; | ||||||
|             if (matches(selector, component_list_index - 1, to<Element>(*ancestor))) |             if (matches(selector, component_list_index - 1, downcast<Element>(*ancestor))) | ||||||
|                 return true; |                 return true; | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|  | @ -139,7 +139,7 @@ bool matches(const Selector& selector, int component_list_index, const Element& | ||||||
|         ASSERT(component_list_index != 0); |         ASSERT(component_list_index != 0); | ||||||
|         if (!element.parent() || !is<Element>(*element.parent())) |         if (!element.parent() || !is<Element>(*element.parent())) | ||||||
|             return false; |             return false; | ||||||
|         return matches(selector, component_list_index - 1, to<Element>(*element.parent())); |         return matches(selector, component_list_index - 1, downcast<Element>(*element.parent())); | ||||||
|     case Selector::ComplexSelector::Relation::AdjacentSibling: |     case Selector::ComplexSelector::Relation::AdjacentSibling: | ||||||
|         ASSERT(component_list_index != 0); |         ASSERT(component_list_index != 0); | ||||||
|         if (auto* sibling = element.previous_element_sibling()) |         if (auto* sibling = element.previous_element_sibling()) | ||||||
|  |  | ||||||
|  | @ -47,10 +47,8 @@ private: | ||||||
|     String m_data; |     String m_data; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<CharacterData>(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() | ||||||
|  |  | ||||||
|  | @ -39,10 +39,8 @@ public: | ||||||
|     virtual FlyString node_name() const override { return "#comment"; } |     virtual FlyString node_name() const override { return "#comment"; } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<Comment>(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() | ||||||
|  |  | ||||||
|  | @ -188,10 +188,9 @@ private: | ||||||
|     QuirksMode m_quirks_mode { QuirksMode::No }; |     QuirksMode m_quirks_mode { QuirksMode::No }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<Document>(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() | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -44,10 +44,8 @@ public: | ||||||
|     virtual FlyString node_name() const override { return "#document-fragment"; } |     virtual FlyString node_name() const override { return "#document-fragment"; } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<DocumentFragment>(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() | ||||||
|  |  | ||||||
|  | @ -55,10 +55,8 @@ private: | ||||||
|     String m_system_id; |     String m_system_id; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<DocumentType>(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() | ||||||
|  |  | ||||||
|  | @ -271,17 +271,17 @@ String Element::inner_html() const | ||||||
|         for (auto* child = node.first_child(); child; child = child->next_sibling()) { |         for (auto* child = node.first_child(); child; child = child->next_sibling()) { | ||||||
|             if (child->is_element()) { |             if (child->is_element()) { | ||||||
|                 builder.append('<'); |                 builder.append('<'); | ||||||
|                 builder.append(to<Element>(*child).local_name()); |                 builder.append(downcast<Element>(*child).local_name()); | ||||||
|                 builder.append('>'); |                 builder.append('>'); | ||||||
| 
 | 
 | ||||||
|                 recurse(*child); |                 recurse(*child); | ||||||
| 
 | 
 | ||||||
|                 builder.append("</"); |                 builder.append("</"); | ||||||
|                 builder.append(to<Element>(*child).local_name()); |                 builder.append(downcast<Element>(*child).local_name()); | ||||||
|                 builder.append('>'); |                 builder.append('>'); | ||||||
|             } |             } | ||||||
|             if (child->is_text()) { |             if (child->is_text()) { | ||||||
|                 builder.append(to<Text>(*child).data()); |                 builder.append(downcast<Text>(*child).data()); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  | @ -99,10 +99,8 @@ private: | ||||||
|     Vector<FlyString> m_classes; |     Vector<FlyString> m_classes; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<Element>(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() | ||||||
|  |  | ||||||
|  | @ -65,8 +65,8 @@ Node::~Node() | ||||||
| const HTMLAnchorElement* Node::enclosing_link_element() const | const HTMLAnchorElement* Node::enclosing_link_element() const | ||||||
| { | { | ||||||
|     for (auto* node = this; node; node = node->parent()) { |     for (auto* node = this; node; node = node->parent()) { | ||||||
|         if (is<HTMLAnchorElement>(*node) && to<HTMLAnchorElement>(*node).has_attribute(HTML::AttributeNames::href)) |         if (is<HTMLAnchorElement>(*node) && downcast<HTMLAnchorElement>(*node).has_attribute(HTML::AttributeNames::href)) | ||||||
|             return to<HTMLAnchorElement>(node); |             return downcast<HTMLAnchorElement>(node); | ||||||
|     } |     } | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
|  | @ -160,9 +160,9 @@ String Node::child_text_content() const | ||||||
|         return String::empty(); |         return String::empty(); | ||||||
| 
 | 
 | ||||||
|     StringBuilder builder; |     StringBuilder builder; | ||||||
|     to<ParentNode>(*this).for_each_child([&](auto& child) { |     downcast<ParentNode>(*this).for_each_child([&](auto& child) { | ||||||
|         if (is<Text>(child)) |         if (is<Text>(child)) | ||||||
|             builder.append(to<Text>(child).text_content()); |             builder.append(downcast<Text>(child).text_content()); | ||||||
|     }); |     }); | ||||||
|     return builder.build(); |     return builder.build(); | ||||||
| } | } | ||||||
|  | @ -184,14 +184,14 @@ Element* Node::parent_element() | ||||||
| { | { | ||||||
|     if (!parent() || !is<Element>(parent())) |     if (!parent() || !is<Element>(parent())) | ||||||
|         return nullptr; |         return nullptr; | ||||||
|     return to<Element>(parent()); |     return downcast<Element>(parent()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const Element* Node::parent_element() const | const Element* Node::parent_element() const | ||||||
| { | { | ||||||
|     if (!parent() || !is<Element>(parent())) |     if (!parent() || !is<Element>(parent())) | ||||||
|         return nullptr; |         return nullptr; | ||||||
|     return to<Element>(parent()); |     return downcast<Element>(parent()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RefPtr<Node> Node::append_child(NonnullRefPtr<Node> node, bool notify) | RefPtr<Node> Node::append_child(NonnullRefPtr<Node> node, bool notify) | ||||||
|  |  | ||||||
|  | @ -29,6 +29,7 @@ | ||||||
| #include <AK/Badge.h> | #include <AK/Badge.h> | ||||||
| #include <AK/RefPtr.h> | #include <AK/RefPtr.h> | ||||||
| #include <AK/String.h> | #include <AK/String.h> | ||||||
|  | #include <AK/TypeCasts.h> | ||||||
| #include <AK/Vector.h> | #include <AK/Vector.h> | ||||||
| #include <LibWeb/Bindings/Wrappable.h> | #include <LibWeb/Bindings/Wrappable.h> | ||||||
| #include <LibWeb/DOM/EventTarget.h> | #include <LibWeb/DOM/EventTarget.h> | ||||||
|  | @ -151,64 +152,12 @@ protected: | ||||||
|     bool m_needs_style_update { true }; |     bool m_needs_style_update { true }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 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); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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> | template<typename T> | ||||||
| inline const T* Node::first_child_of_type() const | inline const T* Node::first_child_of_type() const | ||||||
| { | { | ||||||
|     for (auto* child = first_child(); child; child = child->next_sibling()) { |     for (auto* child = first_child(); child; child = child->next_sibling()) { | ||||||
|         if (is<T>(*child)) |         if (is<T>(*child)) | ||||||
|             return to<T>(child); |             return downcast<T>(child); | ||||||
|     } |     } | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
|  | @ -218,7 +167,7 @@ inline const T* Node::first_ancestor_of_type() const | ||||||
| { | { | ||||||
|     for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { |     for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { | ||||||
|         if (is<T>(*ancestor)) |         if (is<T>(*ancestor)) | ||||||
|             return to<T>(ancestor); |             return downcast<T>(ancestor); | ||||||
|     } |     } | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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() | ||||||
|  |  | ||||||
|  | @ -43,10 +43,8 @@ private: | ||||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) override; |     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<Text>(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() | ||||||
|  |  | ||||||
|  | @ -128,10 +128,10 @@ GUI::Variant DOMTreeModel::data(const GUI::ModelIndex& index, Role role) const | ||||||
|     } |     } | ||||||
|     if (role == Role::Display) { |     if (role == Role::Display) { | ||||||
|         if (node.is_text()) |         if (node.is_text()) | ||||||
|             return String::format("%s", with_whitespace_collapsed(to<Text>(node).data()).characters()); |             return String::format("%s", with_whitespace_collapsed(downcast<Text>(node).data()).characters()); | ||||||
|         if (!node.is_element()) |         if (!node.is_element()) | ||||||
|             return node.node_name(); |             return node.node_name(); | ||||||
|         auto& element = to<Element>(node); |         auto& element = downcast<Element>(node); | ||||||
|         StringBuilder builder; |         StringBuilder builder; | ||||||
|         builder.append('<'); |         builder.append('<'); | ||||||
|         builder.append(element.local_name()); |         builder.append(element.local_name()); | ||||||
|  |  | ||||||
|  | @ -51,8 +51,8 @@ void dump_tree(const Node& node) | ||||||
|     if (is<Document>(node)) { |     if (is<Document>(node)) { | ||||||
|         dbgprintf("*Document*\n"); |         dbgprintf("*Document*\n"); | ||||||
|     } else if (is<Element>(node)) { |     } else if (is<Element>(node)) { | ||||||
|         dbgprintf("<%s", to<Element>(node).local_name().characters()); |         dbgprintf("<%s", downcast<Element>(node).local_name().characters()); | ||||||
|         to<Element>(node).for_each_attribute([](auto& name, auto& value) { |         downcast<Element>(node).for_each_attribute([](auto& name, auto& value) { | ||||||
|             dbgprintf(" %s=%s", name.characters(), value.characters()); |             dbgprintf(" %s=%s", name.characters(), value.characters()); | ||||||
|         }); |         }); | ||||||
|         dbgprintf(">\n"); |         dbgprintf(">\n"); | ||||||
|  | @ -61,7 +61,7 @@ void dump_tree(const Node& node) | ||||||
|     } else if (is<DocumentType>(node)) { |     } else if (is<DocumentType>(node)) { | ||||||
|         dbgprintf("<!DOCTYPE html>\n"); |         dbgprintf("<!DOCTYPE html>\n"); | ||||||
|     } else if (is<Comment>(node)) { |     } else if (is<Comment>(node)) { | ||||||
|         dbgprintf("<!--%s-->\n", to<Comment>(node).data().characters()); |         dbgprintf("<!--%s-->\n", downcast<Comment>(node).data().characters()); | ||||||
|     } else if (is<DocumentFragment>(node)) { |     } else if (is<DocumentFragment>(node)) { | ||||||
|         dbgprintf("#document-fragment\n"); |         dbgprintf("#document-fragment\n"); | ||||||
|     } |     } | ||||||
|  | @ -88,13 +88,13 @@ void dump_tree(const LayoutNode& layout_node) | ||||||
|     else if (is<Document>(layout_node.node())) |     else if (is<Document>(layout_node.node())) | ||||||
|         tag_name = "#document"; |         tag_name = "#document"; | ||||||
|     else if (is<Element>(layout_node.node())) |     else if (is<Element>(layout_node.node())) | ||||||
|         tag_name = to<Element>(*layout_node.node()).local_name(); |         tag_name = downcast<Element>(*layout_node.node()).local_name(); | ||||||
|     else |     else | ||||||
|         tag_name = "???"; |         tag_name = "???"; | ||||||
| 
 | 
 | ||||||
|     String identifier = ""; |     String identifier = ""; | ||||||
|     if (layout_node.node() && is<Element>(*layout_node.node())) { |     if (layout_node.node() && is<Element>(*layout_node.node())) { | ||||||
|         auto& element = to<Element>(*layout_node.node()); |         auto& element = downcast<Element>(*layout_node.node()); | ||||||
|         StringBuilder builder; |         StringBuilder builder; | ||||||
|         auto id = element.attribute(HTML::AttributeNames::id); |         auto id = element.attribute(HTML::AttributeNames::id); | ||||||
|         if (!id.is_empty()) { |         if (!id.is_empty()) { | ||||||
|  | @ -111,7 +111,7 @@ void dump_tree(const LayoutNode& layout_node) | ||||||
|     if (!layout_node.is_box()) { |     if (!layout_node.is_box()) { | ||||||
|         dbgprintf("%s {\033[33m%s\033[0m%s}\n", layout_node.class_name(), tag_name.characters(), identifier.characters()); |         dbgprintf("%s {\033[33m%s\033[0m%s}\n", layout_node.class_name(), tag_name.characters(), identifier.characters()); | ||||||
|     } else { |     } else { | ||||||
|         auto& layout_box = to<LayoutBox>(layout_node); |         auto& layout_box = downcast<LayoutBox>(layout_node); | ||||||
|         dbgprintf("%s {\033[34m%s\033[0m%s} at (%g,%g) size %gx%g", |         dbgprintf("%s {\033[34m%s\033[0m%s} at (%g,%g) size %gx%g", | ||||||
|             layout_box.class_name(), |             layout_box.class_name(), | ||||||
|             tag_name.characters(), |             tag_name.characters(), | ||||||
|  |  | ||||||
|  | @ -80,7 +80,7 @@ bool EventHandler::handle_mouseup(const Gfx::IntPoint& position, unsigned button | ||||||
|     if (result.layout_node && result.layout_node->node()) { |     if (result.layout_node && result.layout_node->node()) { | ||||||
|         RefPtr<Node> node = result.layout_node->node(); |         RefPtr<Node> node = result.layout_node->node(); | ||||||
|         if (is<HTMLIFrameElement>(*node)) { |         if (is<HTMLIFrameElement>(*node)) { | ||||||
|             if (auto* subframe = to<HTMLIFrameElement>(*node).hosted_frame()) |             if (auto* subframe = downcast<HTMLIFrameElement>(*node).hosted_frame()) | ||||||
|                 return subframe->event_handler().handle_mouseup(position.translated(compute_mouse_event_offset({}, *result.layout_node)), button, modifiers); |                 return subframe->event_handler().handle_mouseup(position.translated(compute_mouse_event_offset({}, *result.layout_node)), button, modifiers); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  | @ -113,7 +113,7 @@ bool EventHandler::handle_mousedown(const Gfx::IntPoint& position, unsigned butt | ||||||
|         return false; |         return false; | ||||||
| 
 | 
 | ||||||
|     if (is<HTMLIFrameElement>(*node)) { |     if (is<HTMLIFrameElement>(*node)) { | ||||||
|         if (auto* subframe = to<HTMLIFrameElement>(*node).hosted_frame()) |         if (auto* subframe = downcast<HTMLIFrameElement>(*node).hosted_frame()) | ||||||
|             return subframe->event_handler().handle_mousedown(position.translated(compute_mouse_event_offset({}, *result.layout_node)), button, modifiers); |             return subframe->event_handler().handle_mousedown(position.translated(compute_mouse_event_offset({}, *result.layout_node)), button, modifiers); | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  | @ -176,7 +176,7 @@ bool EventHandler::handle_mousemove(const Gfx::IntPoint& position, unsigned butt | ||||||
|         RefPtr<Node> node = result.layout_node->node(); |         RefPtr<Node> node = result.layout_node->node(); | ||||||
| 
 | 
 | ||||||
|         if (node && is<HTMLIFrameElement>(*node)) { |         if (node && is<HTMLIFrameElement>(*node)) { | ||||||
|             if (auto* subframe = to<HTMLIFrameElement>(*node).hosted_frame()) |             if (auto* subframe = downcast<HTMLIFrameElement>(*node).hosted_frame()) | ||||||
|                 return subframe->event_handler().handle_mousemove(position.translated(compute_mouse_event_offset({}, *result.layout_node)), buttons, modifiers); |                 return subframe->event_handler().handle_mousemove(position.translated(compute_mouse_event_offset({}, *result.layout_node)), buttons, modifiers); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -125,7 +125,7 @@ void Frame::scroll_to_anchor(const String& fragment) | ||||||
|         auto candidates = document()->get_elements_by_name(fragment); |         auto candidates = document()->get_elements_by_name(fragment); | ||||||
|         for (auto* candidate : candidates) { |         for (auto* candidate : candidates) { | ||||||
|             if (is<HTMLAnchorElement>(*candidate)) { |             if (is<HTMLAnchorElement>(*candidate)) { | ||||||
|                 element = to<HTMLAnchorElement>(candidate); |                 element = downcast<HTMLAnchorElement>(candidate); | ||||||
|                 break; |                 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() } }; |     Gfx::FloatRect float_rect { layout_node.box_type_agnostic_position(), { (float)viewport_rect().width(), (float)viewport_rect().height() } }; | ||||||
|     if (is<LayoutBox>(layout_node)) { |     if (is<LayoutBox>(layout_node)) { | ||||||
|         auto& layout_box = to<LayoutBox>(layout_node); |         auto& layout_box = downcast<LayoutBox>(layout_node); | ||||||
|         auto padding_box = layout_box.box_model().padding_box(layout_box); |         auto padding_box = layout_box.box_model().padding_box(layout_box); | ||||||
|         float_rect.move_by(-padding_box.left, -padding_box.top); |         float_rect.move_by(-padding_box.left, -padding_box.top); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -39,10 +39,8 @@ public: | ||||||
|     String target() const { return attribute(HTML::AttributeNames::target); } |     String target() const { return attribute(HTML::AttributeNames::target); } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLAnchorElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::Element>(node).local_name() == Web::HTML::TagNames::a; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -38,10 +38,8 @@ public: | ||||||
|     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) override; |     virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLBRElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::Element>(node).local_name() == Web::HTML::TagNames::br; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -42,10 +42,8 @@ private: | ||||||
|     NonnullRefPtr<Core::Timer> m_timer; |     NonnullRefPtr<Core::Timer> m_timer; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLBlinkElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::Element>(node).local_name() == Web::HTML::TagNames::blink; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -42,10 +42,8 @@ private: | ||||||
|     RefPtr<ImageStyleValue> m_background_style_value; |     RefPtr<ImageStyleValue> m_background_style_value; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLBodyElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::Element>(node).local_name() == Web::HTML::TagNames::body; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -57,10 +57,8 @@ private: | ||||||
|     RefPtr<CanvasRenderingContext2D> m_context; |     RefPtr<CanvasRenderingContext2D> m_context; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLCanvasElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::Element>(node).local_name() == Web::HTML::TagNames::canvas; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -43,10 +43,8 @@ private: | ||||||
|     virtual bool is_html_element() const final { return true; } |     virtual bool is_html_element() const final { return true; } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLElement>(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() | ||||||
|  |  | ||||||
|  | @ -38,10 +38,8 @@ public: | ||||||
|     virtual void apply_presentational_hints(StyleProperties&) const override; |     virtual void apply_presentational_hints(StyleProperties&) const override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLFontElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::Element>(node).local_name() == Web::HTML::TagNames::font; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -63,7 +63,7 @@ void HTMLFormElement::submit(RefPtr<HTMLInputElement> submitter) | ||||||
|     Vector<URLQueryParam> parameters; |     Vector<URLQueryParam> parameters; | ||||||
| 
 | 
 | ||||||
|     for_each_in_subtree_of_type<HTMLInputElement>([&](auto& node) { |     for_each_in_subtree_of_type<HTMLInputElement>([&](auto& node) { | ||||||
|         auto& input = to<HTMLInputElement>(node); |         auto& input = downcast<HTMLInputElement>(node); | ||||||
|         if (!input.name().is_null() && (input.type() != "submit" || &input == submitter)) |         if (!input.name().is_null() && (input.type() != "submit" || &input == submitter)) | ||||||
|             parameters.append({ input.name(), input.value() }); |             parameters.append({ input.name(), input.value() }); | ||||||
|         return IterationDecision::Continue; |         return IterationDecision::Continue; | ||||||
|  |  | ||||||
|  | @ -42,10 +42,8 @@ public: | ||||||
|     void submit(RefPtr<HTMLInputElement> submitter); |     void submit(RefPtr<HTMLInputElement> submitter); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLFormElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::HTMLElement>(node).local_name() == Web::HTML::TagNames::form; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -36,10 +36,8 @@ public: | ||||||
|     virtual ~HTMLHRElement() override; |     virtual ~HTMLHRElement() override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLHRElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::HTMLElement>(node).local_name() == Web::HTML::TagNames::hr; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -36,10 +36,8 @@ public: | ||||||
|     virtual ~HTMLHeadElement() override; |     virtual ~HTMLHeadElement() override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLHeadElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::Element>(node).local_name() == Web::HTML::TagNames::head; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -36,10 +36,8 @@ public: | ||||||
|     virtual ~HTMLHtmlElement() override; |     virtual ~HTMLHtmlElement() override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLHtmlElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::HTMLElement>(node).local_name() == Web::HTML::TagNames::html; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -51,10 +51,8 @@ private: | ||||||
|     RefPtr<Frame> m_hosted_frame; |     RefPtr<Frame> m_hosted_frame; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLIFrameElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::HTMLElement>(node).local_name() == Web::HTML::TagNames::iframe; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -60,10 +60,8 @@ private: | ||||||
|     ImageLoader m_image_loader; |     ImageLoader m_image_loader; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLImageElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::Element>(node).local_name() == Web::HTML::TagNames::img; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -83,7 +83,7 @@ RefPtr<LayoutNode> HTMLInputElement::create_layout_node(const StyleProperties* p | ||||||
|         auto& text_box = page_view.add<GUI::TextBox>(); |         auto& text_box = page_view.add<GUI::TextBox>(); | ||||||
|         text_box.set_text(value()); |         text_box.set_text(value()); | ||||||
|         text_box.on_change = [this] { |         text_box.on_change = [this] { | ||||||
|             auto& widget = to<LayoutWidget>(layout_node())->widget(); |             auto& widget = downcast<LayoutWidget>(layout_node())->widget(); | ||||||
|             const_cast<HTMLInputElement*>(this)->set_attribute(HTML::AttributeNames::value, static_cast<const GUI::TextBox&>(widget).text()); |             const_cast<HTMLInputElement*>(this)->set_attribute(HTML::AttributeNames::value, static_cast<const GUI::TextBox&>(widget).text()); | ||||||
|         }; |         }; | ||||||
|         int text_width = Gfx::Font::default_font().width(value()); |         int text_width = Gfx::Font::default_font().width(value()); | ||||||
|  |  | ||||||
|  | @ -42,10 +42,8 @@ public: | ||||||
|     String name() const { return attribute(HTML::AttributeNames::name); } |     String name() const { return attribute(HTML::AttributeNames::name); } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLInputElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::HTMLElement>(node).local_name() == Web::HTML::TagNames::input; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -64,10 +64,8 @@ private: | ||||||
|     RefPtr<StyleSheet> m_style_sheet; |     RefPtr<StyleSheet> m_style_sheet; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLLinkElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::HTMLElement>(node).local_name() == Web::HTML::TagNames::link; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -52,10 +52,8 @@ private: | ||||||
|     bool m_should_show_fallback_content { false }; |     bool m_should_show_fallback_content { false }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLObjectElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::Element>(node).local_name() == Web::HTML::TagNames::object; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -65,10 +65,8 @@ private: | ||||||
|     String m_script_source; |     String m_script_source; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLScriptElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::HTMLElement>(node).local_name() == Web::HTML::TagNames::script; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -46,7 +46,7 @@ void HTMLStyleElement::children_changed() | ||||||
|     StringBuilder builder; |     StringBuilder builder; | ||||||
|     for_each_child([&](auto& child) { |     for_each_child([&](auto& child) { | ||||||
|         if (is<Text>(child)) |         if (is<Text>(child)) | ||||||
|             builder.append(to<Text>(child).text_content()); |             builder.append(downcast<Text>(child).text_content()); | ||||||
|     }); |     }); | ||||||
|     m_stylesheet = parse_css(CSS::ParsingContext(document()), builder.to_string()); |     m_stylesheet = parse_css(CSS::ParsingContext(document()), builder.to_string()); | ||||||
|     if (m_stylesheet) |     if (m_stylesheet) | ||||||
|  |  | ||||||
|  | @ -44,11 +44,8 @@ private: | ||||||
|     RefPtr<StyleSheet> m_stylesheet; |     RefPtr<StyleSheet> m_stylesheet; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLStyleElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::HTMLElement>(node).local_name() == Web::HTML::TagNames::style; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -39,10 +39,8 @@ private: | ||||||
|     virtual void apply_presentational_hints(StyleProperties&) const override; |     virtual void apply_presentational_hints(StyleProperties&) const override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLTableCellElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::HTMLElement>(node).local_name() == Web::HTML::TagNames::td; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -39,10 +39,8 @@ private: | ||||||
|     virtual void apply_presentational_hints(StyleProperties&) const override; |     virtual void apply_presentational_hints(StyleProperties&) const override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLTableElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::HTMLElement>(node).local_name() == Web::HTML::TagNames::table; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -36,10 +36,8 @@ public: | ||||||
|     virtual ~HTMLTableRowElement() override; |     virtual ~HTMLTableRowElement() override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLTableRowElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::HTMLElement>(node).local_name() == Web::HTML::TagNames::tr; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -36,10 +36,8 @@ public: | ||||||
|     virtual ~HTMLTitleElement() override; |     virtual ~HTMLTitleElement() override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<HTMLTitleElement>(const Node& node) |  | ||||||
| { |  | ||||||
|     return is<Element>(node) && to<Element>(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<Web::HTMLElement>(node).local_name() == Web::HTML::TagNames::title; } | ||||||
|  | AK_END_TYPE_TRAITS() | ||||||
|  |  | ||||||
|  | @ -155,13 +155,13 @@ void LayoutBlock::layout_contained_boxes(LayoutMode layout_mode) | ||||||
|             return IterationDecision::Continue; |             return IterationDecision::Continue; | ||||||
|         box.layout(layout_mode); |         box.layout(layout_mode); | ||||||
|         if (box.is_replaced()) |         if (box.is_replaced()) | ||||||
|             place_block_level_replaced_element_in_normal_flow(to<LayoutReplaced>(box)); |             place_block_level_replaced_element_in_normal_flow(downcast<LayoutReplaced>(box)); | ||||||
|         else if (box.is_block()) |         else if (box.is_block()) | ||||||
|             place_block_level_non_replaced_element_in_normal_flow(to<LayoutBlock>(box)); |             place_block_level_non_replaced_element_in_normal_flow(downcast<LayoutBlock>(box)); | ||||||
|         else |         else | ||||||
|             dbg() << "FIXME: LayoutBlock::layout_contained_boxes doesn't know how to place a " << box.class_name(); |             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_height = max(content_height, box.effective_offset().y() + box.height() + box.box_model().margin_box(*this).bottom); | ||||||
|         content_width = max(content_width, to<LayoutBox>(box).width()); |         content_width = max(content_width, downcast<LayoutBox>(box).width()); | ||||||
|         return IterationDecision::Continue; |         return IterationDecision::Continue; | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|  | @ -257,7 +257,7 @@ void LayoutBlock::layout_inline_children(LayoutMode layout_mode) | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (fragment.layout_node().is_inline_block()) { |             if (fragment.layout_node().is_inline_block()) { | ||||||
|                 auto& inline_block = const_cast<LayoutBlock&>(to<LayoutBlock>(fragment.layout_node())); |                 auto& inline_block = const_cast<LayoutBlock&>(downcast<LayoutBlock>(fragment.layout_node())); | ||||||
|                 inline_block.set_size(fragment.size()); |                 inline_block.set_size(fragment.size()); | ||||||
|                 inline_block.layout(layout_mode); |                 inline_block.layout(layout_mode); | ||||||
|             } |             } | ||||||
|  | @ -587,7 +587,7 @@ LayoutBlock::ShrinkToFitResult LayoutBlock::calculate_shrink_to_fit_width() | ||||||
|         } else { |         } else { | ||||||
|             for_each_child([&](auto& child) { |             for_each_child([&](auto& child) { | ||||||
|                 if (child.is_box()) |                 if (child.is_box()) | ||||||
|                     max_width = max(max_width, to<LayoutBox>(child).width()); |                     max_width = max(max_width, downcast<LayoutBox>(child).width()); | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|         return max_width; |         return max_width; | ||||||
|  | @ -725,11 +725,11 @@ HitTestResult LayoutBlock::hit_test(const Gfx::IntPoint& position) const | ||||||
|     HitTestResult last_good_candidate; |     HitTestResult last_good_candidate; | ||||||
|     for (auto& line_box : m_line_boxes) { |     for (auto& line_box : m_line_boxes) { | ||||||
|         for (auto& fragment : line_box.fragments()) { |         for (auto& fragment : line_box.fragments()) { | ||||||
|             if (is<LayoutBox>(fragment.layout_node()) && to<LayoutBox>(fragment.layout_node()).stacking_context()) |             if (is<LayoutBox>(fragment.layout_node()) && downcast<LayoutBox>(fragment.layout_node()).stacking_context()) | ||||||
|                 continue; |                 continue; | ||||||
|             if (enclosing_int_rect(fragment.absolute_rect()).contains(position)) { |             if (enclosing_int_rect(fragment.absolute_rect()).contains(position)) { | ||||||
|                 if (fragment.layout_node().is_block()) |                 if (fragment.layout_node().is_block()) | ||||||
|                     return to<LayoutBlock>(fragment.layout_node()).hit_test(position); |                     return downcast<LayoutBlock>(fragment.layout_node()).hit_test(position); | ||||||
|                 return { fragment.layout_node(), fragment.text_index_at(position.x()) }; |                 return { fragment.layout_node(), fragment.text_index_at(position.x()) }; | ||||||
|             } |             } | ||||||
|             if (fragment.absolute_rect().top() <= position.y()) |             if (fragment.absolute_rect().top() <= position.y()) | ||||||
|  |  | ||||||
|  | @ -53,10 +53,10 @@ public: | ||||||
| 
 | 
 | ||||||
|     virtual HitTestResult hit_test(const Gfx::IntPoint&) const override; |     virtual HitTestResult hit_test(const Gfx::IntPoint&) const override; | ||||||
| 
 | 
 | ||||||
|     LayoutBlock* previous_sibling() { return to<LayoutBlock>(LayoutNode::previous_sibling()); } |     LayoutBlock* previous_sibling() { return downcast<LayoutBlock>(LayoutNode::previous_sibling()); } | ||||||
|     const LayoutBlock* previous_sibling() const { return to<LayoutBlock>(LayoutNode::previous_sibling()); } |     const LayoutBlock* previous_sibling() const { return downcast<LayoutBlock>(LayoutNode::previous_sibling()); } | ||||||
|     LayoutBlock* next_sibling() { return to<LayoutBlock>(LayoutNode::next_sibling()); } |     LayoutBlock* next_sibling() { return downcast<LayoutBlock>(LayoutNode::next_sibling()); } | ||||||
|     const LayoutBlock* next_sibling() const { return to<LayoutBlock>(LayoutNode::next_sibling()); } |     const LayoutBlock* next_sibling() const { return downcast<LayoutBlock>(LayoutNode::next_sibling()); } | ||||||
| 
 | 
 | ||||||
|     template<typename Callback> |     template<typename Callback> | ||||||
|     void for_each_fragment(Callback); |     void for_each_fragment(Callback); | ||||||
|  | @ -119,10 +119,8 @@ void LayoutBlock::for_each_fragment(Callback callback) const | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| ALWAYS_INLINE bool is<LayoutBlock>(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() | ||||||
|  |  | ||||||
|  | @ -231,7 +231,7 @@ HitTestResult LayoutBox::hit_test(const Gfx::IntPoint& position) const | ||||||
|     //        m_rect.contains() since inline text rects can't be trusted..
 |     //        m_rect.contains() since inline text rects can't be trusted..
 | ||||||
|     HitTestResult result { absolute_rect().contains(position.x(), position.y()) ? this : nullptr }; |     HitTestResult result { absolute_rect().contains(position.x(), position.y()) ? this : nullptr }; | ||||||
|     for_each_child([&](auto& child) { |     for_each_child([&](auto& child) { | ||||||
|         if (is<LayoutBox>(child) && to<LayoutBox>(child).stacking_context()) |         if (is<LayoutBox>(child) && downcast<LayoutBox>(child).stacking_context()) | ||||||
|             return; |             return; | ||||||
|         auto child_result = child.hit_test(position); |         auto child_result = child.hit_test(position); | ||||||
|         if (child_result.layout_node) |         if (child_result.layout_node) | ||||||
|  | @ -297,7 +297,7 @@ StackingContext* LayoutBox::enclosing_stacking_context() | ||||||
|     for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { |     for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { | ||||||
|         if (!ancestor->is_box()) |         if (!ancestor->is_box()) | ||||||
|             continue; |             continue; | ||||||
|         auto& ancestor_box = to<LayoutBox>(*ancestor); |         auto& ancestor_box = downcast<LayoutBox>(*ancestor); | ||||||
|         if (!ancestor_box.establishes_stacking_context()) |         if (!ancestor_box.establishes_stacking_context()) | ||||||
|             continue; |             continue; | ||||||
|         ASSERT(ancestor_box.stacking_context()); |         ASSERT(ancestor_box.stacking_context()); | ||||||
|  |  | ||||||
|  | @ -98,10 +98,8 @@ private: | ||||||
|     OwnPtr<StackingContext> m_stacking_context; |     OwnPtr<StackingContext> m_stacking_context; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| ALWAYS_INLINE bool is<LayoutBox>(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() | ||||||
|  |  | ||||||
|  | @ -36,11 +36,16 @@ public: | ||||||
|     LayoutBreak(Document&, const HTMLBRElement&); |     LayoutBreak(Document&, const HTMLBRElement&); | ||||||
|     virtual ~LayoutBreak() override; |     virtual ~LayoutBreak() override; | ||||||
| 
 | 
 | ||||||
|     const HTMLBRElement& node() const { return to<HTMLBRElement>(*LayoutNode::node()); } |     const HTMLBRElement& node() const { return downcast<HTMLBRElement>(*LayoutNode::node()); } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |     virtual bool is_break() const override { return true; } | ||||||
|     virtual const char* class_name() const override { return "LayoutBreak"; } |     virtual const char* class_name() const override { return "LayoutBreak"; } | ||||||
|     virtual void split_into_lines(LayoutBlock&, LayoutMode) override; |     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() | ||||||
|  |  | ||||||
|  | @ -48,10 +48,9 @@ private: | ||||||
|     virtual bool is_canvas() const override { return true; } |     virtual bool is_canvas() const override { return true; } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<LayoutCanvas>(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() | ||||||
|  |  | ||||||
|  | @ -76,7 +76,7 @@ void LayoutDocument::layout(LayoutMode layout_mode) | ||||||
|     float lowest_bottom = 0; |     float lowest_bottom = 0; | ||||||
|     for_each_child([&](auto& child) { |     for_each_child([&](auto& child) { | ||||||
|         ASSERT(is<LayoutBlock>(child)); |         ASSERT(is<LayoutBlock>(child)); | ||||||
|         auto& child_block = to<LayoutBlock>(child); |         auto& child_block = downcast<LayoutBlock>(child); | ||||||
|         lowest_bottom = max(lowest_bottom, child_block.absolute_rect().bottom()); |         lowest_bottom = max(lowest_bottom, child_block.absolute_rect().bottom()); | ||||||
|     }); |     }); | ||||||
|     set_height(lowest_bottom); |     set_height(lowest_bottom); | ||||||
|  |  | ||||||
|  | @ -58,11 +58,8 @@ private: | ||||||
|     LayoutRange m_selection; |     LayoutRange m_selection; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<LayoutDocument>(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() | ||||||
|  |  | ||||||
|  | @ -48,10 +48,8 @@ private: | ||||||
|     virtual void did_set_rect() override; |     virtual void did_set_rect() override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<LayoutFrame>(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() | ||||||
|  |  | ||||||
|  | @ -71,7 +71,7 @@ void LayoutImage::layout(LayoutMode layout_mode) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (renders_as_alt_text()) { |     if (renders_as_alt_text()) { | ||||||
|         auto& image_element = to<HTMLImageElement>(node()); |         auto& image_element = downcast<HTMLImageElement>(node()); | ||||||
|         auto& font = Gfx::Font::default_font(); |         auto& font = Gfx::Font::default_font(); | ||||||
|         auto alt = image_element.alt(); |         auto alt = image_element.alt(); | ||||||
|         if (alt.is_empty()) |         if (alt.is_empty()) | ||||||
|  | @ -101,7 +101,7 @@ void LayoutImage::paint(PaintContext& context, PaintPhase phase) | ||||||
| 
 | 
 | ||||||
|     if (phase == PaintPhase::Foreground) { |     if (phase == PaintPhase::Foreground) { | ||||||
|         if (renders_as_alt_text()) { |         if (renders_as_alt_text()) { | ||||||
|             auto& image_element = to<HTMLImageElement>(node()); |             auto& image_element = downcast<HTMLImageElement>(node()); | ||||||
|             context.painter().set_font(Gfx::Font::default_font()); |             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); |             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(); |             auto alt = image_element.alt(); | ||||||
|  |  | ||||||
|  | @ -57,10 +57,8 @@ private: | ||||||
|     const ImageLoader& m_image_loader; |     const ImageLoader& m_image_loader; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<LayoutImage>(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() | ||||||
|  |  | ||||||
|  | @ -67,7 +67,7 @@ const LayoutBlock* LayoutNode::containing_block() const | ||||||
|         auto* ancestor = parent(); |         auto* ancestor = parent(); | ||||||
|         while (ancestor && !is<LayoutBlock>(*ancestor)) |         while (ancestor && !is<LayoutBlock>(*ancestor)) | ||||||
|             ancestor = ancestor->parent(); |             ancestor = ancestor->parent(); | ||||||
|         return to<LayoutBlock>(ancestor); |         return downcast<LayoutBlock>(ancestor); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     if (is_text()) |     if (is_text()) | ||||||
|  | @ -81,7 +81,7 @@ const LayoutBlock* LayoutNode::containing_block() const | ||||||
|             ancestor = ancestor->parent(); |             ancestor = ancestor->parent(); | ||||||
|         while (ancestor && (!is<LayoutBlock>(ancestor) || ancestor->is_anonymous())) |         while (ancestor && (!is<LayoutBlock>(ancestor) || ancestor->is_anonymous())) | ||||||
|             ancestor = ancestor->containing_block(); |             ancestor = ancestor->containing_block(); | ||||||
|         return to<LayoutBlock>(ancestor); |         return downcast<LayoutBlock>(ancestor); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (position == CSS::Position::Fixed) |     if (position == CSS::Position::Fixed) | ||||||
|  | @ -96,7 +96,7 @@ void LayoutNode::paint(PaintContext& context, PaintPhase phase) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|     for_each_child([&](auto& child) { |     for_each_child([&](auto& child) { | ||||||
|         if (child.is_box() && to<LayoutBox>(child).stacking_context()) |         if (child.is_box() && downcast<LayoutBox>(child).stacking_context()) | ||||||
|             return; |             return; | ||||||
|         child.paint(context, phase); |         child.paint(context, phase); | ||||||
|     }); |     }); | ||||||
|  | @ -108,7 +108,7 @@ HitTestResult LayoutNode::hit_test(const Gfx::IntPoint& position) const | ||||||
|     for_each_child([&](auto& child) { |     for_each_child([&](auto& child) { | ||||||
|         // Skip over children that establish their own stacking context.
 |         // Skip over children that establish their own stacking context.
 | ||||||
|         // The outer loop who called us will take care of those.
 |         // The outer loop who called us will take care of those.
 | ||||||
|         if (is<LayoutBox>(child) && to<LayoutBox>(child).stacking_context()) |         if (is<LayoutBox>(child) && downcast<LayoutBox>(child).stacking_context()) | ||||||
|             return; |             return; | ||||||
|         auto child_result = child.hit_test(position); |         auto child_result = child.hit_test(position); | ||||||
|         if (child_result.layout_node) |         if (child_result.layout_node) | ||||||
|  | @ -170,7 +170,7 @@ float LayoutNode::font_size() const | ||||||
| Gfx::FloatPoint LayoutNode::box_type_agnostic_position() const | Gfx::FloatPoint LayoutNode::box_type_agnostic_position() const | ||||||
| { | { | ||||||
|     if (is_box()) |     if (is_box()) | ||||||
|         return to<LayoutBox>(*this).absolute_position(); |         return downcast<LayoutBox>(*this).absolute_position(); | ||||||
|     ASSERT(is_inline()); |     ASSERT(is_inline()); | ||||||
|     Gfx::FloatPoint position; |     Gfx::FloatPoint position; | ||||||
|     if (auto* block = containing_block()) { |     if (auto* block = containing_block()) { | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <AK/NonnullRefPtr.h> | #include <AK/NonnullRefPtr.h> | ||||||
|  | #include <AK/TypeCasts.h> | ||||||
| #include <AK/Vector.h> | #include <AK/Vector.h> | ||||||
| #include <LibGfx/FloatRect.h> | #include <LibGfx/FloatRect.h> | ||||||
| #include <LibGfx/Rect.h> | #include <LibGfx/Rect.h> | ||||||
|  | @ -40,52 +41,6 @@ | ||||||
| 
 | 
 | ||||||
| namespace Web { | namespace Web { | ||||||
| 
 | 
 | ||||||
| template<typename T> |  | ||||||
| inline bool is(const LayoutNode&) |  | ||||||
| { |  | ||||||
|     return false; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| template<typename T> |  | ||||||
| inline bool is(const LayoutNode* node) |  | ||||||
| { |  | ||||||
|     return !node || is<T>(*node); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| template<> |  | ||||||
| inline bool is<LayoutNode>(const LayoutNode&) |  | ||||||
| { |  | ||||||
|     return true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| template<typename T> |  | ||||||
| inline const T& to(const LayoutNode& node) |  | ||||||
| { |  | ||||||
|     ASSERT(is<T>(node)); |  | ||||||
|     return static_cast<const T&>(node); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| template<typename T> |  | ||||||
| inline T* to(LayoutNode* node) |  | ||||||
| { |  | ||||||
|     ASSERT(is<T>(node)); |  | ||||||
|     return static_cast<T*>(node); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| template<typename T> |  | ||||||
| inline const T* to(const LayoutNode* node) |  | ||||||
| { |  | ||||||
|     ASSERT(is<T>(node)); |  | ||||||
|     return static_cast<const T*>(node); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| template<typename T> |  | ||||||
| inline T& to(LayoutNode& node) |  | ||||||
| { |  | ||||||
|     ASSERT(is<T>(node)); |  | ||||||
|     return static_cast<T&>(node); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct HitTestResult { | struct HitTestResult { | ||||||
|     RefPtr<LayoutNode> layout_node; |     RefPtr<LayoutNode> layout_node; | ||||||
|     int index_in_node { 0 }; |     int index_in_node { 0 }; | ||||||
|  | @ -130,7 +85,7 @@ public: | ||||||
|         for (auto* node = first_child(); node; node = node->next_sibling()) { |         for (auto* node = first_child(); node; node = node->next_sibling()) { | ||||||
|             if (!is<T>(node)) |             if (!is<T>(node)) | ||||||
|                 continue; |                 continue; | ||||||
|             callback(to<T>(*node)); |             callback(downcast<T>(*node)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -140,7 +95,7 @@ public: | ||||||
|         for (auto* node = first_child(); node; node = node->next_sibling()) { |         for (auto* node = first_child(); node; node = node->next_sibling()) { | ||||||
|             if (!is<T>(node)) |             if (!is<T>(node)) | ||||||
|                 continue; |                 continue; | ||||||
|             callback(to<T>(*node)); |             callback(downcast<T>(*node)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -158,6 +113,7 @@ public: | ||||||
|     virtual bool is_table_row() const { return false; } |     virtual bool is_table_row() const { return false; } | ||||||
|     virtual bool is_table_cell() const { return false; } |     virtual bool is_table_cell() const { return false; } | ||||||
|     virtual bool is_table_row_group() 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 has_style() const { return m_has_style; } | ||||||
| 
 | 
 | ||||||
|     bool is_inline() const { return m_inline; } |     bool is_inline() const { return m_inline; } | ||||||
|  | @ -269,7 +225,6 @@ protected: | ||||||
|     LayoutNodeWithStyle(Document&, const Node*, NonnullRefPtr<StyleProperties>); |     LayoutNodeWithStyle(Document&, const Node*, NonnullRefPtr<StyleProperties>); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 
 |  | ||||||
|     LayoutStyle m_style; |     LayoutStyle m_style; | ||||||
| 
 | 
 | ||||||
|     NonnullRefPtr<StyleProperties> m_specified_style; |     NonnullRefPtr<StyleProperties> 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()) { |     for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) { | ||||||
|         if (is<T>(*sibling)) |         if (is<T>(*sibling)) | ||||||
|             return &to<T>(*sibling); |             return &downcast<T>(*sibling); | ||||||
|     } |     } | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
|  | @ -331,7 +286,7 @@ inline T* LayoutNode::next_sibling_of_type() | ||||||
| { | { | ||||||
|     for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) { |     for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) { | ||||||
|         if (is<T>(*sibling)) |         if (is<T>(*sibling)) | ||||||
|             return &to<T>(*sibling); |             return &downcast<T>(*sibling); | ||||||
|     } |     } | ||||||
|     return nullptr; |     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()) { |     for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) { | ||||||
|         if (is<T>(*sibling)) |         if (is<T>(*sibling)) | ||||||
|             return &to<T>(*sibling); |             return &downcast<T>(*sibling); | ||||||
|     } |     } | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
|  | @ -351,7 +306,7 @@ inline T* LayoutNode::previous_sibling_of_type() | ||||||
| { | { | ||||||
|     for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) { |     for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) { | ||||||
|         if (is<T>(*sibling)) |         if (is<T>(*sibling)) | ||||||
|             return &to<T>(*sibling); |             return &downcast<T>(*sibling); | ||||||
|     } |     } | ||||||
|     return nullptr; |     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()) { |     for (auto* child = first_child(); child; child = child->next_sibling()) { | ||||||
|         if (is<T>(*child)) |         if (is<T>(*child)) | ||||||
|             return &to<T>(*child); |             return &downcast<T>(*child); | ||||||
|     } |     } | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
|  | @ -371,7 +326,7 @@ inline T* LayoutNode::first_child_of_type() | ||||||
| { | { | ||||||
|     for (auto* child = first_child(); child; child = child->next_sibling()) { |     for (auto* child = first_child(); child; child = child->next_sibling()) { | ||||||
|         if (is<T>(*child)) |         if (is<T>(*child)) | ||||||
|             return &to<T>(*child); |             return &downcast<T>(*child); | ||||||
|     } |     } | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
|  | @ -381,7 +336,7 @@ inline const T* LayoutNode::first_ancestor_of_type() const | ||||||
| { | { | ||||||
|     for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { |     for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { | ||||||
|         if (is<T>(*ancestor)) |         if (is<T>(*ancestor)) | ||||||
|             return &to<T>(*ancestor); |             return &downcast<T>(*ancestor); | ||||||
|     } |     } | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
|  | @ -391,15 +346,13 @@ inline T* LayoutNode::first_ancestor_of_type() | ||||||
| { | { | ||||||
|     for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { |     for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) { | ||||||
|         if (is<T>(*ancestor)) |         if (is<T>(*ancestor)) | ||||||
|             return &to<T>(*ancestor); |             return &downcast<T>(*ancestor); | ||||||
|     } |     } | ||||||
|     return nullptr; |     return nullptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<LayoutNodeWithStyle>(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() | ||||||
|  |  | ||||||
|  | @ -36,8 +36,8 @@ public: | ||||||
|     LayoutReplaced(Document&, const Element&, NonnullRefPtr<StyleProperties>); |     LayoutReplaced(Document&, const Element&, NonnullRefPtr<StyleProperties>); | ||||||
|     virtual ~LayoutReplaced() override; |     virtual ~LayoutReplaced() override; | ||||||
| 
 | 
 | ||||||
|     const Element& node() const { return to<Element>(*LayoutNode::node()); } |     const Element& node() const { return downcast<Element>(*LayoutNode::node()); } | ||||||
|     Element& node() { return to<Element>(*LayoutNode::node()); } |     Element& node() { return downcast<Element>(*LayoutNode::node()); } | ||||||
| 
 | 
 | ||||||
|     virtual bool is_replaced() const final { return true; } |     virtual bool is_replaced() const final { return true; } | ||||||
| 
 | 
 | ||||||
|  | @ -75,10 +75,8 @@ private: | ||||||
|     float m_intrinsic_ratio { 0 }; |     float m_intrinsic_ratio { 0 }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<LayoutReplaced>(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() | ||||||
|  |  | ||||||
|  | @ -44,10 +44,8 @@ private: | ||||||
|     virtual const char* class_name() const override { return "LayoutTable"; } |     virtual const char* class_name() const override { return "LayoutTable"; } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<LayoutTable>(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() | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ LayoutTableCell::~LayoutTableCell() | ||||||
| size_t LayoutTableCell::colspan() const | size_t LayoutTableCell::colspan() const | ||||||
| { | { | ||||||
|     ASSERT(node()); |     ASSERT(node()); | ||||||
|     return to<Element>(*node()).attribute(HTML::AttributeNames::colspan).to_uint().value_or(1); |     return downcast<Element>(*node()).attribute(HTML::AttributeNames::colspan).to_uint().value_or(1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float LayoutTableCell::width_of_logical_containing_block() const | float LayoutTableCell::width_of_logical_containing_block() const | ||||||
|  |  | ||||||
|  | @ -46,10 +46,8 @@ private: | ||||||
|     virtual float width_of_logical_containing_block() const override; |     virtual float width_of_logical_containing_block() const override; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<LayoutTableCell>(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() | ||||||
|  |  | ||||||
|  | @ -46,10 +46,8 @@ private: | ||||||
|     virtual const char* class_name() const override { return "LayoutTableRow"; } |     virtual const char* class_name() const override { return "LayoutTableRow"; } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<LayoutTableRow>(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() | ||||||
|  |  | ||||||
|  | @ -44,10 +44,8 @@ private: | ||||||
|     virtual const char* class_name() const override { return "LayoutTableRowGroup"; } |     virtual const char* class_name() const override { return "LayoutTableRowGroup"; } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<LayoutTableRowGroup>(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() | ||||||
|  |  | ||||||
|  | @ -61,10 +61,8 @@ private: | ||||||
|     String m_text_for_rendering; |     String m_text_for_rendering; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<LayoutText>(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() | ||||||
|  |  | ||||||
|  | @ -50,7 +50,7 @@ static RefPtr<LayoutNode> create_layout_tree(Node& node, const StyleProperties* | ||||||
|     bool have_inline_children = false; |     bool have_inline_children = false; | ||||||
|     bool have_noninline_children = false; |     bool have_noninline_children = false; | ||||||
| 
 | 
 | ||||||
|     to<ParentNode>(node).for_each_child([&](Node& child) { |     downcast<ParentNode>(node).for_each_child([&](Node& child) { | ||||||
|         auto layout_child = create_layout_tree(child, &layout_node->specified_style()); |         auto layout_child = create_layout_tree(child, &layout_node->specified_style()); | ||||||
|         if (!layout_child) |         if (!layout_child) | ||||||
|             return; |             return; | ||||||
|  | @ -63,7 +63,7 @@ static RefPtr<LayoutNode> create_layout_tree(Node& node, const StyleProperties* | ||||||
| 
 | 
 | ||||||
|     for (auto& layout_child : layout_children) { |     for (auto& layout_child : layout_children) { | ||||||
|         if (have_noninline_children && have_inline_children && layout_child.is_inline()) { |         if (have_noninline_children && have_inline_children && layout_child.is_inline()) { | ||||||
|             if (is<LayoutText>(layout_child) && to<LayoutText>(layout_child).text_for_style(*parent_style) == " ") |             if (is<LayoutText>(layout_child) && downcast<LayoutText>(layout_child).text_for_style(*parent_style) == " ") | ||||||
|                 continue; |                 continue; | ||||||
|             layout_node->inline_wrapper().append_child(layout_child); |             layout_node->inline_wrapper().append_child(layout_child); | ||||||
|         } else { |         } else { | ||||||
|  |  | ||||||
|  | @ -50,10 +50,8 @@ private: | ||||||
|     NonnullRefPtr<GUI::Widget> m_widget; |     NonnullRefPtr<GUI::Widget> m_widget; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template<> |  | ||||||
| inline bool is<LayoutWidget>(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() | ||||||
|  |  | ||||||
|  | @ -47,7 +47,7 @@ void LineBox::add_fragment(const LayoutNode& layout_node, int start, int length, | ||||||
|     m_width += width; |     m_width += width; | ||||||
| 
 | 
 | ||||||
|     if (is<LayoutBox>(layout_node)) |     if (is<LayoutBox>(layout_node)) | ||||||
|         const_cast<LayoutBox&>(to<LayoutBox>(layout_node)).set_containing_line_box_fragment(m_fragments.last()); |         const_cast<LayoutBox&>(downcast<LayoutBox>(layout_node)).set_containing_line_box_fragment(m_fragments.last()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LineBox::trim_trailing_whitespace() | void LineBox::trim_trailing_whitespace() | ||||||
|  |  | ||||||
|  | @ -42,7 +42,7 @@ void LineBoxFragment::paint(PaintContext& context) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (is<LayoutText>(layout_node())) { |     if (is<LayoutText>(layout_node())) { | ||||||
|         to<LayoutText>(layout_node()).paint_fragment(context, *this); |         downcast<LayoutText>(layout_node()).paint_fragment(context, *this); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -63,7 +63,7 @@ StringView LineBoxFragment::text() const | ||||||
| { | { | ||||||
|     if (!is<LayoutText>(layout_node())) |     if (!is<LayoutText>(layout_node())) | ||||||
|         return {}; |         return {}; | ||||||
|     return to<LayoutText>(layout_node()).text_for_rendering().substring_view(m_start, m_length); |     return downcast<LayoutText>(layout_node()).text_for_rendering().substring_view(m_start, m_length); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const Gfx::FloatRect LineBoxFragment::absolute_rect() const | const Gfx::FloatRect LineBoxFragment::absolute_rect() const | ||||||
|  | @ -78,7 +78,7 @@ int LineBoxFragment::text_index_at(float x) const | ||||||
| { | { | ||||||
|     if (!layout_node().is_text()) |     if (!layout_node().is_text()) | ||||||
|         return 0; |         return 0; | ||||||
|     auto& layout_text = to<LayoutText>(layout_node()); |     auto& layout_text = downcast<LayoutText>(layout_node()); | ||||||
|     auto& font = layout_text.specified_style().font(); |     auto& font = layout_text.specified_style().font(); | ||||||
|     Utf8View view(text()); |     Utf8View view(text()); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -127,7 +127,7 @@ GUI::Variant LayoutTreeModel::data(const GUI::ModelIndex& index, Role role) cons | ||||||
|     } |     } | ||||||
|     if (role == Role::Display) { |     if (role == Role::Display) { | ||||||
|         if (node.is_text()) |         if (node.is_text()) | ||||||
|             return String::format("LayoutText: %s", with_whitespace_collapsed(to<LayoutText>(node).text_for_rendering()).characters()); |             return String::format("LayoutText: %s", with_whitespace_collapsed(downcast<LayoutText>(node).text_for_rendering()).characters()); | ||||||
|         StringBuilder builder; |         StringBuilder builder; | ||||||
|         builder.append(node.class_name()); |         builder.append(node.class_name()); | ||||||
|         builder.append(' '); |         builder.append(' '); | ||||||
|  | @ -136,7 +136,7 @@ GUI::Variant LayoutTreeModel::data(const GUI::ModelIndex& index, Role role) cons | ||||||
|         } else if (!node.node()->is_element()) { |         } else if (!node.node()->is_element()) { | ||||||
|             builder.append(node.node()->node_name()); |             builder.append(node.node()->node_name()); | ||||||
|         } else { |         } else { | ||||||
|             auto& element = to<Element>(*node.node()); |             auto& element = downcast<Element>(*node.node()); | ||||||
|             builder.append('<'); |             builder.append('<'); | ||||||
|             builder.append(element.local_name()); |             builder.append(element.local_name()); | ||||||
|             element.for_each_attribute([&](auto& name, auto& value) { |             element.for_each_attribute([&](auto& name, auto& value) { | ||||||
|  |  | ||||||
|  | @ -107,7 +107,7 @@ void PageView::select_all() | ||||||
| 
 | 
 | ||||||
|     int last_layout_node_index_in_node = 0; |     int last_layout_node_index_in_node = 0; | ||||||
|     if (is<LayoutText>(*last_layout_node)) |     if (is<LayoutText>(*last_layout_node)) | ||||||
|         last_layout_node_index_in_node = to<LayoutText>(*last_layout_node).text_for_rendering().length() - 1; |         last_layout_node_index_in_node = downcast<LayoutText>(*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 }); |     layout_root->selection().set({ first_layout_node, 0 }, { last_layout_node, last_layout_node_index_in_node }); | ||||||
|     update(); |     update(); | ||||||
|  | @ -127,13 +127,13 @@ String PageView::selected_text() const | ||||||
|     if (selection.start().layout_node == selection.end().layout_node) { |     if (selection.start().layout_node == selection.end().layout_node) { | ||||||
|         if (!is<LayoutText>(*selection.start().layout_node)) |         if (!is<LayoutText>(*selection.start().layout_node)) | ||||||
|             return ""; |             return ""; | ||||||
|         return to<LayoutText>(*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<LayoutText>(*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
 |     // Start node
 | ||||||
|     auto layout_node = selection.start().layout_node; |     auto layout_node = selection.start().layout_node; | ||||||
|     if (is<LayoutText>(*layout_node)) { |     if (is<LayoutText>(*layout_node)) { | ||||||
|         auto& text = to<LayoutText>(*layout_node).text_for_rendering(); |         auto& text = downcast<LayoutText>(*layout_node).text_for_rendering(); | ||||||
|         builder.append(text.substring(selection.start().index_in_node, text.length() - selection.start().index_in_node)); |         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(); |     layout_node = layout_node->next_in_pre_order(); | ||||||
|     while (layout_node && layout_node != selection.end().layout_node) { |     while (layout_node && layout_node != selection.end().layout_node) { | ||||||
|         if (is<LayoutText>(*layout_node)) |         if (is<LayoutText>(*layout_node)) | ||||||
|             builder.append(to<LayoutText>(*layout_node).text_for_rendering()); |             builder.append(downcast<LayoutText>(*layout_node).text_for_rendering()); | ||||||
|         else if (is<LayoutBreak>(*layout_node) || is<LayoutBlock>(*layout_node)) |         else if (is<LayoutBreak>(*layout_node) || is<LayoutBlock>(*layout_node)) | ||||||
|             builder.append('\n'); |             builder.append('\n'); | ||||||
| 
 | 
 | ||||||
|  | @ -151,7 +151,7 @@ String PageView::selected_text() const | ||||||
|     // End node
 |     // End node
 | ||||||
|     ASSERT(layout_node == selection.end().layout_node); |     ASSERT(layout_node == selection.end().layout_node); | ||||||
|     if (is<LayoutText>(*layout_node)) { |     if (is<LayoutText>(*layout_node)) { | ||||||
|         auto& text = to<LayoutText>(*layout_node).text_for_rendering(); |         auto& text = downcast<LayoutText>(*layout_node).text_for_rendering(); | ||||||
|         builder.append(text.substring(0, selection.end().index_in_node + 1)); |         builder.append(text.substring(0, selection.end().index_in_node + 1)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ void StackingContext::paint(PaintContext& context, LayoutNode::PaintPhase phase) | ||||||
|     } else { |     } else { | ||||||
|         // NOTE: LayoutDocument::paint() merely calls StackingContext::paint()
 |         // NOTE: LayoutDocument::paint() merely calls StackingContext::paint()
 | ||||||
|         //       so we call its base class instead.
 |         //       so we call its base class instead.
 | ||||||
|         to<LayoutDocument>(m_box).LayoutBlock::paint(context, phase); |         downcast<LayoutDocument>(m_box).LayoutBlock::paint(context, phase); | ||||||
|     } |     } | ||||||
|     for (auto* child : m_children) { |     for (auto* child : m_children) { | ||||||
|         child->paint(context, phase); |         child->paint(context, phase); | ||||||
|  | @ -69,7 +69,7 @@ HitTestResult StackingContext::hit_test(const Gfx::IntPoint& position) const | ||||||
|     } else { |     } else { | ||||||
|         // NOTE: LayoutDocument::hit_test() merely calls StackingContext::hit_test()
 |         // NOTE: LayoutDocument::hit_test() merely calls StackingContext::hit_test()
 | ||||||
|         //       so we call its base class instead.
 |         //       so we call its base class instead.
 | ||||||
|         result = to<LayoutDocument>(m_box).LayoutBlock::hit_test(position); |         result = downcast<LayoutDocument>(m_box).LayoutBlock::hit_test(position); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     for (auto* child : m_children) { |     for (auto* child : m_children) { | ||||||
|  |  | ||||||
|  | @ -441,7 +441,7 @@ void HTMLDocumentParser::handle_before_head(HTMLToken& token) | ||||||
| 
 | 
 | ||||||
|     if (token.is_start_tag() && token.tag_name() == HTML::TagNames::head) { |     if (token.is_start_tag() && token.tag_name() == HTML::TagNames::head) { | ||||||
|         auto element = insert_html_element(token); |         auto element = insert_html_element(token); | ||||||
|         m_head_element = to<HTMLHeadElement>(element); |         m_head_element = downcast<HTMLHeadElement>(*element); | ||||||
|         m_insertion_mode = InsertionMode::InHead; |         m_insertion_mode = InsertionMode::InHead; | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | @ -456,7 +456,7 @@ void HTMLDocumentParser::handle_before_head(HTMLToken& token) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| AnythingElse: | AnythingElse: | ||||||
|     m_head_element = to<HTMLHeadElement>(insert_html_element(HTMLToken::make_start_tag(HTML::TagNames::head))); |     m_head_element = downcast<HTMLHeadElement>(*insert_html_element(HTMLToken::make_start_tag(HTML::TagNames::head))); | ||||||
|     m_insertion_mode = InsertionMode::InHead; |     m_insertion_mode = InsertionMode::InHead; | ||||||
|     process_using_the_rules_for(InsertionMode::InHead, token); |     process_using_the_rules_for(InsertionMode::InHead, token); | ||||||
|     return; |     return; | ||||||
|  | @ -527,7 +527,7 @@ void HTMLDocumentParser::handle_in_head(HTMLToken& token) | ||||||
|     if (token.is_start_tag() && token.tag_name() == HTML::TagNames::script) { |     if (token.is_start_tag() && token.tag_name() == HTML::TagNames::script) { | ||||||
|         auto adjusted_insertion_location = find_appropriate_place_for_inserting_node(); |         auto adjusted_insertion_location = find_appropriate_place_for_inserting_node(); | ||||||
|         auto element = create_element_for(token); |         auto element = create_element_for(token); | ||||||
|         auto& script_element = to<HTMLScriptElement>(*element); |         auto& script_element = downcast<HTMLScriptElement>(*element); | ||||||
|         script_element.set_parser_document({}, document()); |         script_element.set_parser_document({}, document()); | ||||||
|         script_element.set_non_blocking({}, false); |         script_element.set_non_blocking({}, false); | ||||||
| 
 | 
 | ||||||
|  | @ -636,7 +636,7 @@ Text* HTMLDocumentParser::find_character_insertion_node() | ||||||
|     if (adjusted_insertion_location.parent->is_document()) |     if (adjusted_insertion_location.parent->is_document()) | ||||||
|         return nullptr; |         return nullptr; | ||||||
|     if (adjusted_insertion_location.parent->last_child() && adjusted_insertion_location.parent->last_child()->is_text()) |     if (adjusted_insertion_location.parent->last_child() && adjusted_insertion_location.parent->last_child()->is_text()) | ||||||
|         return to<Text>(adjusted_insertion_location.parent->last_child()); |         return downcast<Text>(adjusted_insertion_location.parent->last_child()); | ||||||
|     auto new_text_node = adopt(*new Text(document(), "")); |     auto new_text_node = adopt(*new Text(document(), "")); | ||||||
|     adjusted_insertion_location.parent->append_child(new_text_node); |     adjusted_insertion_location.parent->append_child(new_text_node); | ||||||
|     return new_text_node; |     return new_text_node; | ||||||
|  | @ -1179,7 +1179,7 @@ void HTMLDocumentParser::handle_in_body(HTMLToken& token) | ||||||
|             close_a_p_element(); |             close_a_p_element(); | ||||||
|         auto element = insert_html_element(token); |         auto element = insert_html_element(token); | ||||||
|         if (!m_stack_of_open_elements.contains(HTML::TagNames::template_)) |         if (!m_stack_of_open_elements.contains(HTML::TagNames::template_)) | ||||||
|             m_form_element = to<HTMLFormElement>(*element); |             m_form_element = downcast<HTMLFormElement>(*element); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -1756,7 +1756,7 @@ void HTMLDocumentParser::handle_text(HTMLToken& token) | ||||||
|     if (token.is_end_of_file()) { |     if (token.is_end_of_file()) { | ||||||
|         PARSE_ERROR(); |         PARSE_ERROR(); | ||||||
|         if (current_node().local_name() == HTML::TagNames::script) |         if (current_node().local_name() == HTML::TagNames::script) | ||||||
|             to<HTMLScriptElement>(current_node()).set_already_started({}, true); |             downcast<HTMLScriptElement>(current_node()).set_already_started({}, true); | ||||||
|         m_stack_of_open_elements.pop(); |         m_stack_of_open_elements.pop(); | ||||||
|         m_insertion_mode = m_original_insertion_mode; |         m_insertion_mode = m_original_insertion_mode; | ||||||
|         process_using_the_rules_for(m_insertion_mode, token); |         process_using_the_rules_for(m_insertion_mode, token); | ||||||
|  | @ -1766,7 +1766,7 @@ void HTMLDocumentParser::handle_text(HTMLToken& token) | ||||||
|         // Make sure the <script> element has up-to-date text content before preparing the script.
 |         // Make sure the <script> element has up-to-date text content before preparing the script.
 | ||||||
|         flush_character_insertions(); |         flush_character_insertions(); | ||||||
| 
 | 
 | ||||||
|         NonnullRefPtr<HTMLScriptElement> script = to<HTMLScriptElement>(current_node()); |         NonnullRefPtr<HTMLScriptElement> script = downcast<HTMLScriptElement>(current_node()); | ||||||
|         m_stack_of_open_elements.pop(); |         m_stack_of_open_elements.pop(); | ||||||
|         m_insertion_mode = m_original_insertion_mode; |         m_insertion_mode = m_original_insertion_mode; | ||||||
|         // FIXME: Handle tokenizer insertion point stuff here.
 |         // FIXME: Handle tokenizer insertion point stuff here.
 | ||||||
|  | @ -2164,7 +2164,7 @@ void HTMLDocumentParser::handle_in_table(HTMLToken& token) | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         m_form_element = to<HTMLFormElement>(insert_html_element(token)); |         m_form_element = downcast<HTMLFormElement>(*insert_html_element(token)); | ||||||
| 
 | 
 | ||||||
|         // FIXME: See previous FIXME, as this is the same situation but for form.
 |         // FIXME: See previous FIXME, as this is the same situation but for form.
 | ||||||
|         m_stack_of_open_elements.pop(); |         m_stack_of_open_elements.pop(); | ||||||
|  | @ -2783,7 +2783,7 @@ NonnullRefPtrVector<Node> HTMLDocumentParser::parse_html_fragment(Element& conte | ||||||
| 
 | 
 | ||||||
|     for (auto* form_candidate = &context_element; form_candidate; form_candidate = form_candidate->parent_element()) { |     for (auto* form_candidate = &context_element; form_candidate; form_candidate = form_candidate->parent_element()) { | ||||||
|         if (is<HTMLFormElement>(*form_candidate)) { |         if (is<HTMLFormElement>(*form_candidate)) { | ||||||
|             parser.m_form_element = to<HTMLFormElement>(*form_candidate); |             parser.m_form_element = downcast<HTMLFormElement>(*form_candidate); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -63,15 +63,13 @@ protected: | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| namespace Web { | AK_BEGIN_TYPE_TRAITS(Web::SVG::SVGGraphicsElement) | ||||||
| 
 | static bool is_type(const Web::Node& node) | ||||||
| template<> |  | ||||||
| inline bool is<SVG::SVGGraphicsElement>(const Node& node) |  | ||||||
| { | { | ||||||
|     if (!is<Element>(node)) |     if (!is<Web::Element>(node)) | ||||||
|         return false; |         return false; | ||||||
| 
 | 
 | ||||||
|     auto tag_name = to<Element>(node).tag_name(); |     auto tag_name = downcast<Web::Element>(node).tag_name(); | ||||||
| 
 | 
 | ||||||
| #define __ENUMERATE_SVG_TAG(name) \ | #define __ENUMERATE_SVG_TAG(name) \ | ||||||
|     if (tag_name == #name)        \ |     if (tag_name == #name)        \ | ||||||
|  | @ -81,5 +79,4 @@ inline bool is<SVG::SVGGraphicsElement>(const Node& node) | ||||||
| 
 | 
 | ||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
| 
 | AK_END_TYPE_TRAITS() | ||||||
| } |  | ||||||
|  |  | ||||||
|  | @ -101,7 +101,7 @@ void SVGSVGElement::paint(Gfx::Painter& painter, const SVGPaintingContext& conte | ||||||
| { | { | ||||||
|     for_each_child([&](Node& child) { |     for_each_child([&](Node& child) { | ||||||
|         if (is<SVGGraphicsElement>(child)) { |         if (is<SVGGraphicsElement>(child)) { | ||||||
|             to<SVGGraphicsElement>(child).paint(painter, make_painting_context_from(context)); |             downcast<SVGGraphicsElement>(child).paint(painter, make_painting_context_from(context)); | ||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -28,19 +28,11 @@ | ||||||
| 
 | 
 | ||||||
| #include <AK/Assertions.h> | #include <AK/Assertions.h> | ||||||
| #include <AK/NonnullRefPtr.h> | #include <AK/NonnullRefPtr.h> | ||||||
|  | #include <AK/TypeCasts.h> | ||||||
| #include <AK/Weakable.h> | #include <AK/Weakable.h> | ||||||
| 
 | 
 | ||||||
| namespace Web { | namespace Web { | ||||||
| 
 | 
 | ||||||
| // FIXME: I wish I didn't have to forward declare these, but I can't seem to avoid
 |  | ||||||
| //        it if I still want to have for_each_in_subtree_of_type<U> inline here.
 |  | ||||||
| class Node; |  | ||||||
| class LayoutNode; |  | ||||||
| template<typename T> |  | ||||||
| bool is(const Node&); |  | ||||||
| template<typename T> |  | ||||||
| bool is(const LayoutNode&); |  | ||||||
| 
 |  | ||||||
| template<typename T> | template<typename T> | ||||||
| class TreeNode : public Weakable<T> { | class TreeNode : public Weakable<T> { | ||||||
| public: | public: | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling