LayoutNode.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. #pragma once
  2. #include <AK/NonnullRefPtr.h>
  3. #include <AK/Vector.h>
  4. #include <LibDraw/Rect.h>
  5. #include <LibHTML/CSS/StyleProperties.h>
  6. #include <LibHTML/Layout/BoxModelMetrics.h>
  7. #include <LibHTML/RenderingContext.h>
  8. #include <LibHTML/TreeNode.h>
  9. class Document;
  10. class Element;
  11. class LayoutBlock;
  12. class LayoutNode;
  13. class LayoutNodeWithStyle;
  14. class LineBoxFragment;
  15. class Node;
  16. struct HitTestResult {
  17. RefPtr<LayoutNode> layout_node;
  18. };
  19. class LayoutNode : public TreeNode<LayoutNode> {
  20. public:
  21. virtual ~LayoutNode();
  22. virtual HitTestResult hit_test(const Point&) const;
  23. bool is_anonymous() const { return !m_node; }
  24. const Node* node() const { return m_node; }
  25. const Document& document() const;
  26. template<typename Callback>
  27. inline void for_each_child(Callback callback) const
  28. {
  29. for (auto* node = first_child(); node; node = node->next_sibling())
  30. callback(*node);
  31. }
  32. template<typename Callback>
  33. inline void for_each_child(Callback callback)
  34. {
  35. for (auto* node = first_child(); node; node = node->next_sibling())
  36. callback(*node);
  37. }
  38. virtual const char* class_name() const { return "LayoutNode"; }
  39. virtual bool is_text() const { return false; }
  40. virtual bool is_block() const { return false; }
  41. virtual bool is_replaced() const { return false; }
  42. virtual bool is_box() const { return false; }
  43. virtual bool is_table() const { return false; }
  44. virtual bool is_table_row() const { return false; }
  45. virtual bool is_table_cell() const { return false; }
  46. bool has_style() const { return m_has_style; }
  47. bool is_inline() const { return m_inline; }
  48. void set_inline(bool b) { m_inline = b; }
  49. virtual void layout();
  50. virtual void render(RenderingContext&);
  51. const LayoutBlock* containing_block() const;
  52. virtual LayoutNode& inline_wrapper() { return *this; }
  53. const StyleProperties& style() const;
  54. LayoutNodeWithStyle* parent();
  55. const LayoutNodeWithStyle* parent() const;
  56. void inserted_into(LayoutNode&) {}
  57. void removed_from(LayoutNode&) {}
  58. virtual void split_into_lines(LayoutBlock& container);
  59. bool is_visible() const { return m_visible; }
  60. void set_visible(bool visible) { m_visible = visible; }
  61. virtual void set_needs_display();
  62. template<typename Callback>
  63. void for_each_fragment_of_this(Callback);
  64. bool children_are_inline() const { return m_children_are_inline; }
  65. void set_children_are_inline(bool value) { m_children_are_inline = value; }
  66. template<typename U>
  67. const U* next_sibling_of_type() const;
  68. template<typename U>
  69. U* next_sibling_of_type();
  70. template<typename T>
  71. const T* first_child_of_type() const;
  72. template<typename T>
  73. T* first_child_of_type();
  74. template<typename T>
  75. const T* first_ancestor_of_type() const;
  76. template<typename T>
  77. T* first_ancestor_of_type();
  78. protected:
  79. explicit LayoutNode(const Node*);
  80. private:
  81. friend class LayoutNodeWithStyle;
  82. const Node* m_node { nullptr };
  83. bool m_inline { false };
  84. bool m_has_style { false };
  85. bool m_visible { true };
  86. bool m_children_are_inline { false };
  87. };
  88. class LayoutNodeWithStyle : public LayoutNode {
  89. public:
  90. virtual ~LayoutNodeWithStyle() override {}
  91. const StyleProperties& style() const { return m_style; }
  92. void set_style(const StyleProperties& style) { m_style = style; }
  93. protected:
  94. explicit LayoutNodeWithStyle(const Node* node, NonnullRefPtr<StyleProperties> style)
  95. : LayoutNode(node)
  96. , m_style(move(style))
  97. {
  98. m_has_style = true;
  99. }
  100. private:
  101. NonnullRefPtr<StyleProperties> m_style;
  102. };
  103. class LayoutNodeWithStyleAndBoxModelMetrics : public LayoutNodeWithStyle {
  104. public:
  105. BoxModelMetrics& box_model() { return m_box_model; }
  106. const BoxModelMetrics& box_model() const { return m_box_model; }
  107. protected:
  108. LayoutNodeWithStyleAndBoxModelMetrics(const Node* node, NonnullRefPtr<StyleProperties> style)
  109. : LayoutNodeWithStyle(node, move(style))
  110. {
  111. }
  112. private:
  113. BoxModelMetrics m_box_model;
  114. };
  115. inline const StyleProperties& LayoutNode::style() const
  116. {
  117. if (m_has_style)
  118. return static_cast<const LayoutNodeWithStyle*>(this)->style();
  119. return parent()->style();
  120. }
  121. inline const LayoutNodeWithStyle* LayoutNode::parent() const
  122. {
  123. return static_cast<const LayoutNodeWithStyle*>(TreeNode<LayoutNode>::parent());
  124. }
  125. inline LayoutNodeWithStyle* LayoutNode::parent()
  126. {
  127. return static_cast<LayoutNodeWithStyle*>(TreeNode<LayoutNode>::parent());
  128. }
  129. template<typename T>
  130. inline bool is(const LayoutNode&)
  131. {
  132. return false;
  133. }
  134. template<typename T>
  135. inline bool is(const LayoutNode* node)
  136. {
  137. return !node || is<T>(*node);
  138. }
  139. template<>
  140. inline bool is<LayoutNode>(const LayoutNode&)
  141. {
  142. return true;
  143. }
  144. template<>
  145. inline bool is<LayoutNodeWithStyle>(const LayoutNode& node)
  146. {
  147. return node.has_style();
  148. }
  149. template<typename T>
  150. inline const T& to(const LayoutNode& node)
  151. {
  152. ASSERT(is<T>(node));
  153. return static_cast<const T&>(node);
  154. }
  155. template<typename T>
  156. inline T* to(LayoutNode* node)
  157. {
  158. ASSERT(is<T>(node));
  159. return static_cast<T*>(node);
  160. }
  161. template<typename T>
  162. inline const T* to(const LayoutNode* node)
  163. {
  164. ASSERT(is<T>(node));
  165. return static_cast<const T*>(node);
  166. }
  167. template<typename T>
  168. inline T& to(LayoutNode& node)
  169. {
  170. ASSERT(is<T>(node));
  171. return static_cast<T&>(node);
  172. }
  173. template<typename T>
  174. inline const T* LayoutNode::next_sibling_of_type() const
  175. {
  176. for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
  177. if (is<T>(*sibling))
  178. return &to<T>(*sibling);
  179. }
  180. return nullptr;
  181. }
  182. template<typename T>
  183. inline T* LayoutNode::next_sibling_of_type()
  184. {
  185. for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
  186. if (is<T>(*sibling))
  187. return &to<T>(*sibling);
  188. }
  189. return nullptr;
  190. }
  191. template<typename T>
  192. inline const T* LayoutNode::first_child_of_type() const
  193. {
  194. for (auto* child = first_child(); child; child = child->next_sibling()) {
  195. if (is<T>(*child))
  196. return &to<T>(*child);
  197. }
  198. return nullptr;
  199. }
  200. template<typename T>
  201. inline T* LayoutNode::first_child_of_type()
  202. {
  203. for (auto* child = first_child(); child; child = child->next_sibling()) {
  204. if (is<T>(*child))
  205. return &to<T>(*child);
  206. }
  207. return nullptr;
  208. }
  209. template<typename T>
  210. inline const T* LayoutNode::first_ancestor_of_type() const
  211. {
  212. for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
  213. if (is<T>(*ancestor))
  214. return &to<T>(*ancestor);
  215. }
  216. return nullptr;
  217. }
  218. template<typename T>
  219. inline T* LayoutNode::first_ancestor_of_type()
  220. {
  221. for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
  222. if (is<T>(*ancestor))
  223. return &to<T>(*ancestor);
  224. }
  225. return nullptr;
  226. }