docs
Loading...
Searching...
No Matches
Node.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// X11's headers define None as a macro, which would break the None enumerators.
7#pragma push_macro("None")
8#undef None
9
10#include <Ultralight/CAPI/CAPI_DOMNode.h>
12#include <Ultralight/dom/detail/Properties.h>
13
14#include <array>
15#include <cstddef>
16#include <string>
17#include <string_view>
18#include <type_traits>
19#include <utility>
20
21namespace ultralight {
22namespace dom {
23
24class Document;
26class Element;
27class Node;
28class NodeList;
29
30/// \cond INTERNAL
31namespace detail {
32
33// An argument the variadic insertion methods (append(), before(), ...) accept: a handle to any
34// node (an Element or a DocumentFragment too), or text as anything that converts to
35// std::string_view.
36template <typename T>
37concept NodeOrString = std::is_convertible_v<T&&, const Node&>
38 || (std::is_convertible_v<T&&, std::string_view>
39 && !std::is_same_v<std::remove_cvref_t<T>, std::nullptr_t>);
40
41inline ULDOMNodeOrString NodeItem(const Node& node);
42
43template <typename T>
44ULDOMNodeOrString NodeOrStringItem(T&& item) {
45 if constexpr (std::is_convertible_v<T&&, const Node&>) {
46 return NodeItem(item);
47 } else {
48 std::string_view text = item;
49 return { nullptr, text.data() ? text.data() : "", text.size() };
50 }
51}
52
53// The C items for an argument pack. They borrow from the arguments, which outlive the call they
54// are passed to (temporaries last until the end of the caller's full-expression).
55template <typename... T>
56std::array<ULDOMNodeOrString, sizeof...(T)> NodeOrStringItems(T&&... items) {
57 return { NodeOrStringItem(std::forward<T>(items))... };
58}
59
60} // namespace detail
61/// \endcond
62
63///
64/// The kinds of DOM node (nodeType), with the web's numeric values.
65///
66enum class NodeType : uint8_t {
67 None = 0, ///< No node (an empty handle or one whose page is gone).
68 Element = 1, ///< An element (eg, `<div>`).
69 Attribute = 2, ///< An attribute node.
70 Text = 3, ///< A text node.
71 CDATASection = 4, ///< A CDATA section (XML documents).
72 ProcessingInstruction = 7, ///< A processing instruction (XML documents).
73 Comment = 8, ///< A comment (`<!-- -->`).
74 Document = 9, ///< A document (never returned as a Node).
75 DocumentType = 10, ///< A doctype (eg, `<!DOCTYPE html>`).
76 DocumentFragment = 11, ///< A document fragment.
77};
78
79///
80/// A reference to an item in the DOM tree.
81///
82/// While query methods like Document::querySelector() find only elements, Node represents any item
83/// in the document hierarchy.
84///
85/// Use Node to walk tree relationships when your application needs to reach content that element
86/// queries skip.
87///
88/// Consider an element containing both text and markup:
89///
90/// ```html
91/// <p id="greeting">Howdy <b>world</b>!</p>
92/// ```
93///
94/// You can step from the element to its first child and narrow the next sibling to an element:
95///
96/// ```
97/// dom::Element greeting = document.getElementById("greeting");
98///
99/// dom::Node first = greeting.firstChild();
100/// Log(first.nodeName()); // "#text" (the "Howdy " text)
101///
102/// dom::Element bold = first.nextSibling().AsElement();
103/// Log(bold.tagName()); // "B"
104/// ```
105///
106/// ## Kinds of Nodes
107///
108/// Both dom::Element and dom::DocumentFragment are Node%s. Unlike on the web, dom::Document is a
109/// separate type and doesn't inherit from Node (call ownerDocument() on any node to reach its
110/// document).
111///
112/// nodeType() returns the kind of node, and nodeName() returns its name. Call AsElement() to narrow
113/// a node to a dom::Element (it returns an empty handle for text and comments).
114///
115/// Traversal methods differ in which node kinds they visit:
116///
117/// - **Node methods visit every child.** Calls like firstChild() and nextSibling() return text and
118/// comments alongside elements.
119/// - **Element methods visit elements only.** Calls on dom::Element like
120/// Element::firstElementChild() and Element::nextElementSibling() skip text and comments.
121///
122/// Like other DOM handles, a Node is always Valid, Empty, or Gone (see dom::Element).
123///
124/// ## Text and Comment Nodes
125///
126/// You can create standalone text and comment nodes on the document using
127/// Document::createTextNode() and Document::createComment(). Passing strings to insertion methods
128/// like Element::append(), Element::prepend(), or before() creates text nodes automatically
129/// (strings are never parsed as markup).
130///
131/// Assigning to nodeValue updates a text node in place, leaving sibling nodes untouched (unlike
132/// assigning to textContent on the parent):
133///
134/// ```
135/// dom::Element scoreboard = document.getElementById("score");
136/// dom::Node points = document.createTextNode("0");
137/// scoreboard.append("Score: ", points); // the string becomes a text node too
138///
139/// points.nodeValue = "42"; // changes only that text node
140/// ```
141///
142/// @note Whitespace between HTML tags becomes a text node (firstElementChild() skips it).
143///
144/// @see dom::Element, dom::DocumentFragment, dom::NodeList, dom::Document::createTextNode(),
145/// dom::Document::createComment()
146///
147class Node {
148 public:
149 ///
150 /// The text of a text or comment node (nodeValue). Assign to replace it.
151 ///
152 /// Other kinds of node (eg, elements) read as an empty string and ignore writes.
153 ///
154 detail::NodeStringProp<detail::NodeValueTag> nodeValue;
155
156 ///
157 /// The text of this node and all its descendants (textContent).
158 ///
159 /// Assigning to an element replaces its children with the text (an empty string removes them).
160 ///
161 detail::NodeStringProp<detail::NodeTextContentTag> textContent;
162
163 ///
164 /// Internal storage (not part of the API). Use raw() to get the C handle.
165 ///
166 detail::NodeStorage detail_;
167
168 ///
169 /// Create an empty Node.
170 ///
171 Node() {}
172
173 ///
174 /// Copy constructor (both handles refer to the same node).
175 ///
176 /// @param other The Node to copy.
177 ///
178 Node(const Node& other)
179 : detail_ { other.detail_.handle ? ulCreateDOMNodeRef(other.detail_.handle)
180 : nullptr } {}
181
182 ///
183 /// Move constructor (`other` becomes empty).
184 ///
185 /// @param other The Node to move from.
186 ///
187 Node(Node&& other) noexcept : detail_ { other.detail_.handle } {
188 other.detail_.handle = nullptr;
189 }
190
191 ///
192 /// Assignment (copies or moves).
193 ///
194 /// @param other The Node to assign from.
195 ///
196 /// @return Returns this Node.
197 ///
198 Node& operator=(Node other) noexcept {
199 std::swap(detail_.handle, other.detail_.handle);
200 return *this;
201 }
202
203 ///
204 /// Destroy this handle (the node itself isn't affected).
205 ///
206 ~Node() { ulDestroyDOMNode(detail_.handle); }
207
208 ///
209 /// Whether or not this Node is valid (see IsAlive()).
210 ///
211 explicit operator bool() const { return IsAlive(); }
212
213 ///
214 /// Whether or not this Node is empty (it holds no handle).
215 ///
216 bool IsEmpty() const { return detail_.handle == nullptr; }
217
218 ///
219 /// Whether or not this Node is valid (it isn't empty and its page is still alive).
220 ///
221 /// @note Safe to call from any thread.
222 ///
223 bool IsAlive() const { return detail_.handle && ulDOMNodeIsAlive(detail_.handle); }
224
225 ///
226 /// Whether or not two handles refer to the same node (isSameNode).
227 ///
228 /// @param other The handle to compare with.
229 ///
230 /// @return Returns true if both handles are valid and refer to the same node.
231 ///
232 bool IsSame(const Node& other) const {
233 return ulDOMNodeIsSame(detail_.handle, other.detail_.handle);
234 }
235
236 // --- Reads ------------------------------------------------------------------------------
237
238 ///
239 /// Get the kind of node (nodeType).
240 ///
241 /// @return Returns the kind of node (NodeType::None for an empty Node or one whose page is
242 /// gone).
243 ///
245 return static_cast<NodeType>(ulDOMNodeGetNodeType(detail_.handle));
246 }
247
248 ///
249 /// Get the node's name (nodeName).
250 ///
251 /// @return Returns the tag name for an element (uppercase for HTML, eg, `DIV`), `#text` for a
252 /// text node, or `#comment` for a comment.
253 ///
254 std::string nodeName() const {
255 return detail::TakeString(ulDOMNodeGetNodeName(detail_.handle));
256 }
257
258 // --- Traversal --------------------------------------------------------------------------
259
260 ///
261 /// Get the node's parent (parentNode).
262 ///
263 /// @return Returns the parent node (empty if the node has no parent or its parent is the
264 /// document).
265 ///
266 Node parentNode() const { return Node(ulDOMNodeGetParentNode(detail_.handle)); }
267
268 ///
269 /// Get the node's parent element (parentElement).
270 ///
271 /// @return Returns the parent element (empty if the parent isn't an element).
272 ///
273 Element parentElement() const;
274
275 ///
276 /// Get the node's first child of any kind (firstChild).
277 ///
278 /// @return Returns the first child (empty if there's none).
279 ///
280 Node firstChild() const { return Node(ulDOMNodeGetFirstChild(detail_.handle)); }
281
282 ///
283 /// Get the node's last child of any kind (lastChild).
284 ///
285 /// @return Returns the last child (empty if there's none).
286 ///
287 Node lastChild() const { return Node(ulDOMNodeGetLastChild(detail_.handle)); }
288
289 ///
290 /// Get the node's previous sibling of any kind (previousSibling).
291 ///
292 /// @return Returns the previous sibling (empty if there's none).
293 ///
295 return Node(ulDOMNodeGetPreviousSibling(detail_.handle));
296 }
297
298 ///
299 /// Get the node's next sibling of any kind (nextSibling).
300 ///
301 /// @return Returns the next sibling (empty if there's none).
302 ///
303 Node nextSibling() const { return Node(ulDOMNodeGetNextSibling(detail_.handle)); }
304
305 ///
306 /// Get the node's children of every kind in order (childNodes).
307 ///
308 /// This is defined in `<Ultralight/dom/NodeList.h>`. Include that header (or
309 /// `<Ultralight/DOM.h>`) to call it.
310 ///
311 /// @return Returns the children, including text and comment nodes (an empty list if there are
312 /// none).
313 ///
314 /// @note The list is a snapshot, where the web's childNodes is live. Call this again to see
315 /// later changes.
316 ///
317 NodeList childNodes() const;
318
319 ///
320 /// Whether or not the node has any children (hasChildNodes).
321 ///
322 /// @return Returns true if the node has at least one child of any kind.
323 ///
324 bool hasChildNodes() const { return ulDOMNodeHasChildNodes(detail_.handle); }
325
326 ///
327 /// Whether or not the node is in its document (isConnected).
328 ///
329 /// A node you just created, or one you removed, isn't connected until you insert it into the
330 /// page.
331 ///
332 /// @return Returns true if the node is in the document (false for an empty Node or one whose
333 /// page is gone).
334 ///
335 bool isConnected() const { return ulDOMNodeIsConnected(detail_.handle); }
336
337 ///
338 /// Get the document this node belongs to (ownerDocument).
339 ///
340 /// @return Returns the document of the page this handle came from.
341 ///
342 Document ownerDocument() const;
343
344 ///
345 /// Get this node as an Element.
346 ///
347 /// @return Returns an Element for the same node (empty if the node isn't an element).
348 ///
349 Element AsElement() const;
350
351 ///
352 /// Get this node as a DocumentFragment.
353 ///
354 /// This is defined in `<Ultralight/dom/DocumentFragment.h>`. Include that header (or
355 /// `<Ultralight/DOM.h>`) to call it.
356 ///
357 /// @return Returns a DocumentFragment for the same node (empty if the node isn't a document
358 /// fragment).
359 ///
361
362 // --- Tree -------------------------------------------------------------------------------
363
364 ///
365 /// Insert nodes and strings just before this node, in its parent (before).
366 ///
367 /// Each string is inserted as a new text node (it's never parsed as markup). This does nothing
368 /// if the node has no parent.
369 ///
370 /// @param nodes The nodes and strings to insert, in order. A node that's already in a
371 /// document moves (even if it's one of this node's siblings).
372 ///
373 /// @note With more than one argument, the nodes leave their old positions before the insertion
374 /// is checked (like the web), so a call that fails can leave them out of the page.
375 ///
376 template <typename... T>
377 requires((detail::NodeOrString<T> && ...))
378 void before(T&&... nodes) const {
379 auto items = detail::NodeOrStringItems(std::forward<T>(nodes)...);
380 ulDOMNodeBefore(detail_.handle, items.data(), items.size(), nullptr);
381 }
382
383 ///
384 /// Same as before(), but returns a Result with the reason for a failure (eg, a
385 /// HierarchyRequestError for a cycle).
386 ///
387 /// dom::Checked comes first here, before the nodes (`node.before(dom::Checked, a, "b")`).
388 ///
389 /// @return Returns success (including when this node has no parent). Fails with a
390 /// HierarchyRequestError if one of the nodes can't go there (eg, it's this node's
391 /// parent or one of its ancestors).
392 ///
393 template <typename... T>
394 requires((detail::NodeOrString<T> && ...))
395 [[nodiscard]] Result<void> before(Checked_t, T&&... nodes) const {
396 auto items = detail::NodeOrStringItems(std::forward<T>(nodes)...);
397 if (IsEmpty() || detail::HasEmptyItem(items))
398 return detail::EmptyHandleError();
399 detail::ErrorScope error;
400 if (ulDOMNodeBefore(detail_.handle, items.data(), items.size(), error.out()))
401 return {};
402 return Unexpected<Error>(error.TakeError());
403 }
404
405 ///
406 /// Insert nodes and strings just after this node, in its parent (after).
407 ///
408 /// Each string is inserted as a new text node (it's never parsed as markup). This does nothing
409 /// if the node has no parent.
410 ///
411 /// @param nodes The nodes and strings to insert, in order. A node that's already in a
412 /// document moves (even if it's one of this node's siblings).
413 ///
414 /// @note With more than one argument, the nodes leave their old positions before the insertion
415 /// is checked (like the web), so a call that fails can leave them out of the page.
416 ///
417 template <typename... T>
418 requires((detail::NodeOrString<T> && ...))
419 void after(T&&... nodes) const {
420 auto items = detail::NodeOrStringItems(std::forward<T>(nodes)...);
421 ulDOMNodeAfter(detail_.handle, items.data(), items.size(), nullptr);
422 }
423
424 ///
425 /// Same as after(), but returns a Result with the reason for a failure (eg, a
426 /// HierarchyRequestError for a cycle).
427 ///
428 /// dom::Checked comes first here, before the nodes (`node.after(dom::Checked, a, "b")`).
429 ///
430 /// @return Returns success (including when this node has no parent). Fails with a
431 /// HierarchyRequestError if one of the nodes can't go there (eg, it's this node's
432 /// parent or one of its ancestors).
433 ///
434 template <typename... T>
435 requires((detail::NodeOrString<T> && ...))
436 [[nodiscard]] Result<void> after(Checked_t, T&&... nodes) const {
437 auto items = detail::NodeOrStringItems(std::forward<T>(nodes)...);
438 if (IsEmpty() || detail::HasEmptyItem(items))
439 return detail::EmptyHandleError();
440 detail::ErrorScope error;
441 if (ulDOMNodeAfter(detail_.handle, items.data(), items.size(), error.out()))
442 return {};
443 return Unexpected<Error>(error.TakeError());
444 }
445
446 ///
447 /// Replace this node with nodes and strings, in its parent (replaceWith).
448 ///
449 /// Each string is inserted as a new text node (it's never parsed as markup). With no arguments,
450 /// this removes the node. This does nothing if the node has no parent. This handle still
451 /// refers to the removed node afterward.
452 ///
453 /// @param nodes The nodes and strings to put in its place, in order. A node that's already in
454 /// a document moves (even if it's one of this node's siblings).
455 ///
456 /// @note With more than one argument, the nodes leave their old positions before the insertion
457 /// is checked (like the web), so a call that fails can leave them out of the page.
458 ///
459 template <typename... T>
460 requires((detail::NodeOrString<T> && ...))
461 void replaceWith(T&&... nodes) const {
462 auto items = detail::NodeOrStringItems(std::forward<T>(nodes)...);
463 ulDOMNodeReplaceWith(detail_.handle, items.data(), items.size(), nullptr);
464 }
465
466 ///
467 /// Same as replaceWith(), but returns a Result with the reason for a failure (eg, a
468 /// HierarchyRequestError for a cycle).
469 ///
470 /// dom::Checked comes first here, before the nodes (`node.replaceWith(dom::Checked, a, "b")`).
471 ///
472 /// @return Returns success (including when this node has no parent). Fails with a
473 /// HierarchyRequestError if one of the nodes can't go there (eg, it's this node's
474 /// parent or one of its ancestors).
475 ///
476 template <typename... T>
477 requires((detail::NodeOrString<T> && ...))
478 [[nodiscard]] Result<void> replaceWith(Checked_t, T&&... nodes) const {
479 auto items = detail::NodeOrStringItems(std::forward<T>(nodes)...);
480 if (IsEmpty() || detail::HasEmptyItem(items))
481 return detail::EmptyHandleError();
482 detail::ErrorScope error;
483 if (ulDOMNodeReplaceWith(detail_.handle, items.data(), items.size(), error.out()))
484 return {};
485 return Unexpected<Error>(error.TakeError());
486 }
487
488 ///
489 /// Remove this node from its parent (remove). Does nothing if it has no parent.
490 ///
491 /// This handle still refers to the removed node, so you can insert it again.
492 ///
493 void remove() const { ulDOMNodeRemove(detail_.handle, nullptr); }
494
495 ///
496 /// Same as remove(), but returns a Result with the reason for a failure.
497 ///
498 /// @return Returns success (including when this node has no parent). It fails only when this
499 /// Node is empty or its page is gone.
500 ///
501 [[nodiscard]] Result<void> remove(Checked_t) const {
502 if (IsEmpty())
503 return detail::EmptyHandleError();
504 detail::ErrorScope error;
505 if (ulDOMNodeRemove(detail_.handle, error.out()))
506 return {};
507 return Unexpected<Error>(error.TakeError());
508 }
509
510 // --- Interop with the C API (most embedders never touch raw handles) -----------------------
511
512 ///
513 /// Wrap a C handle you own, taking ownership of it.
514 ///
515 /// @param handle A handle from the C API that you would otherwise destroy with
516 /// ulDestroyDOMNode() (NULL gives an empty Node).
517 ///
518 /// @return Returns a Node that destroys `handle` when it's done.
519 ///
520 static Node Adopt(ULDOMNode handle) { return Node(handle); }
521
522 ///
523 /// Wrap a C handle the library owns (eg, a callback argument), adding a reference.
524 ///
525 /// @param handle The borrowed handle (NULL gives an empty Node).
526 ///
527 /// @return Returns a Node with its own reference, so you can keep it after the callback.
528 ///
529 static Node FromBorrowed(ULDOMNode handle) {
530 return Node(handle ? ulCreateDOMNodeRef(handle) : nullptr);
531 }
532
533 ///
534 /// Get the C handle, for passing to the `<Ultralight/CAPI/CAPI_DOMNode.h>` functions.
535 ///
536 /// @return Returns the handle (NULL for an empty Node). This Node still owns it, so don't
537 /// destroy it.
538 ///
539 ULDOMNode raw() const { return detail_.handle; }
540
541 ///
542 /// Give up ownership of the C handle and return it. This Node becomes empty.
543 ///
544 /// @return Returns the handle. You must call ulDestroyDOMNode() when finished.
545 ///
546 ULDOMNode LeakRef() {
547 ULDOMNode handle = detail_.handle;
548 detail_.handle = nullptr;
549 return handle;
550 }
551
552 protected:
553 explicit Node(ULDOMNode handle) : detail_ { handle } {}
554};
555
556// Node keeps every data member in one class, so its member offsets are well-defined
557// constants for the proxy owner recovery below (Element's own members ride clang's
558// conditional offsetof support instead; see the note after Element).
559static_assert(std::is_standard_layout_v<Node>, "Node must stay standard-layout");
560static_assert(!std::is_aggregate_v<Node>, "Node must not be an aggregate");
561
562/// \cond INTERNAL
563namespace detail {
564
565inline ULDOMNodeOrString NodeItem(const Node& node) {
566 return { node.raw(), nullptr, 0 };
567}
568
569inline ULDOMNode OwnerNodeHandle(const void* member, size_t member_offset) {
570 const Node* node = reinterpret_cast<const Node*>(
571 reinterpret_cast<const char*>(member) - member_offset);
572 return node->detail_.handle;
573}
574
575template <>
576inline size_t NodePropOffset<NodeValueTag>() {
577 return offsetof(Node, nodeValue);
578}
579template <>
580inline size_t NodePropOffset<NodeTextContentTag>() {
581 return offsetof(Node, textContent);
582}
583
584template <class Tag>
585void NodeStringProp<Tag>::operator=(std::string_view value) const {
586 Tag::Set(OwnerNodeHandle(this, NodePropOffset<Tag>()), value);
587}
588
589template <class Tag>
590void NodeStringProp<Tag>::operator+=(std::string_view suffix) const {
591 ULDOMNode h = OwnerNodeHandle(this, NodePropOffset<Tag>());
592 std::string combined = Tag::Get(h);
593 combined.append(suffix);
594 Tag::Set(h, combined);
595}
596
597template <class Tag>
598NodeStringProp<Tag>::operator std::string() const {
599 return Tag::Get(OwnerNodeHandle(this, NodePropOffset<Tag>()));
600}
601
602} // namespace detail
603/// \endcond
604
605} // namespace dom
606} // namespace ultralight
607
608#pragma pop_macro("None")
A container for assembling DOM nodes off the page.
Definition DocumentFragment.h:43
The root of a page's DOM tree in a View or frame.
Definition Document.h:106
A handle to an element on a page.
Definition Element.h:142
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
Node()
Create an empty Node.
Definition Node.h:171
Node nextSibling() const
Get the node's next sibling of any kind (nextSibling).
Definition Node.h:303
ULDOMNode LeakRef()
Give up ownership of the C handle and return it.
Definition Node.h:546
Result< void > replaceWith(Checked_t, T &&... nodes) const
Same as replaceWith(), but returns a Result with the reason for a failure (eg, a HierarchyRequestErro...
Definition Node.h:478
Node(const Node &other)
Copy constructor (both handles refer to the same node).
Definition Node.h:178
Node(Node &&other) noexcept
Move constructor (other becomes empty).
Definition Node.h:187
DocumentFragment AsFragment() const
Get this node as a DocumentFragment.
Definition DocumentFragment.h:281
Node lastChild() const
Get the node's last child of any kind (lastChild).
Definition Node.h:287
NodeList childNodes() const
Get the node's children of every kind in order (childNodes).
Definition NodeList.h:171
detail::NodeStringProp< detail::NodeTextContentTag > textContent
The text of this node and all its descendants (textContent).
Definition Node.h:161
NodeType nodeType() const
Get the kind of node (nodeType).
Definition Node.h:244
void before(T &&... nodes) const
Insert nodes and strings just before this node, in its parent (before).
Definition Node.h:378
ULDOMNode raw() const
Get the C handle, for passing to the <Ultralight/CAPI/CAPI_DOMNode.h> functions.
Definition Node.h:539
Document ownerDocument() const
Get the document this node belongs to (ownerDocument).
Definition Document.h:1030
static Node Adopt(ULDOMNode handle)
Wrap a C handle you own, taking ownership of it.
Definition Node.h:520
~Node()
Destroy this handle (the node itself isn't affected).
Definition Node.h:206
bool isConnected() const
Whether or not the node is in its document (isConnected).
Definition Node.h:335
void remove() const
Remove this node from its parent (remove).
Definition Node.h:493
Node parentNode() const
Get the node's parent (parentNode).
Definition Node.h:266
Node & operator=(Node other) noexcept
Assignment (copies or moves).
Definition Node.h:198
bool IsEmpty() const
Whether or not this Node is empty (it holds no handle).
Definition Node.h:216
bool IsAlive() const
Whether or not this Node is valid (it isn't empty and its page is still alive).
Definition Node.h:223
Node(ULDOMNode handle)
Definition Node.h:553
detail::NodeStringProp< detail::NodeValueTag > nodeValue
The text of a text or comment node (nodeValue).
Definition Node.h:154
bool IsSame(const Node &other) const
Whether or not two handles refer to the same node (isSameNode).
Definition Node.h:232
static Node FromBorrowed(ULDOMNode handle)
Wrap a C handle the library owns (eg, a callback argument), adding a reference.
Definition Node.h:529
Node firstChild() const
Get the node's first child of any kind (firstChild).
Definition Node.h:280
Element parentElement() const
Get the node's parent element (parentElement).
Definition Element.h:3448
bool hasChildNodes() const
Whether or not the node has any children (hasChildNodes).
Definition Node.h:324
Result< void > remove(Checked_t) const
Same as remove(), but returns a Result with the reason for a failure.
Definition Node.h:501
Node previousSibling() const
Get the node's previous sibling of any kind (previousSibling).
Definition Node.h:294
Element AsElement() const
Get this node as an Element.
Definition Element.h:3452
Result< void > before(Checked_t, T &&... nodes) const
Same as before(), but returns a Result with the reason for a failure (eg, a HierarchyRequestError for...
Definition Node.h:395
void replaceWith(T &&... nodes) const
Replace this node with nodes and strings, in its parent (replaceWith).
Definition Node.h:461
void after(T &&... nodes) const
Insert nodes and strings just after this node, in its parent (after).
Definition Node.h:419
std::string nodeName() const
Get the node's name (nodeName).
Definition Node.h:254
Result< void > after(Checked_t, T &&... nodes) const
Same as after(), but returns a Result with the reason for a failure (eg, a HierarchyRequestError for ...
Definition Node.h:436
A fixed list of nodes of any kind (eg, the results of Node::childNodes()).
Definition NodeList.h:34
Direct C++ access to modify page elements and handle events.
NodeType
The kinds of DOM node (nodeType), with the web's numeric values.
Definition Node.h:66
@ Comment
A comment (<!-- -->).
Definition Node.h:73
@ CDATASection
A CDATA section (XML documents).
Definition Node.h:71
@ ProcessingInstruction
A processing instruction (XML documents).
Definition Node.h:72
@ Text
A text node.
Definition Node.h:70
@ DocumentType
A doctype (eg, <!DOCTYPE html>).
Definition Node.h:75
@ Attribute
An attribute node.
Definition Node.h:69
Expected< T, Error > Result
The result of a DOM operation that can fail (either a T or a dom::Error).
Definition Error.h:277
Root namespace for every public Ultralight type, function, and enumeration.
@ None
Definition Anchor.h:36
The type of dom::Checked.
Definition Error.h:282