docs
Loading...
Searching...
No Matches
Triggers.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_DOMEvent.h>
11#include <Ultralight/CAPI/CAPI_DOMTriggers.h>
13#include <Ultralight/View.h>
14#include <Ultralight/detail/InjectionFilter.h>
17#include <Ultralight/dom/detail/Receivers.h>
18
19#include <string_view>
20#include <type_traits>
21#include <utility>
22
23namespace ultralight {
24namespace dom {
25
26/// \cond INTERNAL
27namespace detail {
28
29// Trampoline behind Triggers::OnDOMReady; the document is borrowed, so the typed view
30// takes its own reference.
31template <typename Fn>
32void ReadyThunk(void* user_data, ULDOMDocument document) {
33 Fn& fn = *static_cast<Fn*>(user_data);
34 CallListener("DOM-ready or restore hook", [&] {
35 if constexpr (std::is_invocable_v<Fn&, Document>)
36 fn(Document::FromBorrowed(document));
37 else
38 fn();
39 });
40}
41
42} // namespace detail
43/// \endcond
44
45///
46/// The flags for Triggers::AttachTo() (the typed form of ULDOMTriggersAttachFlags).
47///
48enum class AttachFlags : unsigned {
49 None = 0, ///< Add the listeners to the main frame only.
50 AllFrames = 1u << 1, ///< Add the listeners to subframes too.
51};
52
54 return static_cast<AttachFlags>(static_cast<unsigned>(a) | static_cast<unsigned>(b));
55}
56
58 return a = a | b;
59}
60
61///
62/// Add the listeners to subframes too (shorthand for AttachFlags::AllFrames).
63///
65
66static_assert(static_cast<unsigned>(AttachFlags::AllFrames) == kULDOMTriggersAttachFlags_AllFrames,
67 "dom::AttachFlags must mirror ULDOMTriggersAttachFlags");
68
69///
70/// Options for Triggers::AttachTo().
71///
72/// ```
73/// if (!ui.AttachTo(view.get(), { .flags = dom::AllFrames,
74/// .origin_rules = { "https://*.mygame.com" } }))
75/// Log("the attach failed");
76/// ```
77///
79 ///
80 /// The attach flags (see AttachFlags).
81 ///
83
84 ///
85 /// The origin rules for the pages that get the listeners. Leave it empty for the default
86 /// policy (your application's own content). See ultralight::OriginRules.
87 ///
89};
90
91///
92/// Information passed to a DOM triggers filter callback.
93///
94/// When you set a filter callback with dom::SetInjectionFilter(), a View passes this struct each
95/// time it's about to add an attached Triggers set to a page. Origin rules run first and provide an
96/// initial verdict in `rules_allow`, which your callback can override.
97///
98/// This filter adds a developer-tools listener set only when a user setting is on:
99///
100/// ```
101/// dom::SetInjectionFilter(view.get(), [](const dom::InjectionRequest& request) {
102/// if (request.triggers == dev_tools.raw())
103/// return request.rules_allow && dev_tools_enabled;
104/// return request.rules_allow;
105/// });
106/// ```
107///
108/// @note New members may be added at the end in later versions, so read members by name.
109///
110/// @see dom::SetInjectionFilter(), dom::ClearInjectionFilter(), dom::Triggers,
111/// ultralight::OriginRules
112///
114 ///
115 /// The View loading the page (the View you set the filter on).
116 ///
118
119 ///
120 /// The set of DOM listeners being decided on. It's the handle your Triggers' raw() returns,
121 /// so compare the two to tell your sets apart.
122 ///
124
125 ///
126 /// The page's security origin, serialized (eg, "https://example.com", or "null" for an opaque
127 /// origin).
128 ///
129 const char* origin;
130
131 ///
132 /// Whether or not the page is in the View's main frame.
133 ///
135
136 ///
137 /// Whether or not the origin rules allow the page.
138 ///
140};
141
142///
143/// A set of DOM event listeners and lifecycle hooks that persists across page navigations.
144///
145/// You define DOM event listeners and setup hooks in a dom::Triggers set and attach it to a View
146/// instead of re-registering handlers on every page load. One set can serve several View%s, and it
147/// functions even when JavaScript is disabled.
148///
149/// Attach the set to a View before loading content so every page gets the listeners:
150///
151/// ```
152/// dom::Triggers ui;
153///
154/// ui.On("#save", "click", [] { SaveGame(); });
155/// ui.OnDOMReady([](dom::Document document) {
156/// document.getElementById("status").textContent = "Ready";
157/// });
158///
159/// if (ui.AttachTo(view.get()))
160/// view->LoadURL("file:///app.html");
161/// ```
162///
163/// ## Delivery Timing
164///
165/// Pages receive an attached set based on their load state:
166///
167/// - **A loading page gets the set once its document finishes parsing.** Any OnDOMReady() hooks run
168/// right after the listeners attach.
169/// - **Attaching after a page has loaded applies the listeners right away.** Any OnDOMReady() hooks
170/// run synchronously inside AttachTo().
171/// - **Handlers added after attaching reach only subsequent pages.** The current page keeps its
172/// existing listeners unchanged.
173///
174/// @note The page's own `DOMContentLoaded` event fires before the set arrives. Use OnDOMReady()
175/// for setup code that runs once document parsing completes.
176///
177/// ## Origin Rules and Page Filtering
178///
179/// By default, only your own content gets the set (`file://` pages and View::LoadHTML()). Passing
180/// custom origin rules in AttachOptions replaces this default policy:
181///
182/// - **Local pages require an explicit `"file://*"` rule.** Without it, local content stops
183/// receiving the set.
184/// - **Pages loaded without a URL match no origin rule.** Content loaded through View::LoadHTML()
185/// without a URL has an opaque origin, so origin patterns never match it.
186/// - **Subframes are excluded unless requested.** Pass `dom::AllFrames` in `flags` to deliver
187/// listeners to subframe documents and run OnDOMReady() for each frame's document.
188/// - **Malformed rules cancel the attachment.** If any rule fails to parse, AttachTo() returns
189/// `false`, logs a warning explaining the failure, and leaves the View unchanged.
190///
191/// Configure origin rules and frame targeting through AttachOptions when attaching the set:
192///
193/// ```
194/// bool attached = ui.AttachTo(view.get(), {
195/// .flags = dom::AllFrames,
196/// .origin_rules = { "https://*.mygame.com", "file://*" } });
197/// ```
198///
199/// For decisions origin rules can't express (such as checking a user setting or allowing an opaque
200/// origin), see dom::SetInjectionFilter() and dom::InjectionRequest.
201///
202/// ## Object Lifetime and Cleanup
203///
204/// Calling DetachFrom() removes the whole set from a View immediately, though individual
205/// registrations can't be removed on their own.
206///
207/// Destroying a dom::Triggers instance automatically detaches it from every View and stops its
208/// listeners right away. Storing the set as a member of the class whose methods its callbacks
209/// invoke ensures the listeners never outlive the surrounding object:
210///
211/// ```
212/// class Hud {
213/// public:
214/// explicit Hud(View* view) {
215/// ui_.On("#close", "click", [this] { Dismiss(); });
216/// if (!ui_.AttachTo(view))
217/// Log("an origin rule failed to parse");
218/// }
219///
220/// private:
221/// void Dismiss() {}
222/// dom::Triggers ui_;
223/// };
224/// ```
225///
226/// ## Back-Forward Cache Restores
227///
228/// When a page returns from the back-forward cache (`Config::page_cache_size` above 0), the library
229/// restores its event listeners before the `pageshow` event fires. Hooks registered with
230/// OnDOMReady() don't run again because the document was parsed during the initial load.
231///
232/// Register an OnRestore() hook for tasks that must run every time a cached page reappears:
233///
234/// ```
235/// ui.OnRestore([](dom::Document document) {
236/// document.getElementById("status").textContent = "Welcome back";
237/// });
238/// ```
239///
240/// ## Choosing Between Triggers and addEventListener
241///
242/// Choose between dom::Triggers and Element::addEventListener() based on whether the listeners
243/// belong to one page or the whole View:
244///
245/// - **dom::Triggers persists across navigations and cache restores.** Use it for interface
246/// elements that must remain active across page loads or multiple View%s.
247/// - **Element::addEventListener() attaches to a single page's elements.** Direct listeners belong
248/// to one document and are gone after a back-forward restore or navigation.
249///
250/// @see dom::AttachOptions, dom::SetInjectionFilter(), dom::InjectionRequest,
251/// ultralight::OriginRules, dom::Element::On(), dom::EventListener
252///
253class Triggers {
254 public:
255 ///
256 /// Create a new set of DOM listeners.
257 ///
258 Triggers() : handle_(ulCreateDOMTriggers()) {}
259
260 Triggers(const Triggers&) = delete;
261 Triggers& operator=(const Triggers&) = delete;
262
263 ///
264 /// Move constructor (`other` becomes empty).
265 ///
266 /// @param other The Triggers to move from.
267 ///
268 Triggers(Triggers&& other) noexcept : handle_(other.handle_) { other.handle_ = nullptr; }
269
270 ///
271 /// Move assignment (releases the set this object held, then takes over `other`'s).
272 ///
273 /// @param other The Triggers to move from.
274 ///
275 /// @return Returns this object.
276 ///
277 Triggers& operator=(Triggers&& other) noexcept {
278 if (this != &other) {
279 ulDestroyDOMTriggers(handle_);
280 handle_ = other.handle_;
281 other.handle_ = nullptr;
282 }
283 return *this;
284 }
285
286 ///
287 /// Release this object's reference to the set.
288 ///
289 /// @note Destroying the set detaches it from every View (see the class overview),
290 /// unless it came from FromBorrowed() or another owning handle to it exists.
291 ///
292 ~Triggers() { ulDestroyDOMTriggers(handle_); }
293
294 ///
295 /// Whether or not this object holds a set (false after a move or LeakRef(), or when it wraps
296 /// NULL).
297 ///
298 explicit operator bool() const { return handle_ != nullptr; }
299
300 ///
301 /// Add a listener for events on elements matching a CSS selector.
302 ///
303 /// On every page that gets the set, the event target and its ancestors are tested against
304 /// `selector`, and the callback fires with the nearest match. This covers elements added to
305 /// the page later too (it works like Element::On() on the whole document).
306 ///
307 /// @param selector The CSS selector to match (eg, `#save`).
308 ///
309 /// @param type The event type to listen for (eg, `click`).
310 ///
311 /// @param callback The callable to invoke, taking (dom::Event, dom::Element matched),
312 /// (dom::Element matched), or ().
313 ///
314 /// @param flags The registration options (see EventListenerFlags).
315 ///
316 /// @return Returns true if the listener was added, or false if it wasn't (eg, this object
317 /// is empty, or `selector` is malformed). On false, the library destroys its copy
318 /// of `callback`. You can ignore the result, since the library logs a warning for a
319 /// refused selector.
320 ///
321 /// \parblock
322 /// @note Events that don't bubble (eg, `focus`) reach the listener only with dom::Capture. A
323 /// wheel listener is passive unless you pass dom::NotPassive.
324 /// \endparblock
325 ///
326 /// \parblock
327 /// @note With dom::Once, the first `type` event that reaches the document uses up the
328 /// listener on that page, even if no element matches.
329 /// \endparblock
330 ///
331 /// \parblock
332 /// @note Before a Renderer exists, only an empty `selector` is refused here. Each page
333 /// checks the selector when it gets the set instead, and skips a malformed one with a
334 /// warning.
335 /// \endparblock
336 ///
337 template <typename F>
338 bool On(std::string_view selector, std::string_view type, F&& callback,
340 using Fn = std::decay_t<F>;
341 static_assert(detail::InvocableWithEvent<Fn, Element> || std::is_invocable_v<Fn&, Element>
342 || std::is_invocable_v<Fn&>,
343 "On takes a callable invocable with (dom::Event, dom::Element), "
344 "(dom::Element), or ()");
345 detail::CString sel(selector);
346 detail::CString t(type);
347 // The C call takes ownership of fn either way: on failure it runs DeleteCallable.
348 return ulDOMTriggersOn(handle_, sel.c_str(), t.c_str(), static_cast<unsigned>(flags),
349 &detail::DelegatedThunk<Fn>, new Fn(std::forward<F>(callback)),
350 &detail::DeleteCallable<Fn>);
351 }
352
353 ///
354 /// Add a selector listener that calls a member function on a borrowed receiver (no
355 /// forwarding lambda needed):
356 ///
357 /// ```
358 /// ui.On("#save", "click", toolbar, &Toolbar::OnSave);
359 /// ```
360 ///
361 /// @param selector The CSS selector to match (eg, `#save`).
362 ///
363 /// @param type The event type to listen for (eg, `click`).
364 ///
365 /// @param receiver The object to call `method` on. You must keep it alive until this
366 /// Triggers is destroyed or the set is detached from every View.
367 ///
368 /// @param method The member function to call, taking (dom::Event, dom::Element matched),
369 /// (dom::Element matched), or ().
370 ///
371 /// @param flags The registration options (see EventListenerFlags).
372 ///
373 /// @return Returns true if the listener was added (see the callable overload).
374 ///
375 template <typename C, typename M>
376 requires(std::is_class_v<C> && std::is_member_function_pointer_v<M>
378 bool On(std::string_view selector, std::string_view type, C& receiver, M method,
380 return On(selector, type, detail::WrapBorrowedMember(receiver, method), flags);
381 }
382
383 ///
384 /// Add a selector listener that calls a member function through a holder (a shared_ptr, a
385 /// weak_ptr, or a custom smart pointer with a HolderTraits specialization).
386 ///
387 /// The holder is locked around each delivery, and an expired holder skips the delivery
388 /// silently (see LockableHolder).
389 ///
390 /// @param selector The CSS selector to match (eg, `#save`).
391 ///
392 /// @param type The event type to listen for (eg, `click`).
393 ///
394 /// @param holder The holder to lock and call the member on.
395 ///
396 /// @param method The member function to call, taking (dom::Event, dom::Element matched),
397 /// (dom::Element matched), or ().
398 ///
399 /// @param flags The registration options (see EventListenerFlags).
400 ///
401 /// @return Returns true if the listener was added (see the callable overload).
402 ///
403 template <typename H, typename M>
404 requires(LockableHolder<H> && std::is_member_function_pointer_v<M>)
405 bool On(std::string_view selector, std::string_view type, H holder, M method,
407 return On(selector, type, detail::WrapHolderMember(std::move(holder), method), flags);
408 }
409
410 ///
411 /// Add a hook that runs on each page that gets the set, once its document has finished
412 /// parsing.
413 ///
414 /// The hook runs after the set's listeners were added to the page, with or without JavaScript
415 /// enabled. With dom::AllFrames it also runs for each subframe's document. It doesn't run when
416 /// a page is restored from the back-forward cache (see OnRestore()).
417 ///
418 /// @param callback The callable to invoke, taking (dom::Document) or ().
419 ///
420 template <typename F>
421 void OnDOMReady(F&& callback) {
422 using Fn = std::decay_t<F>;
423 static_assert(std::is_invocable_v<Fn&, Document> || std::is_invocable_v<Fn&>,
424 "OnDOMReady takes a callable invocable with (dom::Document) or ()");
425 // The C call takes ownership of the callable either way: on failure it runs DeleteCallable.
426 ulDOMTriggersOnDOMReady(handle_, &detail::ReadyThunk<Fn>, new Fn(std::forward<F>(callback)),
427 &detail::DeleteCallable<Fn>);
428 }
429
430 ///
431 /// Add a hook that runs each time a page that gets the set is restored from the back-forward
432 /// cache (Config::page_cache_size > 0).
433 ///
434 /// The hook runs after the set's listeners were added to the page again, and before the
435 /// page's `pageshow` event. It never runs on a normal load.
436 ///
437 /// @param callback The callable to invoke, taking (dom::Document) or ().
438 ///
439 template <typename F>
440 void OnRestore(F&& callback) {
441 using Fn = std::decay_t<F>;
442 static_assert(std::is_invocable_v<Fn&, Document> || std::is_invocable_v<Fn&>,
443 "OnRestore takes a callable invocable with (dom::Document) or ()");
444 // The C call takes ownership of the callable either way: on failure it runs DeleteCallable.
445 ulDOMTriggersOnRestore(handle_, &detail::ReadyThunk<Fn>, new Fn(std::forward<F>(callback)),
446 &detail::DeleteCallable<Fn>);
447 }
448
449 ///
450 /// Attach this set to a View.
451 ///
452 /// The listeners are added to the View's current page (if its document has finished parsing
453 /// and the origin rules allow it) and to every page the View loads afterward. The View
454 /// keeps the set attached until you detach it or destroy this Triggers instance. Attaching
455 /// again updates the flags and origin rules for later pages.
456 ///
457 /// ```
458 /// // Your own content, subframes included:
459 /// if (!ui.AttachTo(view.get(), { .flags = dom::AllFrames }))
460 /// Log("the attach failed");
461 /// ```
462 ///
463 /// @param view The View to attach to.
464 ///
465 /// @param options The attach flags and the origin rules for the pages that get the
466 /// listeners (see AttachOptions).
467 ///
468 /// @return Returns true on success, or false if `view` is nullptr, this object holds no set,
469 /// a flag is unknown, or a rule failed to parse. Nothing changes then. An unknown
470 /// flag or a rule that failed to parse also logs a warning that says why.
471 ///
472 [[nodiscard]] bool AttachTo(View* view, const AttachOptions& options = {}) {
473 return view && handle_
474 && view->AttachDOMTriggers(handle_, static_cast<unsigned>(options.flags),
475 options.origin_rules.data(), options.origin_rules.size());
476 }
477
478 ///
479 /// Detach this set from a View.
480 ///
481 /// The listeners are removed from the View's pages right away, and no later page gets them.
482 ///
483 /// @param view The View to detach from.
484 ///
485 /// @note If you attach the set again, the current page gets it again (and its DOM-ready
486 /// hooks run again there).
487 ///
488 void DetachFrom(View* view) {
489 if (view && handle_)
490 view->DetachDOMTriggers(handle_);
491 }
492
493 // --- Interop with the C API (most embedders never touch raw handles) -------------------
494
495 ///
496 /// Wrap a C handle you own, taking ownership of it.
497 ///
498 /// @param handle A handle from the C API that you would otherwise destroy with
499 /// ulDestroyDOMTriggers() (NULL gives an empty object).
500 ///
501 /// @return Returns a Triggers that releases `handle` when it's done.
502 ///
503 static Triggers Adopt(ULDOMTriggers handle) { return Triggers(handle, AdoptTag {}); }
504
505 ///
506 /// Wrap a C handle someone else owns, without owning the set (eg, the `triggers` member of a
507 /// dom::InjectionRequest).
508 ///
509 /// The result works like any Triggers, but destroying it never detaches the set, and it
510 /// doesn't keep the set attached once its owners are gone.
511 ///
512 /// @param handle The borrowed handle (NULL gives an empty object).
513 ///
514 /// @return Returns a Triggers with its own (non-owning) reference, so you can keep it after
515 /// the callback. Its raw() is a different handle than `handle`.
516 ///
518 return Triggers(handle ? ulCreateDOMTriggersBorrowedRef(handle) : nullptr, AdoptTag {});
519 }
520
521 ///
522 /// Get the C handle, for passing to the `<Ultralight/CAPI/CAPI_DOMTriggers.h>` functions.
523 ///
524 /// @return Returns the handle (NULL if this object holds no set). This object still owns it,
525 /// so don't destroy it.
526 ///
527 ULDOMTriggers raw() const { return handle_; }
528
529 ///
530 /// Give up ownership of the C handle and return it. This object becomes empty.
531 ///
532 /// @return Returns the handle. You must call ulDestroyDOMTriggers() when finished.
533 ///
535 ULDOMTriggers handle = handle_;
536 handle_ = nullptr;
537 return handle;
538 }
539
540 private:
541 struct AdoptTag {};
542 Triggers(ULDOMTriggers handle, AdoptTag) : handle_(handle) {}
543
544 ULDOMTriggers handle_ = nullptr;
545};
546
547} // namespace dom
548
549/// \cond INTERNAL
550namespace detail {
551template <>
552struct InjectionRequestTraits<ULDOMTriggersInjectionRequest> {
553 static dom::InjectionRequest ToRequest(View* view,
554 const ULDOMTriggersInjectionRequest& request) {
555 return { view, request.triggers, request.origin, request.is_main_frame,
556 request.rules_allow };
557 }
558 static void ReportException(const char* what) {
559 ulDOMReportCallbackException("DOM triggers injection filter", what);
560 }
561};
562} // namespace detail
563/// \endcond
564
565namespace dom {
566
567///
568/// Set a View's DOM triggers filter with a C++ callable (the typed form of
569/// View::SetDOMTriggersInjectionFilter()).
570///
571/// The View calls the filter each time it's about to add an attached set of DOM listeners to a
572/// page (when a page finishes parsing, when you attach a set, and when a page returns from the
573/// back-forward cache). The origin rules run first, and `rules_allow` holds their result.
574/// Return true to add the listeners or false to skip the page, whatever the rules decided. Use
575/// it for decisions that origin rules can't express, such as checking a user setting or allowing
576/// a page whose origin is opaque.
577///
578/// ```
579/// dom::SetInjectionFilter(view.get(), [](const dom::InjectionRequest& request) {
580/// return request.rules_allow && request.is_main_frame;
581/// });
582/// ```
583///
584/// @param view The View to set the filter on (nothing happens if it's nullptr).
585///
586/// @param filter A callable invocable as `bool(const dom::InjectionRequest&)`. The new filter
587/// replaces (and destroys) the previous one.
588///
589/// \parblock
590/// @note Call this on the Renderer's thread. The filter runs there too.
591/// \endparblock
592///
593/// \parblock
594/// @note The filter runs on subframes only for sets attached with dom::AllFrames. The request
595/// is valid only during the call.
596/// \endparblock
597///
598/// \parblock
599/// @note A filter that throws a C++ exception skips that page.
600/// \endparblock
601///
602/// @see ClearInjectionFilter()
603///
604template <typename F>
605void SetInjectionFilter(View* view, F&& filter) {
606 using Fn = std::decay_t<F>;
607 static_assert(std::is_invocable_r_v<bool, Fn&, const InjectionRequest&>,
608 "dom::SetInjectionFilter takes a callable invocable as "
609 "bool(const dom::InjectionRequest&)");
610 if (!view)
611 return;
612 using Adapter = ultralight::detail::InjectionFilterAdapter<Fn, ULDOMTriggersInjectionRequest>;
613 view->SetDOMTriggersInjectionFilter(&Adapter::Invoke,
614 new Adapter { std::forward<F>(filter), view },
615 &Adapter::Destroy);
616}
617
618///
619/// Remove a View's DOM triggers filter, so the origin rules alone decide which pages get each
620/// set.
621///
622/// @param view The View to clear the filter on (nothing happens if it's nullptr).
623///
624/// @note Call this on the Renderer's thread.
625///
626inline void ClearInjectionFilter(View* view) {
627 if (view)
628 view->SetDOMTriggersInjectionFilter(nullptr, nullptr, nullptr);
629}
630
631} // namespace dom
632} // namespace ultralight
633
634#pragma pop_macro("None")
AdoptTag
Definition JSRetainPtr.h:48
struct C_DOMTriggers * ULDOMTriggers
Opaque handle to a set of DOM event listeners and DOM-ready hooks.
Definition View.h:46
struct C_DOMDocument * ULDOMDocument
Opaque handle to a page's DOM document.
Definition View.h:39
struct ULDOMTriggersInjectionRequest ULDOMTriggersInjectionRequest
The details a DOM triggers injection filter decides on.
Definition View.h:67
A list of origin patterns that controls which pages get an attached API.
Definition OriginRules.h:90
Web-page container rendered to an offscreen surface.
Definition View.h:483
virtual void SetDOMTriggersInjectionFilter(DOMTriggersInjectionFilter filter, void *user_data, void(*destroy_user_data)(void *))=0
Set a filter that decides whether an attached set of DOM listeners is applied to a page.
virtual bool AttachDOMTriggers(ULDOMTriggers triggers, unsigned flags=0, const char *const *origin_rules=nullptr, size_t num_origin_rules=0)=0
Attach a set of DOM listeners to this View.
virtual void DetachDOMTriggers(ULDOMTriggers triggers)=0
Detach a set of DOM listeners from this View.
void OnRestore(F &&callback)
Add a hook that runs each time a page that gets the set is restored from the back-forward cache (Conf...
Definition Triggers.h:440
ULDOMTriggers raw() const
Get the C handle, for passing to the <Ultralight/CAPI/CAPI_DOMTriggers.h> functions.
Definition Triggers.h:527
Triggers & operator=(const Triggers &)=delete
bool AttachTo(View *view, const AttachOptions &options={})
Attach this set to a View.
Definition Triggers.h:472
ULDOMTriggers LeakRef()
Give up ownership of the C handle and return it.
Definition Triggers.h:534
~Triggers()
Release this object's reference to the set.
Definition Triggers.h:292
Triggers & operator=(Triggers &&other) noexcept
Move assignment (releases the set this object held, then takes over other's).
Definition Triggers.h:277
static Triggers Adopt(ULDOMTriggers handle)
Wrap a C handle you own, taking ownership of it.
Definition Triggers.h:503
Triggers(Triggers &&other) noexcept
Move constructor (other becomes empty).
Definition Triggers.h:268
Triggers(const Triggers &)=delete
bool On(std::string_view selector, std::string_view type, C &receiver, M method, EventListenerFlags flags=EventListenerFlags::None)
Add a selector listener that calls a member function on a borrowed receiver (no forwarding lambda nee...
Definition Triggers.h:378
bool On(std::string_view selector, std::string_view type, H holder, M method, EventListenerFlags flags=EventListenerFlags::None)
Add a selector listener that calls a member function through a holder (a shared_ptr,...
Definition Triggers.h:405
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
static Triggers FromBorrowed(ULDOMTriggers handle)
Wrap a C handle someone else owns, without owning the set (eg, the triggers member of a dom::Injectio...
Definition Triggers.h:517
Triggers()
Create a new set of DOM listeners.
Definition Triggers.h:258
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
void DetachFrom(View *view)
Detach this set from a View.
Definition Triggers.h:488
Whether or not the DOM API can hold an object through H (ignoring const and references),...
Definition Holders.h:41
Direct C++ access to modify page elements and handle events.
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
constexpr EventListenerFlags & operator|=(EventListenerFlags &a, EventListenerFlags b)
Definition EventListener.h:65
constexpr EventListenerFlags operator|(EventListenerFlags a, EventListenerFlags b)
Definition EventListener.h:61
EventListenerFlags
Options for adding an event listener, as flags (addEventListener() and On()).
Definition EventListener.h:41
@ None
Definition EventListener.h:42
void ClearInjectionFilter(View *view)
Remove a View's DOM triggers filter, so the origin rules alone decide which pages get each set.
Definition Triggers.h:626
AttachFlags
The flags for Triggers::AttachTo() (the typed form of ULDOMTriggersAttachFlags).
Definition Triggers.h:48
@ AllFrames
Add the listeners to subframes too.
Definition Triggers.h:50
@ None
Add the listeners to the main frame only.
Definition Triggers.h:49
constexpr AttachFlags AllFrames
Add the listeners to subframes too (shorthand for AttachFlags::AllFrames).
Definition Triggers.h:64
Root namespace for every public Ultralight type, function, and enumeration.
@ None
Definition Anchor.h:36
Options for Triggers::AttachTo().
Definition Triggers.h:78
OriginRules origin_rules
The origin rules for the pages that get the listeners.
Definition Triggers.h:88
AttachFlags flags
The attach flags (see AttachFlags).
Definition Triggers.h:82
Information passed to a DOM triggers filter callback.
Definition Triggers.h:113
const char * origin
The page's security origin, serialized (eg, "https://example.com", or "null" for an opaque origin).
Definition Triggers.h:129
bool rules_allow
Whether or not the origin rules allow the page.
Definition Triggers.h:139
bool is_main_frame
Whether or not the page is in the View's main frame.
Definition Triggers.h:134
ULDOMTriggers triggers
The set of DOM listeners being decided on.
Definition Triggers.h:123
View * view
The View loading the page (the View you set the filter on).
Definition Triggers.h:117