Serenity Operating System
at master 82 lines 2.5 kB view raw
1/* 2 * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <LibJS/Runtime/Object.h> 10#include <LibWeb/DOM/NodeFilter.h> 11 12namespace Web::DOM { 13 14// https://dom.spec.whatwg.org/#nodeiterator 15class NodeIterator final : public Bindings::PlatformObject { 16 WEB_PLATFORM_OBJECT(NodeIterator, Bindings::PlatformObject); 17 18public: 19 static WebIDL::ExceptionOr<JS::NonnullGCPtr<NodeIterator>> create(Node& root, unsigned what_to_show, JS::GCPtr<NodeFilter>); 20 21 virtual ~NodeIterator() override; 22 23 JS::NonnullGCPtr<Node> root() { return m_root; } 24 JS::NonnullGCPtr<Node> reference_node() { return m_reference.node; } 25 bool pointer_before_reference_node() const { return m_reference.is_before_node; } 26 unsigned what_to_show() const { return m_what_to_show; } 27 28 NodeFilter* filter() { return m_filter.ptr(); } 29 30 JS::ThrowCompletionOr<JS::GCPtr<Node>> next_node(); 31 JS::ThrowCompletionOr<JS::GCPtr<Node>> previous_node(); 32 33 void detach(); 34 35 void run_pre_removing_steps(Node&); 36 37private: 38 explicit NodeIterator(Node& root); 39 40 virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override; 41 virtual void visit_edges(Cell::Visitor&) override; 42 virtual void finalize() override; 43 44 enum class Direction { 45 Next, 46 Previous, 47 }; 48 49 JS::ThrowCompletionOr<JS::GCPtr<Node>> traverse(Direction); 50 51 JS::ThrowCompletionOr<NodeFilter::Result> filter(Node&); 52 53 // https://dom.spec.whatwg.org/#concept-traversal-root 54 JS::NonnullGCPtr<Node> m_root; 55 56 struct NodePointer { 57 JS::NonnullGCPtr<Node> node; 58 59 // https://dom.spec.whatwg.org/#nodeiterator-pointer-before-reference 60 bool is_before_node { true }; 61 }; 62 63 void run_pre_removing_steps_with_node_pointer(Node&, NodePointer&); 64 65 // https://dom.spec.whatwg.org/#nodeiterator-reference 66 NodePointer m_reference; 67 68 // While traversal is ongoing, we keep track of the current node pointer. 69 // This allows us to adjust it during traversal if calling the filter ends up removing the node from the DOM. 70 Optional<NodePointer> m_traversal_pointer; 71 72 // https://dom.spec.whatwg.org/#concept-traversal-whattoshow 73 unsigned m_what_to_show { 0 }; 74 75 // https://dom.spec.whatwg.org/#concept-traversal-filter 76 JS::GCPtr<NodeFilter> m_filter; 77 78 // https://dom.spec.whatwg.org/#concept-traversal-active 79 bool m_active { false }; 80}; 81 82}