docs
Loading...
Searching...
No Matches
ultralight::dom

Overview

Direct C++ access to modify page elements and handle events.

#include <Ultralight/DOM.h>

Note
This API is a preview and may still change after 2.0.

The DOM API connects your application to the HTML pages a View loads, letting native code update the user interface and respond to user input.

Names and behavior follow the web's DOM, so page script ports over nearly line for line.

This example configures a DOM-ready hook and a click listener on a View before loading a page:

page.OnDOMReady([](dom::Document document) {
auto status = document.getElementById("status");
status.textContent = "Connected";
status.classList.add("online");
});
page.On("#save", "click", [](dom::Element button) {
button.textContent = "Saved";
});
if (page.AttachTo(view.get()))
view->LoadURL("file:///app.html");
The root of a page's DOM tree in a View or frame.
Definition Document.h:106
Element getElementById(std::string_view id) const
Find the element with a certain id (getElementById).
Definition Document.h:190
A handle to an element on a page.
Definition Element.h:142
detail::StringProp< detail::TextContentTag > textContent
The text of this element and all its descendants (textContent).
Definition Element.h:216
A set of DOM event listeners and lifecycle hooks that persists across page navigations.
Definition Triggers.h:253
bool AttachTo(View *view, const AttachOptions &options={})
Attach this set to a View.
Definition Triggers.h:472
void OnDOMReady(F &&callback)
Add a hook that runs on each page that gets the set, once its document has finished parsing.
Definition Triggers.h:421
bool On(std::string_view selector, std::string_view type, F &&callback, EventListenerFlags flags=EventListenerFlags::None)
Add a listener for events on elements matching a CSS selector.
Definition Triggers.h:338

Accessing Page Content

You can interact with a View through persistent listeners or a direct document handle:

Where to Start

Recommended types and headers for common tasks:

Task Starting Point
Finding and changing elements dom::Document, dom::Element
Listening for events dom::Element::addEventListener()
Viewport and window events dom::Window
Inspecting call failures dom::Error
Passing elements to JavaScript <Ultralight/dom/JSInterop.h>

Rules for All DOM Types

Every DOM class follows these common conventions:

  • Call DOM operations on the Renderer's thread. To work with the DOM from another thread, post tasks using Renderer::PostTask(). Copying, moving, and destroying handles is safe on any thread.
  • A handle never keeps its page alive. Once a page navigates away, calls on its handles fail safely (for handle states, see dom::Element).
  • The API never throws C++ exceptions. A call that fails returns an empty value, or a dom::Result holding a dom::Error if you pass dom::Checked.
  • Callbacks that throw are caught and logged.
  • A const handle can still modify its node. Constness applies to the handle itself rather than the page element, so you can still assign to properties and insert child nodes.
  • Counts and indices use size_t. Where web standards return -1 or null for a missing position, methods return std::optional<size_t> holding std::nullopt.
Note
The DOM API works even with JavaScript disabled (ViewConfig::enable_javascript = false).
See also
dom::Document, dom::Element, dom::Triggers, LoadListener::OnDOMReady()

Namespaces

namespace  data
 Data-binding API that connects native C++ data to HTML and CSS markup.

Classes

class  AbortController
 A controller that removes a group of DOM event listeners together. More...
class  AbortSignal
 A signal that removes event listeners when an AbortController aborts. More...
struct  AddEventListenerOptions
 Options for adding an event listener, like the web's options object for addEventListener(). More...
struct  AttachOptions
 Options for Triggers::AttachTo(). More...
struct  Checked_t
 The type of dom::Checked. More...
class  ComputedStyle
 A read-only view of an element's computed style (getComputedStyle). More...
struct  CSSPropertyName
 A CSS property name checked when your code compiles (the type of dom::css). More...
class  CssValue
 Compile-time wrapper for CSS string literals assigned to element styles. More...
class  CustomEvent
 An event with a string payload (CustomEvent). More...
