7#pragma push_macro("None")
10#include <Ultralight/CAPI/CAPI_DOMData.h>
18#include <Ultralight/dom/data/detail/ContextImpl.h>
19#include <Ultralight/dom/data/detail/Descriptors.h>
20#include <Ultralight/dom/data/detail/Emission.h>
24#include <initializer_list>
125static_assert(
static_cast<int>(
DumpAt::NextSync) == kULDOMDataDumpAt_NextSync
126 &&
static_cast<int>(
DumpAt::Now) == kULDOMDataDumpAt_Now,
127 "DumpAt must mirror ULDOMDataDumpAt");
137static_assert(
static_cast<unsigned>(
AttachFlags::None) == kULDOMDataContextAttachFlags_None,
138 "dom::data::AttachFlags must mirror ULDOMDataContextAttachFlags");
322 Context(
Context&& other) noexcept : handle_(other.handle_) { other.handle_ =
nullptr; }
334 if (
this != &other) {
335 ulDestroyDOMDataContext(handle_);
336 handle_ = other.handle_;
337 other.handle_ =
nullptr;
358 explicit operator bool()
const {
return handle_ !=
nullptr; }
381 template <
typename T>
384 Binding<T> binding(BindHandle<T>(name,
static_cast<void*
>(std::addressof(instance)),
385 &detail::BorrowedAcquire,
nullptr,
nullptr));
387 binding.access_ = detail::MakeBorrowedAccess<T>(std::addressof(instance));
404 template <
typename T>
408 BindHandle<T>(name,
const_cast<void*
>(
static_cast<const void*
>(std::addressof(instance))),
409 &detail::BorrowedAcquire,
nullptr,
nullptr));
428 template <
typename T>
430 [[nodiscard]]
Binding<std::remove_cvref_t<T>>
Bind(std::string_view name, T&& instance) {
431 using Plain = std::remove_cvref_t<T>;
432 using Box = detail::ValueHolderBox<Plain>;
433 auto* box =
new Box { std::forward<T>(instance) };
435 BindHandle<Plain>(name, box, &Box::Acquire,
nullptr, &Box::Destroy));
437 binding.access_ = detail::MakeValueAccess<Plain>(box);
460 template <
typename H>
463 std::remove_cv_t<typename HolderTraits<std::remove_cvref_t<H>>::element_type>>
464 Bind(std::string_view name, H&& holder) {
465 using Plain = std::remove_cvref_t<H>;
466 using T = std::remove_cv_t<typename HolderTraits<Plain>::element_type>;
467 using Box = detail::SmartHolderBox<Plain>;
468 auto* box =
new Box { std::forward<H>(holder), std::nullopt };
470 BindHandle<T>(name, box, &Box::Acquire, &Box::Release, &Box::Destroy));
473 =
decltype(*ultralight::detail::LockHolder(std::declval<const Plain&>()));
474 if constexpr (!std::is_const_v<std::remove_reference_t<LockedRef>>)
475 binding.access_ = detail::MakeHolderAccess<Plain, T>(box);
515 return view && handle_
517 options.origin_rules.data(), options.origin_rules.size());
555 void Sync() { ulDOMDataContextSync(handle_); }
585 bool PostAction(std::string_view name) {
return PostActionByName(name,
nullptr, 0); }
606 template <
typename P>
609 using Plain = std::remove_cvref_t<P>;
610 static_assert(detail::PayloadMarshalable<Plain>(),
611 "dom::data: a payload type carries plain data fields only (readable "
612 "leaf members of boolean, integral, floating-point, string, or "
613 "reflected enum type)");
614 std::vector<std::string> strings;
615 std::vector<ULDOMDataPayloadEntry> entries;
616 detail::MarshalPayload(payload, strings, entries);
617 return PostActionByName(name, entries.empty() ?
nullptr : entries.data(),
638 template <
typename P>
642 ULDOMDataPayloadEntry entry {};
643 detail::MarshalScalarPayload(payload, backing, entry);
644 return PostActionByName(name, &entry, 1);
687 template <
typename F>
688 requires(std::is_invocable_v<std::decay_t<F>&>
689 || std::is_invocable_v<std::decay_t<F>&,
Document>)
691 using Fn = std::decay_t<F>;
692 auto* fn =
new Fn(std::forward<F>(callback));
693 if constexpr (std::is_invocable_v<Fn&, Document>) {
694 ulDOMDataContextPostTask(handle_, &detail::InvokePostedCallable<Fn>, fn,
695 &detail::DeletePostedCallable<Fn>);
697 ulDOMDataContextPostTaskOnce(handle_, &detail::InvokePostedCallable<Fn>, fn,
698 &detail::DeletePostedCallable<Fn>);
733 template <
typename Fn>
735 using Plain = std::decay_t<Fn>;
736 static_assert(std::is_invocable_v<Plain&, Value>,
737 "dom::data: a formatter takes the published value as a dd::Value");
738 if constexpr (std::is_invocable_v<Plain&, Value>) {
739 using R = std::remove_cvref_t<std::invoke_result_t<Plain&, Value>>;
740 static_assert(std::is_same_v<R, ultralight::String> || std::is_same_v<R, std::string>
741 || std::is_constructible_v<ultralight::String, R>,
742 "dom::data: a formatter returns display text (String, std::string, "
744 auto* boxed =
new Plain(std::forward<Fn>(fn));
745 ulDOMDataContextDefineFormat(handle_, std::string(name).c_str(),
746 &detail::InvokeFormatCallable<Plain>, boxed,
747 &detail::DeletePostedCallable<Plain>);
762 ulDOMDataContextDefineFormat(handle_, std::string(name).c_str(),
nullptr,
nullptr,
nullptr);
773 uint64_t
generation()
const {
return ulDOMDataContextGetGeneration(handle_); }
787 ulDOMDataContextSetActionQueueCapacity(handle_, capacity);
798 return ulDOMDataContextGetActionQueueCapacity(handle_);
827 ULString text = ulDOMDataContextGetSchema(handle_);
829 return std::string();
830 std::string result(ulStringGetData(text), ulStringGetLength(text));
831 ulDestroyString(text);
859 return ulDOMDataContextDumpSchema(handle_, utf8_path,
static_cast<ULDOMDataDumpAt
>(when));
886 return Context(handle ? ulCreateDOMDataContextBorrowedRef(handle) :
nullptr);
911 template <
typename T>
912 ULDOMDataBinding BindHandle(std::string_view name,
void* holder_state,
913 ULDOMDataAcquireCallback acquire, ULDOMDataReleaseCallback release,
914 ULUserDataDestroyCallback destroy_holder) {
915 return ulDOMDataContextBind(handle_, std::string(name).c_str(),
916 reinterpret_cast<ULDOMDataType
>(detail::Descriptors<T>()),
917 &detail::SyncWalkThunk<T>, holder_state, acquire, release,
921 bool PostActionByName(std::string_view name,
const ULDOMDataPayloadEntry* entries,
923 const size_t dot = name.find(
'.');
924 if (dot == std::string_view::npos || dot == 0 || dot + 1 == name.size())
926 const std::string binding_name(name.substr(0, dot));
927 const std::string action_name(name.substr(dot + 1));
928 return ulDOMDataContextPostActionByName(handle_, binding_name.c_str(), action_name.c_str(),
945#pragma pop_macro("None")
struct C_DOMDataContext * ULDOMDataContext
Opaque handle to a data-binding context.
Definition View.h:53
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 DetachDOMDataContext(ULDOMDataContext context)=0
Detach a data-binding context from this View.
virtual bool AttachDOMDataContext(ULDOMDataContext context, unsigned flags=0, const char *const *origin_rules=nullptr, size_t num_origin_rules=0)=0
Attach a data-binding context to this View.
The root of a page's DOM tree in a View or frame.
Definition Document.h:106
A handle that keeps an instance bound to pages and registers its input handlers.
Definition Binding.h:229
Binding()=default
Create an empty Binding.
Context & operator=(Context &&other) noexcept
Move assignment (other becomes empty).
Definition Context.h:333
Binding< T > Bind(std::string_view name, T &instance)
Bind an instance of a described type under a binding name.
Definition Context.h:383
uint64_t generation() const
Get the generation of the last update Sync() sent to the pages.
Definition Context.h:773
static Context Adopt(ULDOMDataContext handle)
Wrap a C handle you own, taking ownership of it.
Definition Context.h:872
bool PostAction(std::string_view name)
Send an action to a bound instance's handler as if the page fired it.
Definition Context.h:585
bool DumpSchema(const char *utf8_path, DumpAt when=DumpAt::NextSync)
Write the JSON from schema() to a file.
Definition Context.h:858
Context & operator=(const Context &)=delete
Context & UndefineFormat(std::string_view name)
Remove a formatter.
Definition Context.h:761
bool PostAction(std::string_view name, const P &payload)
Send an action with a payload struct (see the payloadless overload).
Definition Context.h:608
static Context FromBorrowed(ULDOMDataContext handle)
Wrap a C handle someone else owns, without owning the context.
Definition Context.h:885
Binding< std::remove_cvref_t< T > > Bind(std::string_view name, T &&instance)
Bind an instance by value under a binding name.
Definition Context.h:430
bool AttachTo(View *view, const AttachOptions &options={})
Attach this Context to a View.
Definition Context.h:514
ULDOMDataContext LeakRef()
Give up ownership of the C handle and return it.
Definition Context.h:902
static Context Create()
Create a Context whose home thread is the calling thread.
Definition Context.h:290
Context(Context &&other) noexcept
Move constructor (other becomes empty).
Definition Context.h:322
void set_action_queue_capacity(uint32_t capacity)
Set how many actions can wait for the next Sync().
Definition Context.h:786
Binding< std::remove_cv_t< typename HolderTraits< std::remove_cvref_t< H > >::element_type > > Bind(std::string_view name, H &&holder)
Bind an instance through a smart pointer under a binding name.
Definition Context.h:464
void Sync()
Deliver input from the page to your handlers and send your changes to the pages.
Definition Context.h:555
ULDOMDataContext raw() const
Get the C handle, for passing to the <Ultralight/CAPI/CAPI_DOMData.h> functions.
Definition Context.h:895
bool PostAction(std::string_view name, const P &payload)
Send an action with a single-value payload (see the payloadless overload).
Definition Context.h:640
static Context CreateThreadSafe()
Create a Context that any thread can use.
Definition Context.h:312
void PostTask(F &&callback)
Run a callable on the Renderer's thread once the pages show your latest data.
Definition Context.h:690
~Context()
Destroy this handle.
Definition Context.h:353
Context(const Context &)=delete
uint32_t action_queue_capacity() const
Get how many actions can wait for the next Sync().
Definition Context.h:797
void DetachFrom(View *view)
Detach this Context from a View.
Definition Context.h:532
Context & DefineFormat(std::string_view name, Fn &&fn)
Define a formatter for {{path|name}} text.
Definition Context.h:734
Binding< T > Bind(std::string_view name, const T &instance)
Bind a const instance under a binding name.
Definition Context.h:406
std::string schema() const
Get the schema of every bound instance as JSON, with their current values.
Definition Context.h:826
Whether or not Context::Bind() can bind an instance through H.
Definition Holders.h:37
Whether or not T has a schema (ignoring const, volatile, and references), ie.
Definition TypeTraits.h:163
Whether or not P can be an action's payload without a payload struct (ignoring const,...
Definition ValueTraits.h:268
Data-binding API that connects native C++ data to HTML and CSS markup.
Definition ActionInfo.h:13
DumpAt
When Context::DumpSchema() writes its file.
Definition Context.h:120
@ Now
Right away.
Definition Context.h:122
@ NextSync
At the end of the next Context::Sync().
Definition Context.h:121
AttachFlags
The flags for Context::AttachTo() (the typed form of ULDOMDataContextAttachFlags).
Definition Context.h:133
@ None
No options.
Definition Context.h:134
Direct C++ access to modify page elements and handle events.
@ None
Add the listeners to the main frame only.
Definition Triggers.h:49
Root namespace for every public Ultralight type, function, and enumeration.
@ None
Definition Anchor.h:36
Options for Context::AttachTo().
Definition Context.h:143
OriginRules origin_rules
The origin rules for the pages that get the bindings.
Definition Context.h:153
AttachFlags flags
The attach flags (see AttachFlags).
Definition Context.h:147