Coverage Report

Created: 2025-03-04 07:22

/src/serenity/Userland/Libraries/LibWeb/DOM/NodeIterator.h
Line
Count
Source (jump to first uncovered line)
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
12
namespace Web::DOM {
13
14
// https://dom.spec.whatwg.org/#nodeiterator
15
class NodeIterator final : public Bindings::PlatformObject {
16
    WEB_PLATFORM_OBJECT(NodeIterator, Bindings::PlatformObject);
17
    JS_DECLARE_ALLOCATOR(NodeIterator);
18
19
public:
20
    static WebIDL::ExceptionOr<JS::NonnullGCPtr<NodeIterator>> create(Node& root, unsigned what_to_show, JS::GCPtr<NodeFilter>);
21
22
    virtual ~NodeIterator() override;
23
24
0
    JS::NonnullGCPtr<Node> root() { return m_root; }
25
0
    JS::NonnullGCPtr<Node> reference_node() { return m_reference.node; }
26
0
    bool pointer_before_reference_node() const { return m_reference.is_before_node; }
27
0
    unsigned what_to_show() const { return m_what_to_show; }
28
29
0
    NodeFilter* filter() { return m_filter.ptr(); }
30
31
    JS::ThrowCompletionOr<JS::GCPtr<Node>> next_node();
32
    JS::ThrowCompletionOr<JS::GCPtr<Node>> previous_node();
33
34
    void detach();
35
36
    void run_pre_removing_steps(Node&);
37
38
private:
39
    explicit NodeIterator(Node& root);
40
41
    virtual void initialize(JS::Realm&) override;
42
    virtual void visit_edges(Cell::Visitor&) override;
43
    virtual void finalize() override;
44
45
    enum class Direction {
46
        Next,
47
        Previous,
48
    };
49
50
    JS::ThrowCompletionOr<JS::GCPtr<Node>> traverse(Direction);
51
52
    JS::ThrowCompletionOr<NodeFilter::Result> filter(Node&);
53
54
    // https://dom.spec.whatwg.org/#concept-traversal-root
55
    JS::NonnullGCPtr<Node> m_root;
56
57
    struct NodePointer {
58
        JS::NonnullGCPtr<Node> node;
59
60
        // https://dom.spec.whatwg.org/#nodeiterator-pointer-before-reference
61
        bool is_before_node { true };
62
    };
63
64
    void run_pre_removing_steps_with_node_pointer(Node&, NodePointer&);
65
66
    // https://dom.spec.whatwg.org/#nodeiterator-reference
67
    NodePointer m_reference;
68
69
    // While traversal is ongoing, we keep track of the current node pointer.
70
    // This allows us to adjust it during traversal if calling the filter ends up removing the node from the DOM.
71
    Optional<NodePointer> m_traversal_pointer;
72
73
    // https://dom.spec.whatwg.org/#concept-traversal-whattoshow
74
    unsigned m_what_to_show { 0 };
75
76
    // https://dom.spec.whatwg.org/#concept-traversal-filter
77
    JS::GCPtr<NodeFilter> m_filter;
78
79
    // https://dom.spec.whatwg.org/#concept-traversal-active
80
    bool m_active { false };
81
};
82
83
}