class  Document
 The root of a page's DOM tree in a View or frame. More...
class  DocumentFragment
 A container for assembling DOM nodes off the page. More...
struct  DOMRect
 A rectangle in CSS pixels, relative to the viewport (DOMRect). More...
class  Element
 A handle to an element on a page. More...
class  ElementList
 A fixed list of DOM elements returned by a query or an Element::children() call. More...
class  Error
 The reason a DOM operation failed. More...
class  Event
 A page event (such as a click or key press) received by a listener callback. More...
struct  EventInit
 Options for an event you dispatch yourself (the web's EventInit). More...
class  EventListener
 A handle to a registered DOM event listener. More...
class  FocusEvent
 A focus event (FocusEvent). More...
class  HTMLAnchorElement
 An <a> element (HTMLAnchorElement). More...
class  HTMLFormElement
 A <form> element (HTMLFormElement). More...
class  HTMLIFrameElement
 An <iframe> element (HTMLIFrameElement). More...
class  HTMLImageElement
 An <img> element (HTMLImageElement). More...
class  HTMLInputElement
 An <input> element (HTMLInputElement). More...
class  HTMLOptionElement
 An <option> element (HTMLOptionElement). More...
class  HTMLSelectElement
 A <select> element (HTMLSelectElement). More...
class  HTMLTextAreaElement
 A <textarea> element (HTMLTextAreaElement). More...
struct  InjectionRequest
 Information passed to a DOM triggers filter callback. More...
class  InputEvent
 An edit to an editable element (InputEvent). More...
class  KeyboardEvent
 A keyboard event (KeyboardEvent). More...
class  MouseEvent
 A mouse event (MouseEvent). More...
class  Node
 A reference to an item in the DOM tree. More...
class  NodeList
 A fixed list of nodes of any kind (eg, the results of Node::childNodes()). More...
class  Range
 A handle to a live range (a span of a page between two boundary points). More...
class  Selection
 A handle to the active user selection or caret in a document. More...
struct  StyleValue
 A numeric CSS value and its unit. More...
class  SubmitEvent
 A form submission event (SubmitEvent). More...
class  Triggers
 A set of DOM event listeners and lifecycle hooks that persists across page navigations. More...
struct  ValidityState
 The ways a form control fails its constraints (ValidityState). More...
class  WheelEvent
 A wheel event (WheelEvent). More...
class  Window
 The viewport of a DOM document. More...

Concepts

concept  LockableHolder
 Whether or not the DOM API can hold an object through H (ignoring const and references), ie.

Typedefs

template<typename T, typename E = Error>
using Expected = ultralight::detail::Expected<T, E>
 A value of type T or an error of type E (like std::expected).
template<typename T>
using Result = Expected<T, Error>
 The result of a DOM operation that can fail (either a T or a dom::Error).

Enumerations

enum class  SelectionDirection : uint8_t { None , Forward , Backward }
 The direction of a text control's selection (selectionDirection). More...
enum class  SelectionMode : uint8_t { Preserve , Select , Start , End }
 Where the selection goes after HTMLInputElement::setRangeText() replaces text (selectMode). More...
enum class  ErrorType : unsigned {
  None = 0 , Unknown , SyntaxError , InvalidCharacterError ,
  HierarchyRequestError , NotFoundError , NoModificationAllowedError , InvalidStateError ,
  IndexSizeError , NotSupportedError , TypeError , InvalidNodeTypeError ,
  WrongDocumentError
}
 The kinds of DOM exception a dom::Error can hold (the web's DOMException names, plus TypeError). More...
enum class  EventListenerFlags : unsigned {
  None = 0 , Capture = 1u << 0 , Once = 1u << 1 , Passive = 1u << 2 ,
  NotPassive = 1u << 3
}
 Options for adding an event listener, as flags (addEventListener() and On()). More...
enum class  NodeType : uint8_t {
  None = 0 , Element = 1 , Attribute = 2 , Text = 3 ,
  CDATASection = 4 , ProcessingInstruction = 7 , Comment = 8 , Document = 9 ,
  DocumentType = 10 , DocumentFragment = 11
}
 The kinds of DOM node (nodeType), with the web's numeric values. More...
enum class  StyleUnit : unsigned {
  Number = 0 , Percent , Px , Em ,
  Rem , Vw , Vh , Deg ,
  Ms , S , Empty
}
 The unit of a StyleValue (the same values as the C API's ULDOMStyleUnit). More...
enum class  AttachFlags : unsigned { None = 0 , AllFrames = 1u << 1 }
 The flags for Triggers::AttachTo() (the typed form of ULDOMTriggersAttachFlags). More...

Functions

ComputedStyle getComputedStyle (const Element &element)
 Get an element's computed style (getComputedStyle).
template<typename T>
requires std::is_default_constructible_v<T>
T OrEmpty (Result< T > result)
 Get a Result's value, or a default-constructed T if it holds an error.
constexpr EventListenerFlags operator| (EventListenerFlags a, EventListenerFlags b)
constexpr EventListenerFlags & operator|= (EventListenerFlags &a, EventListenerFlags b)
js::Value ToJS (const js::Context &context, const Element &element)
 Get an element's JavaScript object (the same object the page's scripts see for it).
Element FromJS (const js::Value &value)
 Get the element a JavaScript value refers to (the inverse of ToJS()).
js::Context GetJSContext (const Document &document)
 Get the JavaScript context of a document (the context its page's scripts run in).
constexpr AttachFlags operator| (AttachFlags a, AttachFlags b)
constexpr AttachFlags & operator|= (AttachFlags &a, AttachFlags b)
template<typename F>
void SetInjectionFilter (View *view, F &&filter)
 Set a View's DOM triggers filter with a C++ callable (the typed form of View::SetDOMTriggersInjectionFilter()).
void ClearInjectionFilter (View *view)
 Remove a View's DOM triggers filter, so the origin rules alone decide which pages get each set.

Variables

template<detail::FixedString Name>
constexpr CSSPropertyName< Name > css {}
 A CSS property name checked when your code compiles.
constexpr Checked_t Checked {}
 Pass to a DOM call to get a dom::Result holding the reason for a failure instead of an empty value.
constexpr EventListenerFlags Capture = EventListenerFlags::Capture
 Receive the event in the capture phase (shorthand for EventListenerFlags::Capture).
constexpr EventListenerFlags Once = EventListenerFlags::Once
 Remove the listener after the first event it receives (shorthand for EventListenerFlags::Once).
constexpr EventListenerFlags Passive = EventListenerFlags::Passive
 Make the listener passive (shorthand for EventListenerFlags::Passive).
constexpr EventListenerFlags NotPassive = EventListenerFlags::NotPassive
 Make the listener not passive (shorthand for EventListenerFlags::NotPassive).
constexpr AttachFlags AllFrames = AttachFlags::AllFrames
 Add the listeners to subframes too (shorthand for AttachFlags::AllFrames).

Typedef Documentation

◆ Expected

template<typename T, typename E = Error>
using Expected = ultralight::detail::Expected<T, E>

A value of type T or an error of type E (like std::expected).

Warning
Don't call value() when has_value() is false. That's undefined behavior, since the library never throws C++ exceptions. Check first or use value_or().

◆ Result

template<typename T>
using Result = Expected<T, Error>

The result of a DOM operation that can fail (either a T or a dom::Error).

DOM calls return one when you pass dom::Checked.

Result is dom::Expected<T, dom::Error>, the library's own type with the members of std::expected (has_value(), value(), error(), value_or(), and_then(), transform(), and the rest). It's the same type in every file of your program, whichever C++ standard each file is compiled with.

Enumeration Type Documentation

◆ AttachFlags

enum class AttachFlags : unsigned
strong

The flags for Triggers::AttachTo() (the typed form of ULDOMTriggersAttachFlags).

Enumerator
None 

Add the listeners to the main frame only.

AllFrames 

Add the listeners to subframes too.

◆ ErrorType

enum class ErrorType : unsigned
strong

The kinds of DOM exception a dom::Error can hold (the web's DOMException names, plus TypeError).

The values match ULDOMErrorCode in the C API. They stay the same across releases. Later versions may add types, so handle a value you don't know (eg, with a default case).

Enumerator
None 

Not a DOM exception (eg, a page-gone error).

Unknown 

A DOM exception with no code of its own here.

SyntaxError 

A malformed selector, or an invalid position for Element::insertAdjacentHTML() and its siblings.

InvalidCharacterError 

An invalid tag, attribute, or class name (only the C API reports it, since the typed calls that take these names have no dom::Checked form).

HierarchyRequestError 

The tree would contain a cycle, or the node can't go there (eg, text directly under the document).

NotFoundError 

A node isn't where the call needs it (eg, a reference child that isn't a child).

NoModificationAllowedError 

The target can't be changed (eg, it has no parent).

InvalidStateError 

The call isn't valid in the target's current state.

IndexSizeError 

An index or offset is out of range.

NotSupportedError 

The operation isn't supported.

TypeError 

An argument has the wrong type (eg, a submitter passed to HTMLFormElement::requestSubmit() that isn't a submit button).

InvalidNodeTypeError 

The node is the wrong kind for the call (eg, selecting a node that has no parent).

WrongDocumentError 

A node or range belongs to a different document.

◆ EventListenerFlags

enum class EventListenerFlags : unsigned
strong

Options for adding an event listener, as flags (addEventListener() and On()).

Combine them with |:

el.addEventListener("click", OnClick, dom::Once | dom::Capture);
constexpr EventListenerFlags Once
Remove the listener after the first event it receives (shorthand for EventListenerFlags::Once).
Definition EventListener.h:78
constexpr EventListenerFlags Capture
Receive the event in the capture phase (shorthand for EventListenerFlags::Capture).
Definition EventListener.h:72

Passiveness takes two flags because the web has three choices. dom::Passive makes the listener passive (its preventDefault() calls are ignored), dom::NotPassive makes it not passive, and with neither flag the page's default applies.

To add a listener with an AbortSignal, use AddEventListenerOptions instead.

Note
Wheel listeners on the window, the document, <html>, and <body> are passive by default (like the web), so pass dom::NotPassive to cancel wheel events there.
Enumerator
None 
Capture 

Receive the event in the capture phase (on its way down to the target).

Once 

Remove the listener after the first event it receives.

Passive 

Make the listener passive (its preventDefault() calls are ignored).

NotPassive 

Make the listener not passive, even where the default is passive.

◆ NodeType

enum class NodeType : uint8_t
strong

The kinds of DOM node (nodeType), with the web's numeric values.

Enumerator
None 

No node (an empty handle or one whose page is gone).

Element 

An element (eg, <div>).

Attribute 

An attribute node.

Text 

A text node.

CDATASection 

A CDATA section (XML documents).

ProcessingInstruction 

A processing instruction (XML documents).

Comment 

A comment (<!-- -->).

Document 

A document (never returned as a Node).

DocumentType 

A doctype (eg, <!DOCTYPE html>).

DocumentFragment 

A document fragment.

◆ SelectionDirection

enum class SelectionDirection : uint8_t
strong

The direction of a text control's selection (selectionDirection).

Enumerator
None 

No direction.

Forward 

The selection was made toward the end of the text.

Backward 

The selection was made toward the start of the text.

◆ SelectionMode

enum class SelectionMode : uint8_t
strong

Where the selection goes after HTMLInputElement::setRangeText() replaces text (selectMode).

Enumerator
Preserve 

Keep the selection, adjusted for the edit.

Select 

Select the inserted text.

Start 

Put the caret before the inserted text.

End 

Put the caret after the inserted text.

◆ StyleUnit

enum class StyleUnit : unsigned
strong

The unit of a StyleValue (the same values as the C API's ULDOMStyleUnit).

Enumerator
Number 

A unitless number (CSS <number>).

Percent 

%

Px 

px

Em 

em

Rem 

rem

Vw 

vw

Vh 

vh

Deg 

deg

Ms 

ms

S 

s

Empty 

No number (an Empty StyleValue; writing it removes the property).

Function Documentation

◆ ClearInjectionFilter()

void ClearInjectionFilter ( View * view)
inline

Remove a View's DOM triggers filter, so the origin rules alone decide which pages get each set.

Parameters
viewThe View to clear the filter on (nothing happens if it's nullptr).
Note
Call this on the Renderer's thread.

◆ FromJS()

Element FromJS ( const js::Value & value)
inline

Get the element a JavaScript value refers to (the inverse of ToJS()).

The element can be in any frame of the value's View, subframes included. The returned Element belongs to the element's own page (not the value's), so it stops working when that page goes away.

Parameters
valueA JavaScript value that refers to a DOM element.
Returns
Returns the element (empty if value isn't a DOM element, the element is in another View, or its document is no longer loaded in a frame).
Note
When DOM diagnostics are on, the library logs why it refused an element (see dom::Element).
See also
ToJS()

◆ getComputedStyle()

ComputedStyle getComputedStyle ( const Element & element)
inline

Get an element's computed style (getComputedStyle).

This is JavaScript's global getComputedStyle(), and the same as Window::getComputedStyle().

Parameters
elementThe element to read.
Returns
Returns a read-only view of the element's computed style (see ComputedStyle).

◆ GetJSContext()

js::Context GetJSContext ( const Document & document)
inline

Get the JavaScript context of a document (the context its page's scripts run in).

This works for the document of any frame. View::GetJSContext() only gives the main frame's context. Like any js::Context, the result stops working when the document's page goes away.

Parameters
documentThe document.
Returns
Returns the context, or an empty Context if the document's frame can't run scripts (JavaScript is disabled or the document is sandboxed).
See also
ToJS()

◆ operator|() [1/2]

AttachFlags operator| ( AttachFlags a,
AttachFlags b )
constexpr

◆ operator|() [2/2]

◆ operator|=() [1/2]

AttachFlags & operator|= ( AttachFlags & a,
AttachFlags b )
constexpr

◆ operator|=() [2/2]

EventListenerFlags & operator|= ( EventListenerFlags & a,
EventListenerFlags b )
constexpr

◆ OrEmpty()

template<typename T>
requires std::is_default_constructible_v<T>
T OrEmpty ( Result< T > result)
nodiscard

Get a Result's value, or a default-constructed T if it holds an error.

Use this when you've handled the error and want to carry on with an empty value (every operation on an empty Element does nothing):

dom::Result<dom::Element> row = doc.querySelector(selector, dom::Checked);
if (!row && !row.error().is_page_gone())
Log(row.error().message());
constexpr Checked_t Checked
Pass to a DOM call to get a dom::Result holding the reason for a failure instead of an empty value.
Definition Error.h:299
T OrEmpty(Result< T > result)
Get a Result's value, or a default-constructed T if it holds an error.
Definition Error.h:320
Expected< T, Error > Result
The result of a DOM operation that can fail (either a T or a dom::Error).
Definition Error.h:277
ContainerSpec< Children... > row(ContainerOptions options, Children... children)
Describe a row container with child elements.
Definition Builder.h:125
Parameters
resultThe Result to read.
Returns
Returns the value or a default-constructed T.

◆ SetInjectionFilter()

template<typename F>
void SetInjectionFilter ( View * view,
F && filter )

Set a View's DOM triggers filter with a C++ callable (the typed form of View::SetDOMTriggersInjectionFilter()).

The View calls the filter each time it's about to add an attached set of DOM listeners to a page (when a page finishes parsing, when you attach a set, and when a page returns from the back-forward cache). The origin rules run first, and rules_allow holds their result. Return true to add the listeners or false to skip the page, whatever the rules decided. Use it for decisions that origin rules can't express, such as checking a user setting or allowing a page whose origin is opaque.

dom::SetInjectionFilter(view.get(), [](const dom::InjectionRequest& request) {
return request.rules_allow && request.is_main_frame;
});
void SetInjectionFilter(View *view, F &&filter)
Set a View's DOM triggers filter with a C++ callable (the typed form of View::SetDOMTriggersInjection...
Definition Triggers.h:605
Information passed to a DOM triggers filter callback.
Definition Triggers.h:113
Parameters
viewThe View to set the filter on (nothing happens if it's nullptr).
filterA callable invocable as bool(const dom::InjectionRequest&). The new filter replaces (and destroys) the previous one.
Note
Call this on the Renderer's thread. The filter runs there too.
Note
The filter runs on subframes only for sets attached with dom::AllFrames. The request is valid only during the call.
Note
A filter that throws a C++ exception skips that page.
See also
ClearInjectionFilter()

◆ ToJS()

js::Value ToJS ( const js::Context & context,
const Element & element )
inline

Get an element's JavaScript object (the same object the page's scripts see for it).

Converting one element twice gives the same object (they compare ===).

Parameters
contextThe JavaScript context of the element's own frame (see GetJSContext()).
elementThe element to convert.
Returns
Returns the element's JavaScript object, or an empty Value if context belongs to another frame or View.
See also
FromJS()

Variable Documentation

◆ AllFrames

AttachFlags AllFrames = AttachFlags::AllFrames
inlineconstexpr

Add the listeners to subframes too (shorthand for AttachFlags::AllFrames).

◆ Capture

Receive the event in the capture phase (shorthand for EventListenerFlags::Capture).

◆ Checked

Checked_t Checked {}
inlineconstexpr

Pass to a DOM call to get a dom::Result holding the reason for a failure instead of an empty value.

dom::Result<dom::Element> title = doc.querySelector(".panel h1", dom::Checked);
if (!title)
Log(title.error().message()); // eg, a SyntaxError for a malformed selector

◆ css

template<detail::FixedString Name>
CSSPropertyName<Name> css {}
inlineconstexpr

A CSS property name checked when your code compiles.

Use it where style access takes a property name, so a typo is a compile error instead of a write that silently does nothing:

el.style[dom::css<"background-color">] = "purple";
el.style[dom::css<"backgroundColor">] = "purple"; // the same property
el.style[dom::css<"--accent">] = "#ff3366";
std::string size = dom::getComputedStyle(el)[dom::css<"font-size">];
ComputedStyle getComputedStyle(const Element &element)
Get an element's computed style (getComputedStyle).
Definition ComputedStyle.h:232
constexpr CSSPropertyName< Name > css
A CSS property name checked when your code compiles.
Definition CSSPropertyName.h:51

Write a name in lowercase CSS form (background-color) or in the camelCase form JavaScript uses for it (backgroundColor, cssFloat for float). Prefixed legacy names (eg, -webkit-border-radius or webkitBorderRadius) work too, and any custom property name (-- followed by at least one character) is accepted.

Note
For a name you only know at run time, pass a string instead (eg, el.style["background-color"]). An unknown name then does nothing.

◆ NotPassive

EventListenerFlags NotPassive = EventListenerFlags::NotPassive
inlineconstexpr

Make the listener not passive (shorthand for EventListenerFlags::NotPassive).

◆ Once

Remove the listener after the first event it receives (shorthand for EventListenerFlags::Once).

◆ Passive

Make the listener passive (shorthand for EventListenerFlags::Passive).