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