|
Ultralight C++ API 2.0.0
|
Type-checked JavaScript bridge between C++ and web pages.
#include <Ultralight/JS.h>
The JavaScript API provides two-way communication between your C++ application and the web pages loaded into a View. You can bind functions and properties under a global object that page scripts call like any Web API, or reach into a page to run scripts and call JavaScript functions directly.
Conversions between C++ types and JavaScript values happen automatically. The library checks types at compile time with static assertions and at runtime during every JavaScript call.
Register a bound function on an API attached to a View, then call into the page once the document loads:
Common tasks begin with these types:
| Task | Type |
|---|---|
| Bind functions and properties | js::API |
| Return Promises from async functions | js::Task, js::Resolver |
| Call page functions or evaluate scripts | js::Context |
| Inspect and convert script values | js::Value |
| Work directly with raw JavaScriptCore | View::LockJSContext() |
Classes | |
| class | API |
| A global JavaScript namespace for native functions and data. More... | |
| struct | APIOptions |
| Options for creating an API. More... | |
| class | Arg |
| An argument passed to a bound function. More... | |
| class | ArrayBuffer |
| Handle to a JavaScript ArrayBuffer for sharing raw binary memory with the page. More... | |
| struct | AttachOptions |
| Options for API::AttachTo(). More... | |
| class | BindingGuard |
| A binding tied to a C++ object's lifetime. More... | |
| class | CallInfo |
| Details of a call to a bound function: the context, this, and the raw arguments. More... | |
| class | ClassBuilder |
| Builder for exposing a C++ class to JavaScript. More... | |
| struct | ClassHolder |
| Type trait that selects the smart pointer type for owned instances of a bound class. More... | |
| class | Context |
| JavaScript execution environment for a page. More... | |
| struct | Doc |
| A documentation string for a registration (shown in API::schema()). More... | |
| struct | EnumRange |
| The range of values searched for an enum's enumerator names. More... | |
| class | Error |
| An error from a JavaScript operation. More... | |
| class | Eternal |
| Non-owning holder for bound-class singletons and program-lifetime objects. More... | |
| struct | HandleStats |
| Counts of the live handles on one context, for finding leaks (see Context::GetHandleStats()). More... | |
| struct | InjectionRequest |
| The details an API injection filter decides on (see SetInjectionFilter()). More... | |
| struct | NullType |
| Tag type for the JavaScript null value (see js::null). More... | |
| struct | Param |
| A parameter name for a registration (shown in API::schema() and in error messages). More... | |
| struct | PendingPromise |
| A new pending Promise and the Resolver that settles it (see Context::MakePromise()). More... | |
| class | Resolver |
| A handle that settles a JavaScript Promise. More... | |
| class | Task |
| A coroutine that returns a JavaScript Promise to the page. More... | |
| class | TypedArray |
| Handle to a JavaScript typed array on a page. More... | |
| struct | TypeTraits |
| Type conversions between C++ and JavaScript across the bridge. More... | |
| struct | TypeTraits< Color > |
| Color as CSS color text. More... | |
| struct | TypeTraits< dom::Element > |
| dom::Element as its JavaScript object. More... | |
| struct | TypeTraits< H, std::enable_if_t< detail::kIsCanonicalHolder< H > > > |
| Converts a bound class's canonical holder (see js::ClassHolder) with ownership. | |
| struct | TypeTraits< RefPtr< ultralight::Buffer > > |
| Marshals RefPtr<Buffer> as a JavaScript ArrayBuffer without copying in either direction. More... | |
| struct | TypeTraits< std::span< T >, std::enable_if_t< detail::kTypedArrayTypeOf< std::remove_const_t< T > > !=kULJSTypedArrayType_None > > |
| Marshals a typed-array argument as a std::span<T> without copying. | |
| struct | TypeTraits< String > |
| ultralight::String as a JavaScript string in UTF-8, the same as std::string. More... | |
| struct | TypeTraits< T *, std::enable_if_t< std::is_class_v< T > > > |
| Converts a pointer to a bound class as a borrowed instance (you keep ownership). More... | |
| struct | TypeTraits< URL > |
| URL as its canonical string (see URL::str()). More... | |
| struct | UndefinedType |
| Tag type for the JavaScript undefined value (see js::undefined). More... | |
| class | Value |
| A handle to a live JavaScript value. More... | |
| class | WeakValue |
| A weak reference to a JavaScript object. More... | |
Concepts | |
| concept | Holder |
| Whether or not H (ignoring const and references) is an owning holder: its ultralight::HolderTraits declares element_type, kind, and Get(). | |
| concept | LockableHolder |
| Whether or not H (ignoring const and references) is a weak holder: its ultralight::HolderTraits declares element_type and a Lock() that returns an owning holder. | |
| concept | Marshalable |
| Whether or not js::TypeTraits can convert T (ignoring const, volatile, and references). | |
Typedefs | |
| using | Diagnostics = DiagnosticsLevel |
| The diagnostics levels for an API. | |
| 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 JavaScript operation that can fail: a T or a js::Error. | |
Enumerations | |
| enum class | AttachFlags : unsigned { None = 0 , AllFrames = 1u << 1 , Mutable = 1u << 2 } |
| The flags for API::AttachTo() (the C++ form of ULJSAPIAttachFlags). More... | |
| enum class | ErrorType : unsigned { Error = 0 , TypeError , RangeError , SyntaxError , ReferenceError } |
| The type of a JavaScript error, matching the standard error constructors. More... | |
| enum class | PropertyAttributes : unsigned { None = kULJSPropertyAttributes_None , ReadOnly = kULJSPropertyAttributes_ReadOnly , DontEnum = kULJSPropertyAttributes_DontEnum , DontDelete = kULJSPropertyAttributes_DontDelete } |
| Attribute flags for a property created by Value::SetProperty(). More... | |
| enum class | Type : unsigned { Invalid = kULJSType_Invalid , Undefined = kULJSType_Undefined , Null = kULJSType_Null , Boolean = kULJSType_Boolean , Number = kULJSType_Number , String = kULJSType_String , Symbol = kULJSType_Symbol , BigInt = kULJSType_BigInt , Object = kULJSType_Object } |
| The type of a JavaScript value. More... | |
Functions | |
| constexpr AttachFlags | operator| (AttachFlags a, AttachFlags b) |
| Combine attach flags. | |
| constexpr AttachFlags & | operator|= (AttachFlags &a, AttachFlags b) |
| Add attach flags to a. | |
| template<typename F> | |
| void | SetInjectionFilter (View *view, F &&filter) |
| Set a View's API filter with a C++ callable (the typed form of View::SetJSAPIInjectionFilter()). | |
| void | ClearInjectionFilter (View *view) |
| Remove a View's API filter, so the origin rules alone decide which pages get the bindings. | |
| template<typename T, typename M> requires std::is_member_function_pointer_v<M> | |
| auto | Bind (T *instance, M method) |
| Bind a member function to an instance without writing a lambda. | |
| template<typename H, typename M> requires ((Holder<H> || LockableHolder<H>) && std::is_member_function_pointer_v<M>) | |
| auto | Bind (H holder, M method) |
| Bind a member function to an instance kept by a holder. | |
| template<typename Signature, typename C> | |
| constexpr auto | Overload (Signature C::*member) |
| Select one overload of a member function for ClassBuilder::Method(). | |
| template<typename T> | |
| ClassHolder< std::remove_cv_t< T > >::type | Detach (const Value &object) |
| Detach a bound-class instance from its wrapper and take ownership back. | |
| 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. | |
| template<typename T> | |
| Eternal (T *) -> Eternal< T > | |
| template<typename Fn> | |
| auto | RunOnWorker (Fn &&fn) |
| Run a function on a background thread, then resume the coroutine on the Renderer's thread with its return value: | |
| template<typename T = Value> requires Marshalable<T> | |
| auto | Await (const Value &promise) |
| Wait for a JavaScript promise from a Task: | |
| template<typename T = Value, typename R> requires (Marshalable<T> && std::is_same_v<std::remove_cvref_t<R>, Result<Value>>) | |
| auto | Await (R &&call) |
| Call a JavaScript function and wait for the Promise it returns, from a Task: | |
| constexpr PropertyAttributes | operator| (PropertyAttributes a, PropertyAttributes b) |
| Combine property attribute flags. | |
| bool | operator== (const Value &value, NullType) |
| Compare against the JavaScript null literal: if (v == js::null). | |
| bool | operator== (const Value &value, UndefinedType) |
| Compare against the JavaScript undefined literal: if (v == js::undefined). | |
| template<typename T> | |
| T | Or (const Value &value, T fallback) |
| Convert a value to a C++ type with a fallback (the free-function form of Value::Or()). | |
| std::string | Or (const Value &value, const char *fallback) |
| Convert a value to a std::string with a string-literal fallback. | |
| template<typename T> | |
| T | Or (const Arg &arg, T fallback) |
| Convert a callback argument to a C++ type with a fallback. | |
| std::string | Or (const Arg &arg, const char *fallback) |
| Convert a callback argument to a std::string with a string-literal fallback. | |
| template<typename R, typename T> requires std::is_same_v<std::remove_cvref_t<R>, Result<Value>> | |
| T | Or (const R &result, T fallback) |
| Convert the value a call returned to a C++ type with a fallback. | |
| template<typename R> requires std::is_same_v<std::remove_cvref_t<R>, Result<Value>> | |
| std::string | Or (const R &result, const char *fallback) |
| Convert the value a call returned to a std::string with a string-literal fallback. | |
| template<typename T, typename U> requires (!std::is_same_v<T, Value>) | |
| T | Or (const Result< T > &result, U &&fallback) |
| Get a typed Result's value or fallback if it holds an error. | |
| Value | ExceptionValue (const Error &error) |
| Get the value a JavaScript exception threw, to keep it or pass it back to the page. | |
Variables | |
| constexpr AttachFlags | AllFrames = AttachFlags::AllFrames |
| Shorthand for AttachFlags::AllFrames. | |
| constexpr AttachFlags | Mutable = AttachFlags::Mutable |
| Shorthand for AttachFlags::Mutable. | |
| constexpr NullType | null {} |
| The JavaScript null value. | |
| constexpr UndefinedType | undefined {} |
| The JavaScript undefined value. | |
| using Diagnostics = DiagnosticsLevel |
The diagnostics levels for an API.
Diagnostics are development warnings, written to the native logger and to the page's console. Each level does everything the level below it does.
Warn reports mistakes that still run:
Strict also turns two caller mistakes into TypeErrors:
A lossy return value still only warns, since the page can't fix a native return type.
Auto (the default) uses the JavaScript level in Config::diagnostics, which is Warn in developer mode and Off otherwise (see DiagnosticsConfig).
Two warnings follow the Config's JavaScript level instead: an operation on a handle whose page is gone, and a JavaScript exception that nothing read. Mistakes found once at registration (an invalid or reserved root path, an invalid binding path, a missing callback) always warn, whatever the level.
| using Expected = ultralight::detail::Expected<T, E> |
A value of type T or an error of type E (like std::expected).
The result of a JavaScript operation that can fail: a T or a js::Error.
Result is js::Expected<T, js::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.
|
strong |
The flags for API::AttachTo() (the C++ form of ULJSAPIAttachFlags).
|
strong |
The type of a JavaScript error, matching the standard error constructors.
| Enumerator | |
|---|---|
| Error | A plain Error, or an error type with no dedicated constant. |
| TypeError | |
| RangeError | |
| SyntaxError | |
| ReferenceError | |
|
strong |
Attribute flags for a property created by Value::SetProperty().
Combine them with |:
| Enumerator | |
|---|---|
| None | No flags (a normal property). |
| ReadOnly | Script can't change its value. |
| DontEnum | Hidden from for...in and Object.keys. |
| DontDelete | Script can't delete it. |
|
strong |
The type of a JavaScript value.
Later versions may add types, so handle a value you don't know (eg, with a default case).
| Enumerator | |
|---|---|
| Invalid | An empty Value, or one whose page is gone. |
| Undefined | |
| Null | |
| Boolean | |
| Number | |
| String | |
| Symbol | |
| BigInt | |
| Object | |
| auto Await | ( | const Value & | promise | ) |
Wait for a JavaScript promise from a Task:
The Task resumes on the Renderer's thread during a Renderer::Update() after the promise settles. The Result holds the value converted to T, or an Error: the rejection reason, a TypeError if the value doesn't convert, or a page-gone Error if the page goes away first.
Like JavaScript's await, this also takes a value that isn't a Promise. A value that isn't an object resumes the Task right away with that value. Any other object (eg, a thenable) goes through the page's Promise.resolve() first, which can run page code.
| promise | The promise (or other value) to wait for. |
| auto Await | ( | R && | call | ) |
Call a JavaScript function and wait for the Promise it returns, from a Task:
This waits for the call's result like the overload above. If the call itself fails (it throws, or the function is empty or its page is gone), the Task resumes right away with that Error.
| call | The result of the call (a js::Result<js::Value>). |
| auto Bind | ( | H | holder, |
| M | method ) |
Bind a member function to an instance kept by a holder.
Any smart pointer with an ultralight::HolderTraits specialization works, built-in or your own:
A method that returns js::Task<T> keeps the instance alive until its Task finishes, in both forms (the weak form keeps the locked holder), even if the binding is removed meanwhile. A method that takes a trailing js::Resolver binds in both forms too, but the weak form keeps the instance only during the call, not until the Resolver settles.
| holder | The holder to call the method through (copied into the binding). |
| method | The member function pointer. |
| auto Bind | ( | T * | instance, |
| M | method ) |
Bind a member function to an instance without writing a lambda.
How you pass the instance decides who keeps it alive:
The result is an ordinary callable that you can bind anywhere a lambda works. A method that returns js::Task<T> or takes a trailing js::Resolver binds as an async function in every form.
| instance | The object to call the method on. It must outlive every call through the binding. |
| method | The member function pointer. |
|
inline |
| ClassHolder< std::remove_cv_t< T > >::type Detach | ( | const Value & | object | ) |
Detach a bound-class instance from its wrapper and take ownership back.
After this, calls on the wrapper throw a TypeError with code ULJS_DETACHED instead of reaching the instance. Use it to write close methods (see "Closing an Instance" in js::ClassBuilder), and to detach a borrowed instance's wrapper before you free the instance.
Each page has its own wrapper for an instance, and this detaches only the one you pass. To get an instance's wrapper on a page, convert its pointer there (js::Detach<T>(ctx.Make(ptr))), so before you free a borrowed instance, detach its wrapper on every page you gave it to.
| object | The instance's wrapper. |
| Eternal | ( | T * | ) | -> Eternal< T > |
Get the value a JavaScript exception threw, to keep it or pass it back to the page.
| error | The error. |
|
inline |
Compare against the JavaScript undefined literal: if (v == js::undefined).
|
constexpr |
Combine attach flags.
|
constexpr |
Combine property attribute flags.
|
constexpr |
Add attach flags to a.
|
inlinenodiscard |
Convert a callback argument to a std::string with a string-literal fallback.
| arg | The argument to convert. |
| fallback | The text to return if the conversion fails. |
|
nodiscard |
Convert a callback argument to a C++ type with a fallback.
| arg | The argument to convert. |
| fallback | The value to return if the conversion fails. |
|
nodiscard |
Convert the value a call returned to a std::string with a string-literal fallback.
| result | The call's result. |
| fallback | The text to return if the call or the conversion failed. |
|
nodiscard |
Convert the value a call returned to a C++ type with a fallback.
| result | The call's result. |
| fallback | The value to return if the call or the conversion failed. |
|
nodiscard |
Get a typed Result's value or fallback if it holds an error.
This is the same as result.value_or(fallback) and lets a typed call read like an untyped one: js::Or(fn.Invoke<double>(3, 4), 0.0).
| result | The typed result. |
| fallback | The value to return if the result holds an error. |
|
inlinenodiscard |
Convert a value to a std::string with a string-literal fallback.
| value | The value to convert. |
| fallback | The text to return if the conversion fails. |
|
nodiscard |
Convert a value to a C++ type with a fallback (the free-function form of Value::Or()).
This takes a Value, a Value::Ref, a js::Arg, or the Result of a call. The value must already have the requested JavaScript type (see Value::To()). Any failure returns fallback (eg, a missing property or a failed call):
| value | The value to convert. |
| fallback | The value to return if the conversion fails. |
|
nodiscard |
Get a Result's value, or a default-constructed T if it holds an error.
Use this where an empty value is a fine way to mark failure (every operation on an empty Value fails safely):
| result | The Result to read. |
|
constexpr |
Select one overload of a member function for ClassBuilder::Method().
Write the overload's signature as the template argument:
| member | The overloaded member function. |
| auto RunOnWorker | ( | Fn && | fn | ) |
Run a function on a background thread, then resume the coroutine on the Renderer's thread with its return value:
Unlike js::Await() and awaiting a Task, this gives you the function's return value directly (not a Result), so report failures inside that value or, with C++ exceptions enabled, by throwing.
| fn | The function to run. It takes no arguments. |
| void SetInjectionFilter | ( | View * | view, |
| F && | filter ) |
Set a View's API filter with a C++ callable (the typed form of View::SetJSAPIInjectionFilter()).
The View calls the filter each time it's about to add an attached API's bindings to a page: when a page loads, when you attach an API, and when a page returns from the back-forward cache. The origin rules run first and their verdict arrives in rules_allow. Return true to add the bindings or false to withhold them, whatever the rules decided. Use it for decisions that origin rules can't express, such as a user setting or allowing a page whose origin is opaque.
| view | The View to set the filter on (nothing happens if it's nullptr). |
| filter | A callable invocable as bool(const js::InjectionRequest&). The new filter replaces (and destroys) the previous one. |
|
inlineconstexpr |
Shorthand for AttachFlags::AllFrames.
|
inlineconstexpr |
Shorthand for AttachFlags::Mutable.
|
inlineconstexpr |
|
inlineconstexpr |