docs
Loading...
Searching...
No Matches
NodeList.h
Go to the documentation of this file.
1///
2/// Copyright (C) 2026 Ultralight, Inc. All rights reserved.
3/// A license is required for commercial use. https://ultralig.ht
4///
5#pragma once
6#include <Ultralight/CAPI/CAPI_DOMNode.h>
8
9#include <cstddef>
10#include <utility>
11
12namespace ultralight {
13namespace dom {
14
15///
16/// A fixed list of nodes of any kind (eg, the results of Node::childNodes()).
17///
18/// The list is a snapshot, where the web's childNodes is live. Later changes to the page never
19/// add, remove, or reorder its entries, and a node removed from the page stays in the list and
20/// stays valid. Call childNodes() again when you need the current children.
21///
22/// ```
23/// for (dom::Node child : list.childNodes()) {
24/// if (child.nodeType() == dom::NodeType::Text)
25/// child.remove();
26/// }
27/// ```
28///
29/// A NodeList can be moved but not copied.
30///
31/// The list doesn't keep its page alive. Once the page goes away, the list keeps its length but
32/// its nodes fail safely (see dom::Element).
33///
34class NodeList {
35 public:
36 ///
37 /// Create an empty NodeList (length() is 0).
38 ///
39 NodeList() = default;
40
41 NodeList(const NodeList&) = delete;
42 NodeList& operator=(const NodeList&) = delete;
43
44 ///
45 /// Move constructor (`other` becomes empty).
46 ///
47 /// @param other The NodeList to move from.
48 ///
49 NodeList(NodeList&& other) noexcept : handle_(other.handle_) { other.handle_ = nullptr; }
50
51 ///
52 /// Move assignment (destroys the current list and `other` becomes empty).
53 ///
54 /// @param other The NodeList to move from.
55 ///
56 /// @return Returns this NodeList.
57 ///
58 NodeList& operator=(NodeList&& other) noexcept {
59 if (this != &other) {
60 ulDestroyDOMNodeList(handle_);
61 handle_ = other.handle_;
62 other.handle_ = nullptr;
63 }
64 return *this;
65 }
66
67 ///
68 /// Destroy the list (nodes you got from it aren't affected).
69 ///
70 ~NodeList() { ulDestroyDOMNodeList(handle_); }
71
72 ///
73 /// Get the number of nodes in the list (length).
74 ///
75 /// @return Returns the number of nodes (0 for an empty NodeList).
76 ///
77 size_t length() const { return ulDOMNodeListGetLength(handle_); }
78
79 ///
80 /// Get the number of nodes in the list (the same as length()).
81 ///
82 /// @return Returns the number of nodes (0 for an empty NodeList).
83 ///
84 size_t size() const { return length(); }
85
86 ///
87 /// Whether or not the list has no nodes (length() is 0).
88 ///
89 bool empty() const { return length() == 0; }
90
91 ///
92 /// Get the node at an index (item).
93 ///
94 /// @param index The zero-based index.
95 ///
96 /// @return Returns the node (empty if `index` is out of range).
97 ///
98 Node item(size_t index) const { return Node::Adopt(ulDOMNodeListGetNode(handle_, index)); }
99
100 ///
101 /// Get the node at an index (the same as item()).
102 ///
103 /// @param index The zero-based index.
104 ///
105 /// @return Returns the node (empty if `index` is out of range).
106 ///
107 Node operator[](size_t index) const { return item(index); }
108
109 ///
110 /// A forward iterator over the list's nodes, so range-for works
111 /// (`for (dom::Node node : list)`).
112 ///
113 class iterator {
114 public:
115 iterator(const NodeList* list, size_t index) : list_(list), index_(index) {}
116
117 Node operator*() const { return list_->item(index_); }
119 ++index_;
120 return *this;
121 }
122 bool operator!=(const iterator& other) const { return index_ != other.index_; }
123 bool operator==(const iterator& other) const { return index_ == other.index_; }
124
125 private:
126 const NodeList* list_;
127 size_t index_;
128 };
129
130 iterator begin() const { return iterator(this, 0); }
131 iterator end() const { return iterator(this, length()); }
132
133 // --- Interop with the C API (most embedders never touch raw handles) -------------------
134
135 ///
136 /// Wrap a C handle you own, taking ownership of it.
137 ///
138 /// @param handle A handle from the C API that you would otherwise destroy with
139 /// ulDestroyDOMNodeList() (NULL gives an empty NodeList).
140 ///
141 /// @return Returns a NodeList that destroys `handle` when it's done.
142 ///
143 static NodeList Adopt(ULDOMNodeList handle) { return NodeList(handle); }
144
145 ///
146 /// Get the C handle, for passing to the `<Ultralight/CAPI/CAPI_DOMNode.h>` functions.
147 ///
148 /// @return Returns the handle (NULL for an empty NodeList). This NodeList still owns it, so
149 /// don't destroy it.
150 ///
151 ULDOMNodeList raw() const { return handle_; }
152
153 ///
154 /// Give up ownership of the C handle and return it. This NodeList becomes empty.
155 ///
156 /// @return Returns the handle. You must call ulDestroyDOMNodeList() when finished.
157 ///
158 ULDOMNodeList LeakRef() {
159 ULDOMNodeList handle = handle_;
160 handle_ = nullptr;
161 return handle;
162 }
163
164 protected:
165 explicit NodeList(ULDOMNodeList handle) : handle_(handle) {}
166
167 private:
168 ULDOMNodeList handle_ = nullptr;
169};
170
172 return NodeList::Adopt(ulDOMNodeGetChildNodes(detail_.handle));
173}
174
175} // namespace dom
176} // namespace ultralight
A reference to an item in the DOM tree.
Definition Node.h:147
detail::NodeStorage detail_
Internal storage (not part of the API).
Definition Node.h:166
NodeList childNodes() const
Get the node's children of every kind in order (childNodes).
Definition NodeList.h:171
static Node Adopt(ULDOMNode handle)
Wrap a C handle you own, taking ownership of it.
Definition Node.h:520
A forward iterator over the list's nodes, so range-for works (for (dom::Node node : list)).
Definition NodeList.h:113
iterator(const NodeList *list, size_t index)
Definition NodeList.h:115
bool operator!=(const iterator &other) const
Definition NodeList.h:122
bool operator==(const iterator &other) const
Definition NodeList.h:123
Node operator*() const
Definition NodeList.h:117
iterator & operator++()
Definition NodeList.h:118
A fixed list of nodes of any kind (eg, the results of Node::childNodes()).
Definition NodeList.h:34
NodeList & operator=(const NodeList &)=delete
iterator begin() const
Definition NodeList.h:130
ULDOMNodeList raw() const
Get the C handle, for passing to the <Ultralight/CAPI/CAPI_DOMNode.h> functions.
Definition NodeList.h:151
size_t size() const
Get the number of nodes in the list (the same as length()).
Definition NodeList.h:84
NodeList()=default
Create an empty NodeList (length() is 0).
NodeList(const NodeList &)=delete
Node item(size_t index) const
Get the node at an index (item).
Definition NodeList.h:98
bool empty() const
Whether or not the list has no nodes (length() is 0).
Definition NodeList.h:89
iterator end() const
Definition NodeList.h:131
NodeList(ULDOMNodeList handle)
Definition NodeList.h:165
size_t length() const
Get the number of nodes in the list (length).
Definition NodeList.h:77
Node operator[](size_t index) const
Get the node at an index (the same as item()).
Definition NodeList.h:107
NodeList(NodeList &&other) noexcept
Move constructor (other becomes empty).
Definition NodeList.h:49
static NodeList Adopt(ULDOMNodeList handle)
Wrap a C handle you own, taking ownership of it.
Definition NodeList.h:143
~NodeList()
Destroy the list (nodes you got from it aren't affected).
Definition NodeList.h:70
ULDOMNodeList LeakRef()
Give up ownership of the C handle and return it.
Definition NodeList.h:158
NodeList & operator=(NodeList &&other) noexcept
Move assignment (destroys the current list and other becomes empty).
Definition NodeList.h:58
Direct C++ access to modify page elements and handle events.
Root namespace for every public Ultralight type, function, and enumeration.