Node.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. /*
  2. * Copyright (c) 2018-2023, Andreas Kling <andreas@ladybird.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Badge.h>
  8. #include <AK/FlyString.h>
  9. #include <AK/GenericShorthands.h>
  10. #include <AK/JsonObjectSerializer.h>
  11. #include <AK/RefPtr.h>
  12. #include <AK/TypeCasts.h>
  13. #include <AK/Vector.h>
  14. #include <LibWeb/DOM/AccessibilityTreeNode.h>
  15. #include <LibWeb/DOM/EventTarget.h>
  16. #include <LibWeb/DOM/Slottable.h>
  17. #include <LibWeb/DOMParsing/XMLSerializer.h>
  18. #include <LibWeb/TraversalDecision.h>
  19. #include <LibWeb/WebIDL/ExceptionOr.h>
  20. namespace Web::DOM {
  21. enum class NodeType : u16 {
  22. INVALID = 0,
  23. ELEMENT_NODE = 1,
  24. ATTRIBUTE_NODE = 2,
  25. TEXT_NODE = 3,
  26. CDATA_SECTION_NODE = 4,
  27. ENTITY_REFERENCE_NODE = 5,
  28. ENTITY_NODE = 6,
  29. PROCESSING_INSTRUCTION_NODE = 7,
  30. COMMENT_NODE = 8,
  31. DOCUMENT_NODE = 9,
  32. DOCUMENT_TYPE_NODE = 10,
  33. DOCUMENT_FRAGMENT_NODE = 11,
  34. NOTATION_NODE = 12
  35. };
  36. enum class NameOrDescription {
  37. Name,
  38. Description
  39. };
  40. struct GetRootNodeOptions {
  41. bool composed { false };
  42. };
  43. enum class FragmentSerializationMode {
  44. Inner,
  45. Outer,
  46. };
  47. #define ENUMERATE_STYLE_INVALIDATION_REASONS(X) \
  48. X(AdoptedStyleSheetsList) \
  49. X(CSSFontLoaded) \
  50. X(CSSImportRule) \
  51. X(DidLoseFocus) \
  52. X(DidReceiveFocus) \
  53. X(EditingInsertion) \
  54. X(ElementAttributeChange) \
  55. X(ElementSetShadowRoot) \
  56. X(HTMLInputElementSetChecked) \
  57. X(HTMLObjectElementUpdateLayoutAndChildObjects) \
  58. X(HTMLSelectElementSetIsOpen) \
  59. X(Hover) \
  60. X(MediaQueryChangedMatchState) \
  61. X(NavigableSetViewportSize) \
  62. X(NodeInsertBefore) \
  63. X(NodeRemove) \
  64. X(NodeSetTextContent) \
  65. X(Other) \
  66. X(ParentOfInsertedNode) \
  67. X(SetSelectorText) \
  68. X(SettingsChange) \
  69. X(StyleSheetDeleteRule) \
  70. X(StyleSheetInsertRule) \
  71. X(StyleSheetListAddSheet) \
  72. X(StyleSheetListRemoveSheet)
  73. enum class StyleInvalidationReason {
  74. #define __ENUMERATE_STYLE_INVALIDATION_REASON(reason) reason,
  75. ENUMERATE_STYLE_INVALIDATION_REASONS(__ENUMERATE_STYLE_INVALIDATION_REASON)
  76. #undef __ENUMERATE_STYLE_INVALIDATION_REASON
  77. };
  78. class Node : public EventTarget {
  79. WEB_PLATFORM_OBJECT(Node, EventTarget);
  80. public:
  81. ParentNode* parent_or_shadow_host();
  82. ParentNode const* parent_or_shadow_host() const { return const_cast<Node*>(this)->parent_or_shadow_host(); }
  83. Element* parent_or_shadow_host_element();
  84. Element const* parent_or_shadow_host_element() const { return const_cast<Node*>(this)->parent_or_shadow_host_element(); }
  85. virtual ~Node();
  86. NodeType type() const { return m_type; }
  87. bool is_element() const { return type() == NodeType::ELEMENT_NODE; }
  88. bool is_text() const { return type() == NodeType::TEXT_NODE; }
  89. bool is_document() const { return type() == NodeType::DOCUMENT_NODE; }
  90. bool is_document_type() const { return type() == NodeType::DOCUMENT_TYPE_NODE; }
  91. bool is_comment() const { return type() == NodeType::COMMENT_NODE; }
  92. bool is_character_data() const { return first_is_one_of(type(), NodeType::TEXT_NODE, NodeType::COMMENT_NODE, NodeType::CDATA_SECTION_NODE, NodeType::PROCESSING_INSTRUCTION_NODE); }
  93. bool is_document_fragment() const { return type() == NodeType::DOCUMENT_FRAGMENT_NODE; }
  94. bool is_parent_node() const { return is_element() || is_document() || is_document_fragment(); }
  95. bool is_slottable() const { return is_element() || is_text() || is_cdata_section(); }
  96. bool is_attribute() const { return type() == NodeType::ATTRIBUTE_NODE; }
  97. bool is_cdata_section() const { return type() == NodeType::CDATA_SECTION_NODE; }
  98. virtual bool is_shadow_root() const { return false; }
  99. virtual bool requires_svg_container() const { return false; }
  100. virtual bool is_svg_container() const { return false; }
  101. virtual bool is_svg_element() const { return false; }
  102. virtual bool is_svg_graphics_element() const { return false; }
  103. virtual bool is_svg_script_element() const { return false; }
  104. virtual bool is_svg_style_element() const { return false; }
  105. virtual bool is_svg_svg_element() const { return false; }
  106. virtual bool is_svg_use_element() const { return false; }
  107. bool in_a_document_tree() const;
  108. // NOTE: This is intended for the JS bindings.
  109. u16 node_type() const { return (u16)m_type; }
  110. virtual bool is_editable() const;
  111. virtual bool is_dom_node() const final { return true; }
  112. virtual bool is_html_element() const { return false; }
  113. virtual bool is_html_html_element() const { return false; }
  114. virtual bool is_html_anchor_element() const { return false; }
  115. virtual bool is_html_base_element() const { return false; }
  116. virtual bool is_html_body_element() const { return false; }
  117. virtual bool is_html_input_element() const { return false; }
  118. virtual bool is_html_link_element() const { return false; }
  119. virtual bool is_html_progress_element() const { return false; }
  120. virtual bool is_html_script_element() const { return false; }
  121. virtual bool is_html_style_element() const { return false; }
  122. virtual bool is_html_template_element() const { return false; }
  123. virtual bool is_html_table_element() const { return false; }
  124. virtual bool is_html_table_section_element() const { return false; }
  125. virtual bool is_html_table_row_element() const { return false; }
  126. virtual bool is_html_table_cell_element() const { return false; }
  127. virtual bool is_html_br_element() const { return false; }
  128. virtual bool is_html_button_element() const { return false; }
  129. virtual bool is_html_slot_element() const { return false; }
  130. virtual bool is_html_embed_element() const { return false; }
  131. virtual bool is_html_object_element() const { return false; }
  132. virtual bool is_html_form_element() const { return false; }
  133. virtual bool is_html_image_element() const { return false; }
  134. virtual bool is_navigable_container() const { return false; }
  135. virtual bool is_lazy_loading() const { return false; }
  136. WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> pre_insert(JS::NonnullGCPtr<Node>, JS::GCPtr<Node>);
  137. WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> pre_remove(JS::NonnullGCPtr<Node>);
  138. WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> append_child(JS::NonnullGCPtr<Node>);
  139. WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> remove_child(JS::NonnullGCPtr<Node>);
  140. void insert_before(JS::NonnullGCPtr<Node> node, JS::GCPtr<Node> child, bool suppress_observers = false);
  141. void remove(bool suppress_observers = false);
  142. void remove_all_children(bool suppress_observers = false);
  143. enum DocumentPosition : u16 {
  144. DOCUMENT_POSITION_EQUAL = 0,
  145. DOCUMENT_POSITION_DISCONNECTED = 1,
  146. DOCUMENT_POSITION_PRECEDING = 2,
  147. DOCUMENT_POSITION_FOLLOWING = 4,
  148. DOCUMENT_POSITION_CONTAINS = 8,
  149. DOCUMENT_POSITION_CONTAINED_BY = 16,
  150. DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32,
  151. };
  152. u16 compare_document_position(JS::GCPtr<Node> other);
  153. WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> replace_child(JS::NonnullGCPtr<Node> node, JS::NonnullGCPtr<Node> child);
  154. WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> clone_node(Document* document = nullptr, bool clone_children = false);
  155. WebIDL::ExceptionOr<JS::NonnullGCPtr<Node>> clone_node_binding(bool deep);
  156. // NOTE: This is intended for the JS bindings.
  157. bool has_child_nodes() const { return has_children(); }
  158. JS::NonnullGCPtr<NodeList> child_nodes();
  159. Vector<JS::Handle<Node>> children_as_vector() const;
  160. virtual FlyString node_name() const = 0;
  161. String base_uri() const;
  162. String descendant_text_content() const;
  163. Optional<String> text_content() const;
  164. void set_text_content(Optional<String> const&);
  165. WebIDL::ExceptionOr<void> normalize();
  166. Optional<String> node_value() const;
  167. void set_node_value(Optional<String> const&);
  168. JS::GCPtr<HTML::Navigable> navigable() const;
  169. Document& document() { return *m_document; }
  170. Document const& document() const { return *m_document; }
  171. JS::GCPtr<Document> owner_document() const;
  172. const HTML::HTMLAnchorElement* enclosing_link_element() const;
  173. const HTML::HTMLElement* enclosing_html_element() const;
  174. const HTML::HTMLElement* enclosing_html_element_with_attribute(FlyString const&) const;
  175. String child_text_content() const;
  176. Node& root();
  177. Node const& root() const
  178. {
  179. return const_cast<Node*>(this)->root();
  180. }
  181. Node& shadow_including_root();
  182. Node const& shadow_including_root() const
  183. {
  184. return const_cast<Node*>(this)->shadow_including_root();
  185. }
  186. bool is_connected() const;
  187. [[nodiscard]] bool is_browsing_context_connected() const;
  188. Node* parent_node() { return parent(); }
  189. Node const* parent_node() const { return parent(); }
  190. Element* parent_element();
  191. Element const* parent_element() const;
  192. virtual void inserted();
  193. virtual void removed_from(Node*);
  194. virtual void children_changed() { }
  195. virtual void adopted_from(Document&) { }
  196. virtual WebIDL::ExceptionOr<void> cloned(Node&, bool) { return {}; }
  197. Layout::Node const* layout_node() const { return m_layout_node; }
  198. Layout::Node* layout_node() { return m_layout_node; }
  199. Painting::PaintableBox const* paintable_box() const;
  200. Painting::PaintableBox* paintable_box();
  201. Painting::Paintable const* paintable() const;
  202. Painting::Paintable* paintable();
  203. void set_paintable(JS::GCPtr<Painting::Paintable>);
  204. void set_layout_node(Badge<Layout::Node>, JS::NonnullGCPtr<Layout::Node>);
  205. void detach_layout_node(Badge<Layout::TreeBuilder>);
  206. virtual bool is_child_allowed(Node const&) const { return true; }
  207. bool needs_style_update() const { return m_needs_style_update; }
  208. void set_needs_style_update(bool);
  209. bool child_needs_style_update() const { return m_child_needs_style_update; }
  210. void set_child_needs_style_update(bool b) { m_child_needs_style_update = b; }
  211. void invalidate_style(StyleInvalidationReason);
  212. void set_document(Badge<Document>, Document&);
  213. virtual EventTarget* get_parent(Event const&) override;
  214. template<typename T>
  215. bool fast_is() const = delete;
  216. WebIDL::ExceptionOr<void> ensure_pre_insertion_validity(JS::NonnullGCPtr<Node> node, JS::GCPtr<Node> child) const;
  217. bool is_host_including_inclusive_ancestor_of(Node const&) const;
  218. bool is_scripting_enabled() const;
  219. bool is_scripting_disabled() const;
  220. bool contains(JS::GCPtr<Node>) const;
  221. // Used for dumping the DOM Tree
  222. void serialize_tree_as_json(JsonObjectSerializer<StringBuilder>&) const;
  223. bool is_shadow_including_descendant_of(Node const&) const;
  224. bool is_shadow_including_inclusive_descendant_of(Node const&) const;
  225. bool is_shadow_including_ancestor_of(Node const&) const;
  226. bool is_shadow_including_inclusive_ancestor_of(Node const&) const;
  227. i32 unique_id() const { return m_unique_id; }
  228. static Node* from_unique_id(i32);
  229. WebIDL::ExceptionOr<String> serialize_fragment(DOMParsing::RequireWellFormed, FragmentSerializationMode = FragmentSerializationMode::Inner) const;
  230. WebIDL::ExceptionOr<void> unsafely_set_html(Element&, StringView);
  231. void replace_all(JS::GCPtr<Node>);
  232. void string_replace_all(String const&);
  233. bool is_same_node(Node const*) const;
  234. bool is_equal_node(Node const*) const;
  235. JS::NonnullGCPtr<Node> get_root_node(GetRootNodeOptions const& options = {});
  236. bool is_uninteresting_whitespace_node() const;
  237. String debug_description() const;
  238. size_t length() const;
  239. auto& registered_observer_list() { return m_registered_observer_list; }
  240. auto const& registered_observer_list() const { return m_registered_observer_list; }
  241. void add_registered_observer(RegisteredObserver&);
  242. void queue_mutation_record(FlyString const& type, Optional<FlyString> const& attribute_name, Optional<FlyString> const& attribute_namespace, Optional<String> const& old_value, Vector<JS::Handle<Node>> added_nodes, Vector<JS::Handle<Node>> removed_nodes, Node* previous_sibling, Node* next_sibling) const;
  243. // https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-descendant
  244. template<typename Callback>
  245. TraversalDecision for_each_shadow_including_inclusive_descendant(Callback);
  246. // https://dom.spec.whatwg.org/#concept-shadow-including-descendant
  247. template<typename Callback>
  248. TraversalDecision for_each_shadow_including_descendant(Callback);
  249. Slottable as_slottable();
  250. Node* parent() { return m_parent.ptr(); }
  251. Node const* parent() const { return m_parent.ptr(); }
  252. bool has_children() const { return m_first_child; }
  253. Node* next_sibling() { return m_next_sibling.ptr(); }
  254. Node* previous_sibling() { return m_previous_sibling.ptr(); }
  255. Node* first_child() { return m_first_child.ptr(); }
  256. Node* last_child() { return m_last_child.ptr(); }
  257. Node const* next_sibling() const { return m_next_sibling.ptr(); }
  258. Node const* previous_sibling() const { return m_previous_sibling.ptr(); }
  259. Node const* first_child() const { return m_first_child.ptr(); }
  260. Node const* last_child() const { return m_last_child.ptr(); }
  261. size_t child_count() const
  262. {
  263. size_t count = 0;
  264. for (auto* child = first_child(); child; child = child->next_sibling())
  265. ++count;
  266. return count;
  267. }
  268. Node* child_at_index(int index)
  269. {
  270. int count = 0;
  271. for (auto* child = first_child(); child; child = child->next_sibling()) {
  272. if (count == index)
  273. return child;
  274. ++count;
  275. }
  276. return nullptr;
  277. }
  278. Node const* child_at_index(int index) const
  279. {
  280. return const_cast<Node*>(this)->child_at_index(index);
  281. }
  282. // https://dom.spec.whatwg.org/#concept-tree-index
  283. size_t index() const
  284. {
  285. // The index of an object is its number of preceding siblings, or 0 if it has none.
  286. size_t index = 0;
  287. for (auto* node = previous_sibling(); node; node = node->previous_sibling())
  288. ++index;
  289. return index;
  290. }
  291. Optional<size_t> index_of_child(Node const& search_child)
  292. {
  293. VERIFY(search_child.parent() == this);
  294. size_t index = 0;
  295. auto* child = first_child();
  296. VERIFY(child);
  297. do {
  298. if (child == &search_child)
  299. return index;
  300. index++;
  301. } while (child && (child = child->next_sibling()));
  302. return {};
  303. }
  304. template<typename ChildType>
  305. Optional<size_t> index_of_child(Node const& search_child)
  306. {
  307. VERIFY(search_child.parent() == this);
  308. size_t index = 0;
  309. auto* child = first_child();
  310. VERIFY(child);
  311. do {
  312. if (!is<ChildType>(child))
  313. continue;
  314. if (child == &search_child)
  315. return index;
  316. index++;
  317. } while (child && (child = child->next_sibling()));
  318. return {};
  319. }
  320. bool is_ancestor_of(Node const&) const;
  321. bool is_inclusive_ancestor_of(Node const&) const;
  322. bool is_descendant_of(Node const&) const;
  323. bool is_inclusive_descendant_of(Node const&) const;
  324. bool is_following(Node const&) const;
  325. Node* next_in_pre_order()
  326. {
  327. if (first_child())
  328. return first_child();
  329. Node* node;
  330. if (!(node = next_sibling())) {
  331. node = parent();
  332. while (node && !node->next_sibling())
  333. node = node->parent();
  334. if (node)
  335. node = node->next_sibling();
  336. }
  337. return node;
  338. }
  339. Node* next_in_pre_order(Node const* stay_within)
  340. {
  341. if (first_child())
  342. return first_child();
  343. Node* node = static_cast<Node*>(this);
  344. Node* next = nullptr;
  345. while (!(next = node->next_sibling())) {
  346. node = node->parent();
  347. if (!node || node == stay_within)
  348. return nullptr;
  349. }
  350. return next;
  351. }
  352. Node const* next_in_pre_order() const
  353. {
  354. return const_cast<Node*>(this)->next_in_pre_order();
  355. }
  356. Node const* next_in_pre_order(Node const* stay_within) const
  357. {
  358. return const_cast<Node*>(this)->next_in_pre_order(stay_within);
  359. }
  360. Node* previous_in_pre_order()
  361. {
  362. if (auto* node = previous_sibling()) {
  363. while (node->last_child())
  364. node = node->last_child();
  365. return node;
  366. }
  367. return parent();
  368. }
  369. Node const* previous_in_pre_order() const
  370. {
  371. return const_cast<Node*>(this)->previous_in_pre_order();
  372. }
  373. bool is_before(Node const& other) const
  374. {
  375. if (this == &other)
  376. return false;
  377. for (auto* node = this; node; node = node->next_in_pre_order()) {
  378. if (node == &other)
  379. return true;
  380. }
  381. return false;
  382. }
  383. // https://dom.spec.whatwg.org/#concept-tree-preceding (Object A is 'typename U' and Object B is 'this')
  384. template<typename U>
  385. bool has_preceding_node_of_type_in_tree_order() const
  386. {
  387. for (auto* node = previous_in_pre_order(); node; node = node->previous_in_pre_order()) {
  388. if (is<U>(node))
  389. return true;
  390. }
  391. return false;
  392. }
  393. // https://dom.spec.whatwg.org/#concept-tree-following (Object A is 'typename U' and Object B is 'this')
  394. template<typename U>
  395. bool has_following_node_of_type_in_tree_order() const
  396. {
  397. for (auto* node = next_in_pre_order(); node; node = node->next_in_pre_order()) {
  398. if (is<U>(node))
  399. return true;
  400. }
  401. return false;
  402. }
  403. template<typename Callback>
  404. TraversalDecision for_each_in_inclusive_subtree(Callback callback) const
  405. {
  406. if (auto decision = callback(static_cast<Node const&>(*this)); decision != TraversalDecision::Continue)
  407. return decision;
  408. for (auto* child = first_child(); child; child = child->next_sibling()) {
  409. if (child->for_each_in_inclusive_subtree(callback) == TraversalDecision::Break)
  410. return TraversalDecision::Break;
  411. }
  412. return TraversalDecision::Continue;
  413. }
  414. template<typename Callback>
  415. TraversalDecision for_each_in_inclusive_subtree(Callback callback)
  416. {
  417. if (auto decision = callback(static_cast<Node&>(*this)); decision != TraversalDecision::Continue)
  418. return decision;
  419. for (auto* child = first_child(); child; child = child->next_sibling()) {
  420. if (child->for_each_in_inclusive_subtree(callback) == TraversalDecision::Break)
  421. return TraversalDecision::Break;
  422. }
  423. return TraversalDecision::Continue;
  424. }
  425. template<typename U, typename Callback>
  426. TraversalDecision for_each_in_inclusive_subtree_of_type(Callback callback)
  427. {
  428. if (is<U>(static_cast<Node&>(*this))) {
  429. if (auto decision = callback(static_cast<U&>(*this)); decision != TraversalDecision::Continue)
  430. return decision;
  431. }
  432. for (auto* child = first_child(); child; child = child->next_sibling()) {
  433. if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == TraversalDecision::Break)
  434. return TraversalDecision::Break;
  435. }
  436. return TraversalDecision::Continue;
  437. }
  438. template<typename U, typename Callback>
  439. TraversalDecision for_each_in_inclusive_subtree_of_type(Callback callback) const
  440. {
  441. if (is<U>(static_cast<Node const&>(*this))) {
  442. if (auto decision = callback(static_cast<U const&>(*this)); decision != TraversalDecision::Continue)
  443. return decision;
  444. }
  445. for (auto* child = first_child(); child; child = child->next_sibling()) {
  446. if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == TraversalDecision::Break)
  447. return TraversalDecision::Break;
  448. }
  449. return TraversalDecision::Continue;
  450. }
  451. template<typename Callback>
  452. TraversalDecision for_each_in_subtree(Callback callback) const
  453. {
  454. for (auto* child = first_child(); child; child = child->next_sibling()) {
  455. if (child->for_each_in_inclusive_subtree(callback) == TraversalDecision::Break)
  456. return TraversalDecision::Break;
  457. }
  458. return TraversalDecision::Continue;
  459. }
  460. template<typename Callback>
  461. TraversalDecision for_each_in_subtree(Callback callback)
  462. {
  463. for (auto* child = first_child(); child; child = child->next_sibling()) {
  464. if (child->for_each_in_inclusive_subtree(callback) == TraversalDecision::Break)
  465. return TraversalDecision::Break;
  466. }
  467. return TraversalDecision::Continue;
  468. }
  469. template<typename U, typename Callback>
  470. TraversalDecision for_each_in_subtree_of_type(Callback callback)
  471. {
  472. for (auto* child = first_child(); child; child = child->next_sibling()) {
  473. if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == TraversalDecision::Break)
  474. return TraversalDecision::Break;
  475. }
  476. return TraversalDecision::Continue;
  477. }
  478. template<typename U, typename Callback>
  479. TraversalDecision for_each_in_subtree_of_type(Callback callback) const
  480. {
  481. for (auto* child = first_child(); child; child = child->next_sibling()) {
  482. if (child->template for_each_in_inclusive_subtree_of_type<U>(callback) == TraversalDecision::Break)
  483. return TraversalDecision::Break;
  484. }
  485. return TraversalDecision::Continue;
  486. }
  487. template<typename Callback>
  488. void for_each_child(Callback callback) const
  489. {
  490. return const_cast<Node*>(this)->for_each_child(move(callback));
  491. }
  492. template<typename Callback>
  493. void for_each_child(Callback callback)
  494. {
  495. for (auto* node = first_child(); node; node = node->next_sibling()) {
  496. if (callback(*node) == IterationDecision::Break)
  497. return;
  498. }
  499. }
  500. template<typename U, typename Callback>
  501. void for_each_child_of_type(Callback callback)
  502. {
  503. for (auto* node = first_child(); node; node = node->next_sibling()) {
  504. if (is<U>(node)) {
  505. if (callback(verify_cast<U>(*node)) == IterationDecision::Break)
  506. return;
  507. }
  508. }
  509. }
  510. template<typename U, typename Callback>
  511. void for_each_child_of_type(Callback callback) const
  512. {
  513. return const_cast<Node*>(this)->template for_each_child_of_type<U>(move(callback));
  514. }
  515. template<typename U>
  516. U const* next_sibling_of_type() const
  517. {
  518. return const_cast<Node*>(this)->template next_sibling_of_type<U>();
  519. }
  520. template<typename U>
  521. inline U* next_sibling_of_type()
  522. {
  523. for (auto* sibling = next_sibling(); sibling; sibling = sibling->next_sibling()) {
  524. if (is<U>(*sibling))
  525. return &verify_cast<U>(*sibling);
  526. }
  527. return nullptr;
  528. }
  529. template<typename U>
  530. U const* previous_sibling_of_type() const
  531. {
  532. return const_cast<Node*>(this)->template previous_sibling_of_type<U>();
  533. }
  534. template<typename U>
  535. U* previous_sibling_of_type()
  536. {
  537. for (auto* sibling = previous_sibling(); sibling; sibling = sibling->previous_sibling()) {
  538. if (is<U>(*sibling))
  539. return &verify_cast<U>(*sibling);
  540. }
  541. return nullptr;
  542. }
  543. template<typename U>
  544. U const* first_child_of_type() const
  545. {
  546. return const_cast<Node*>(this)->template first_child_of_type<U>();
  547. }
  548. template<typename U>
  549. U const* last_child_of_type() const
  550. {
  551. return const_cast<Node*>(this)->template last_child_of_type<U>();
  552. }
  553. template<typename U>
  554. U* first_child_of_type()
  555. {
  556. for (auto* child = first_child(); child; child = child->next_sibling()) {
  557. if (is<U>(*child))
  558. return &verify_cast<U>(*child);
  559. }
  560. return nullptr;
  561. }
  562. template<typename U>
  563. U* last_child_of_type()
  564. {
  565. for (auto* child = last_child(); child; child = child->previous_sibling()) {
  566. if (is<U>(*child))
  567. return &verify_cast<U>(*child);
  568. }
  569. return nullptr;
  570. }
  571. template<typename U>
  572. bool has_child_of_type() const
  573. {
  574. return first_child_of_type<U>() != nullptr;
  575. }
  576. template<typename U>
  577. U const* first_ancestor_of_type() const
  578. {
  579. return const_cast<Node*>(this)->template first_ancestor_of_type<U>();
  580. }
  581. template<typename U>
  582. U* first_ancestor_of_type()
  583. {
  584. for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
  585. if (is<U>(*ancestor))
  586. return &verify_cast<U>(*ancestor);
  587. }
  588. return nullptr;
  589. }
  590. template<typename U>
  591. U const* shadow_including_first_ancestor_of_type() const
  592. {
  593. return const_cast<Node*>(this)->template shadow_including_first_ancestor_of_type<U>();
  594. }
  595. template<typename U>
  596. U* shadow_including_first_ancestor_of_type();
  597. bool is_parent_of(Node const& other) const
  598. {
  599. for (auto* child = first_child(); child; child = child->next_sibling()) {
  600. if (&other == child)
  601. return true;
  602. }
  603. return false;
  604. }
  605. ErrorOr<String> accessible_name(Document const&) const;
  606. ErrorOr<String> accessible_description(Document const&) const;
  607. Optional<String> locate_a_namespace(Optional<String> const& prefix) const;
  608. Optional<String> lookup_namespace_uri(Optional<String> prefix) const;
  609. Optional<String> lookup_prefix(Optional<String> namespace_) const;
  610. bool is_default_namespace(Optional<String> namespace_) const;
  611. protected:
  612. Node(JS::Realm&, Document&, NodeType);
  613. Node(Document&, NodeType);
  614. virtual void visit_edges(Cell::Visitor&) override;
  615. virtual void finalize() override;
  616. JS::GCPtr<Document> m_document;
  617. JS::GCPtr<Layout::Node> m_layout_node;
  618. JS::GCPtr<Painting::Paintable> m_paintable;
  619. NodeType m_type { NodeType::INVALID };
  620. bool m_needs_style_update { false };
  621. bool m_child_needs_style_update { false };
  622. i32 m_unique_id {};
  623. // https://dom.spec.whatwg.org/#registered-observer-list
  624. // "Nodes have a strong reference to registered observers in their registered observer list." https://dom.spec.whatwg.org/#garbage-collection
  625. OwnPtr<Vector<JS::NonnullGCPtr<RegisteredObserver>>> m_registered_observer_list;
  626. void build_accessibility_tree(AccessibilityTreeNode& parent);
  627. ErrorOr<String> name_or_description(NameOrDescription, Document const&, HashTable<i32>&) const;
  628. private:
  629. void queue_tree_mutation_record(Vector<JS::Handle<Node>> added_nodes, Vector<JS::Handle<Node>> removed_nodes, Node* previous_sibling, Node* next_sibling);
  630. void insert_before_impl(JS::NonnullGCPtr<Node>, JS::GCPtr<Node> child);
  631. void append_child_impl(JS::NonnullGCPtr<Node>);
  632. void remove_child_impl(JS::NonnullGCPtr<Node>);
  633. static Optional<StringView> first_valid_id(StringView, Document const&);
  634. static ErrorOr<void> append_without_space(StringBuilder, StringView const&);
  635. static ErrorOr<void> append_with_space(StringBuilder, StringView const&);
  636. static ErrorOr<void> prepend_without_space(StringBuilder, StringView const&);
  637. static ErrorOr<void> prepend_with_space(StringBuilder, StringView const&);
  638. JS::GCPtr<Node> m_parent;
  639. JS::GCPtr<Node> m_first_child;
  640. JS::GCPtr<Node> m_last_child;
  641. JS::GCPtr<Node> m_next_sibling;
  642. JS::GCPtr<Node> m_previous_sibling;
  643. JS::GCPtr<NodeList> m_child_nodes;
  644. };
  645. }
  646. template<>
  647. inline bool JS::Object::fast_is<Web::DOM::Node>() const { return is_dom_node(); }