docs
Loading...
Searching...
No Matches
Context.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#include <Ultralight/CAPI/CAPI_JSAPI.h>
7#include <Ultralight/CAPI/CAPI_JSRuntime.h>
8#include <Ultralight/CAPI/CAPI_JSValue.h>
9#include <Ultralight/CAPI/CAPI_String.h>
10#include <Ultralight/View.h>
11#include <Ultralight/detail/Exceptions.h>
12#include <Ultralight/js/API.h>
15#include <Ultralight/js/Error.h>
18#include <Ultralight/js/Value.h>
19
20#include <cstddef>
21#include <initializer_list>
22#include <span>
23#include <string_view>
24#include <type_traits>
25#include <utility>
26#include <vector>
27
28namespace ultralight {
29namespace js {
30
31///
32/// Counts of the live handles on one context, for finding leaks (see Context::GetHandleStats()).
33///
34/// \parblock
35/// @note Copies of one js::Value count once, and the counts include a few handles the library
36/// holds for you (eg, for a Promise made with Context::MakePromise()).
37/// \endparblock
38///
39/// \parblock
40/// @note A destroyed handle can stay counted until the next Renderer::Update().
41/// \endparblock
42///
44 size_t total_values = 0; ///< Live value handles.
45 size_t values_by_type[kULJSType_Count] = {}; ///< Live value handles by js::Type (see count()).
46 size_t weak_refs = 0; ///< Live weak references (0 once the context is gone).
47
48 ///
49 /// Get the number of live value handles of one type.
50 ///
51 /// @param type The value type.
52 ///
53 /// @return Returns the number of live value handles of that type.
54 ///
55 size_t count(Type type) const {
56 size_t index = static_cast<size_t>(type);
57 return index < kULJSType_Count ? values_by_type[index] : 0;
58 }
59
60 ///
61 /// Count the value handles that keep something from being garbage collected (strings,
62 /// symbols, BigInts, and objects).
63 ///
64 /// @return Returns the number of those handles.
65 ///
70};
71
72///
73/// A new pending Promise and the Resolver that settles it (see Context::MakePromise()).
74///
76 Value promise; ///< The Promise to hand to the page.
77 Resolver resolver; ///< Settles `promise` (from any thread).
78};
79
80///
81/// JavaScript execution environment for a page.
82///
83/// Every call into a page's JavaScript environment goes through its Context. It represents the
84/// execution state of a loaded document, providing access to the global object where page functions
85/// and variables live.
86///
87/// Construct a Context from a View inside LoadListener::OnDOMReady() to call functions and read
88/// global variables on the page:
89///
90/// ```
91/// void MyApp::OnDOMReady(View* caller, uint64_t frame_id, bool is_main_frame,
92/// const String& url) {
93/// if (!is_main_frame)
94/// return;
95///
96/// js::Context ctx(caller);
97/// ctx["ShowMessage"]("Howdy!"); // call a page function
98/// double score = js::Or(ctx["score"], 0.0); // read a global (0.0 if it fails)
99/// double doubled = js::Or(ctx.Evaluate<double>("score * 2"), 0.0);
100/// }
101/// ```
102///
103/// ## Getting a Context
104///
105/// Constructing a Context with a View wraps the main frame's JavaScript environment. To access the
106/// Context of a subframe or a specific document, pass that document to dom::GetJSContext().
107///
108/// You'll typically construct a Context inside a LoadListener callback:
109///
110/// - **Use LoadListener::OnDOMReady() for work that needs the document or its scripts.** It fires
111/// once the DOM is fully parsed and page scripts have run.
112/// - **Use LoadListener::OnWindowObjectReady() to set up global state early.** It fires before the
113/// page's own scripts run.
114///
115/// Each page gets its own Context. When a View navigates to a new page, the old Context's page is
116/// gone, along with every Value created from it (see js::Value for what that means), so you'll need
117/// to obtain a new Context for the new page. Operations on a Context whose page is gone fail safely
118/// instead of crashing.
119///
120/// ## Creating Values
121///
122/// Call Make() to convert a native C++ value into a JavaScript Value. The method converts any type
123/// that js::TypeTraits supports, including numbers, strings, standard containers, reflected
124/// structs, and enums.
125///
126/// Convert a reflected struct to a JavaScript object and pass it to a page function:
127///
128/// ```
129/// struct HudSettings {
130/// std::string theme;
131/// double volume;
132/// };
133///
134/// js::Value settings = ctx.Make(HudSettings { "dark", 0.8 });
135/// ctx["applySettings"](settings);
136/// ```
137///
138/// \parblock
139/// @note Context operations must run on the Renderer's thread. To dispatch work from another
140/// thread, call PostTask() to schedule a callback that runs during a later
141/// Renderer::Update().
142/// \endparblock
143///
144/// \parblock
145/// @note js::Context and dom::data::Context are unrelated types (dom::data::Context manages
146/// declarative data bindings).
147/// \endparblock
148///
149/// @see js::Value, js::CallInfo::context(), dom::GetJSContext(), LoadListener::OnDOMReady()
150///
151class Context {
152 public:
153 ///
154 /// Create an empty Context.
155 ///
156 Context() = default;
157
158 ///
159 /// Get the context of a View's main frame.
160 ///
161 /// @param view The View. The Context is empty if `view` is NULL or its page can't run script
162 /// (JavaScript is disabled or the document is sandboxed).
163 ///
164 /// @note A Context belongs to the page loaded now. After the View loads a new page, get a new
165 /// Context.
166 ///
167 explicit Context(View* view) : handle_(view ? view->GetJSContext() : nullptr) {}
168
169 ///
170 /// Get the context a value belongs to.
171 ///
172 /// @param value The value. An empty Value gives an empty Context, and a Value whose page is
173 /// gone gives a Context whose page is also gone.
174 ///
175 explicit Context(const Value& value)
176 : handle_(value.raw() ? ulJSValueGetContext(value.raw()) : nullptr) {}
177
178 // --- Interop with the C API (most embedders never touch raw handles) -------------------
179
180 ///
181 /// Take ownership of a context handle from the C API.
182 ///
183 /// @param handle The handle to take ownership of.
184 ///
185 /// @return Returns a Context that owns `handle`.
186 ///
187 /// @warning Don't pass a handle the library owns (eg, one a callback receives). Use
188 /// FromBorrowed() for that.
189 ///
190 static Context Adopt(ULJSContext handle) { return Context(handle); }
191
192 ///
193 /// Add a reference to a context handle the library owns (eg, the context a C API callback
194 /// receives) so you can use it with this class and keep it after the callback.
195 ///
196 /// @param handle The borrowed handle.
197 ///
198 /// @return Returns a Context with its own reference to `handle`.
199 ///
201 return Context(handle ? ulCreateJSContextRef(handle) : nullptr);
202 }
203
204 ///
205 /// Copy constructor (refers to the same context).
206 ///
207 Context(const Context& other)
208 : handle_(other.handle_ ? ulCreateJSContextRef(other.handle_) : nullptr) {}
209
210 ///
211 /// Move constructor (`other` becomes empty).
212 ///
213 Context(Context&& other) noexcept : handle_(other.handle_) { other.handle_ = nullptr; }
214
215 ///
216 /// Assignment (copies or moves `other` into this Context).
217 ///
218 Context& operator=(Context other) noexcept {
219 std::swap(handle_, other.handle_);
220 return *this;
221 }
222
223 ///
224 /// Destructor (releases this handle).
225 ///
226 ~Context() { ulDestroyJSContext(handle_); }
227
228 ///
229 /// Whether or not this Context is valid (it isn't empty and its page is still alive).
230 ///
231 explicit operator bool() const { return handle_ && ulJSContextIsAlive(handle_); }
232
233 ///
234 /// Whether or not this Context holds nothing.
235 ///
236 bool IsEmpty() const { return handle_ == nullptr; }
237
238 ///
239 /// Whether or not this Context's page is still alive (the same test as `operator bool`).
240 ///
241 /// @note Safe to call from any thread, but off the Renderer's thread the result may already
242 /// be out of date when you act on it.
243 ///
244 bool IsAlive() const { return handle_ && ulJSContextIsAlive(handle_); }
245
246 ///
247 /// Run a script and get its completion value.
248 ///
249 /// @param script The script (UTF-8; embedded null characters are kept).
250 ///
251 /// @param source_url A URL for the script, used in error reports (may be NULL).
252 ///
253 /// @return Returns the script's completion value. Fails with a JavaScript exception if the
254 /// script throws.
255 ///
256 [[nodiscard]] Result<Value> Evaluate(std::string_view script,
257 const char* source_url = nullptr) const {
258 if (!handle_)
259 return detail::EmptyHandleError();
260 ULString source = ulCreateStringUTF8(script.data(), script.size());
261 ULJSValue exception = nullptr;
262 ULJSValue result = ulJSContextEvaluate(handle_, source, source_url, &exception);
263 ulDestroyString(source);
264 if (!result) {
265 if (exception)
266 return Unexpected<Error>(Error::AdoptException(exception));
267 return Unexpected<Error>(Error::PageGone());
268 }
269 return Value::Adopt(result);
270 }
271
272 ///
273 /// Run a script and convert its completion value to a C++ type (see Value::To()).
274 ///
275 /// ```
276 /// js::Result<double> health = ctx.Evaluate<double>("game.player.health");
277 /// double speed = ctx.Evaluate<double>("game.player.speed").value_or(1.0);
278 /// ```
279 ///
280 /// @param script The script (UTF-8; embedded null characters are kept).
281 ///
282 /// @param source_url A URL for the script, used in error reports (may be NULL).
283 ///
284 /// @return Returns the converted value. Fails with a JavaScript exception if the script
285 /// throws, or with a TypeError if the value doesn't convert to T.
286 ///
287 template <typename T>
288 requires Marshalable<T>
289 [[nodiscard]] Result<T> Evaluate(std::string_view script,
290 const char* source_url = nullptr) const {
291 Result<Value> completion = Evaluate(script, source_url);
292 if (!completion)
293 return Unexpected<Error>(std::move(completion).error());
294 return completion.value().To<T>();
295 }
296
297 ///
298 /// Get the global object.
299 ///
300 /// @return Returns the global object (an empty Value if the context is gone).
301 ///
303 return Value::Adopt(ulJSContextGetGlobalObject(handle_));
304 }
305
306 ///
307 /// Access a property of the global object (`ctx["fn"](args)` is the same as
308 /// `ctx.GlobalObject()["fn"](args)`):
309 ///
310 /// ```
311 /// ctx["ShowMessage"]("Howdy!"); // `this` = the global object
312 /// double score = js::Or(ctx["score"], 0.0);
313 /// double total = js::Or(ctx["computeTotal"](3, 4), 0.0);
314 /// ```
315 ///
316 /// @param name The property name.
317 ///
318 /// @return Returns a Value::Ref for the property.
319 ///
320 Value::Ref operator[](const char* name) const {
321 Value global = GlobalObject();
322 Value::Ref ref = global[name];
323 // The global object reads empty only when the context's page is gone.
324 ref.source_gone_ = handle_ && global.IsEmpty();
325 return ref;
326 }
327
328 ///
329 /// Convert a C++ value to a JavaScript value through js::TypeTraits.
330 ///
331 /// This works for every supported type, including reflected structs, enums, containers,
332 /// js::null, and js::undefined.
333 ///
334 /// @param value The C++ value to convert.
335 ///
336 /// @return Returns the new value (an empty Value if the context is gone).
337 ///
338 template <typename T>
339 Value Make(T&& value) const {
340 using U = std::decay_t<T>;
341 detail::AssertInteropHeader<U>();
342 static_assert(Marshalable<U>,
343 "no js::TypeTraits for T: use a supported built-in, make it a plain "
344 "aggregate struct, or specialize js::TypeTraits for it");
345 return Value::Adopt(handle_ ? TypeTraits<U>::ToJS(handle_, value) : nullptr);
346 }
347
348 ///
349 /// Create a new empty JavaScript object.
350 ///
351 /// @return Returns the new object (an empty Value if the context is gone).
352 ///
353 Value MakeObject() const { return Value::Adopt(ulCreateJSObject(handle_)); }
354
355 ///
356 /// Create a new JavaScript Array.
357 ///
358 /// @param elements The elements (an empty Value becomes `undefined`).
359 ///
360 /// @param count The number of entries in `elements`.
361 ///
362 /// @return Returns the new Array (an empty Value if the context or an element's page is gone).
363 ///
364 Value MakeArray(const Value* elements, size_t count) const {
365 if (!handle_)
366 return Value();
367 std::vector<ULJSValue> raw(count);
368 for (size_t i = 0; i < count; i++)
369 raw[i] = elements[i].raw();
370 return Value::Adopt(ulCreateJSArray(handle_, count ? raw.data() : nullptr, count));
371 }
372
373 ///
374 /// Create a new JavaScript Array from a brace list (eg, `ctx.MakeArray({ a, b })`).
375 ///
376 /// @param elements The elements.
377 ///
378 /// @return Returns the new Array (an empty Value if the context or an element's page is gone).
379 ///
380 Value MakeArray(std::initializer_list<Value> elements) const {
381 return MakeArray(elements.begin(), elements.size());
382 }
383
384 ///
385 /// Create a new JavaScript Array from a range (eg, a `std::vector<js::Value>`).
386 ///
387 /// @param elements The elements.
388 ///
389 /// @return Returns the new Array (an empty Value if the context or an element's page is gone).
390 ///
391 Value MakeArray(std::span<const Value> elements) const {
392 return MakeArray(elements.data(), elements.size());
393 }
394
395 ///
396 /// Create a value from JSON text (the reverse of Value::ToJSON()):
397 ///
398 /// ```
399 /// js::Value config = js::OrEmpty(ctx.MakeFromJSON(R"({"volume": 5, "muted": false})"));
400 /// ```
401 ///
402 /// @param json The JSON text (any JSON value).
403 ///
404 /// @return Returns the new value. Fails with a SyntaxError (a JavaScript exception) if the
405 /// JSON is invalid.
406 ///
407 [[nodiscard]] Result<Value> MakeFromJSON(std::string_view json) const {
408 if (!handle_)
409 return detail::EmptyHandleError();
410 ULString text = ulCreateStringUTF8(json.data(), json.length());
411 ULJSValue exception = nullptr;
412 ULJSValue result = ulCreateJSValueFromJSON(handle_, text, &exception);
413 ulDestroyString(text);
414 if (!result) {
415 if (exception)
416 return Unexpected<Error>(Error::AdoptException(exception));
417 return Unexpected<Error>(Error::PageGone());
418 }
419 return Value::Adopt(result);
420 }
421
422 ///
423 /// Run a function with this context during a later Renderer::Update().
424 ///
425 /// Use this to touch JavaScript from another thread:
426 ///
427 /// ```
428 /// ctx.PostTask([](js::Context& live) {
429 /// live["progress"] = 0.5;
430 /// });
431 /// ```
432 ///
433 /// @param task The function to run. It can take the live js::Context or nothing.
434 ///
435 /// \parblock
436 /// @note Safe to call from any thread. Tasks run in the order they were posted.
437 /// \endparblock
438 ///
439 /// \parblock
440 /// @note If the context goes away before the task runs, the task is destroyed without running.
441 /// \endparblock
442 ///
443 template <typename F>
444 void PostTask(F&& task) const {
445 using Fn = std::decay_t<F>;
446 static_assert(std::is_invocable_v<Fn&> || std::is_invocable_v<Fn&, Context&>,
447 "js::Context::PostTask takes a callable invocable with nothing or with "
448 "js::Context&");
449 ulJSContextPostTask(handle_, &TaskThunk<Fn>, new Fn(std::forward<F>(task)),
450 &DeleteTaskCallable<Fn>);
451 }
452
453 ///
454 /// Create a pending Promise and the Resolver that settles it, to hand a Promise to the page
455 /// outside a bound function:
456 ///
457 /// ```
458 /// auto [promise, resolver] = ctx.MakePromise();
459 /// ctx["ready"] = promise;
460 /// // later, from any thread:
461 /// resolver.Resolve(std::string("ok"));
462 /// ```
463 ///
464 /// @return Returns the Promise and its Resolver (both empty if the context is gone).
465 ///
467 ULJSPromiseResolver raw = nullptr;
468 ULJSValue promise = handle_ ? ulCreateJSPromise(handle_, &raw) : nullptr;
469 if (!promise)
470 return {};
471 return PendingPromise { Value::Adopt(promise), Resolver::Adopt(raw) };
472 }
473
474 ///
475 /// Create an ArrayBuffer that shares a Buffer's bytes with JavaScript without copying.
476 ///
477 /// The ArrayBuffer keeps a reference to `buffer` until it's garbage collected or detached
478 /// (see "Byte Lifetimes" on js::ArrayBuffer).
479 ///
480 /// @param buffer The buffer to share. An empty buffer gives an ordinary empty ArrayBuffer
481 /// that keeps no reference.
482 ///
483 /// @return Returns a new ArrayBuffer over the buffer's bytes (an empty wrapper if `buffer`
484 /// is null or the context is gone).
485 ///
487 if (!handle_)
488 return ArrayBuffer();
489 return ArrayBuffer(
490 Value::Adopt(detail::WrapBufferThrough(handle_, buffer, [&](ULBuffer shared) {
491 return ulCreateJSArrayBufferFromBuffer(handle_, shared);
492 })));
493 }
494
495 ///
496 /// Create an ArrayBuffer holding a copy of the given bytes.
497 ///
498 /// @param bytes The bytes to copy (may be NULL only when `length` is 0).
499 ///
500 /// @param length The number of bytes to copy (0 creates an empty ArrayBuffer).
501 ///
502 /// @return Returns a new ArrayBuffer (an empty wrapper if `bytes` is NULL and `length`
503 /// isn't 0, or if the context is gone).
504 ///
505 ArrayBuffer MakeArrayBuffer(const void* bytes, size_t length) const {
506 return ArrayBuffer(Value::Adopt(ulCreateJSArrayBuffer(handle_, bytes, length)));
507 }
508
509 ///
510 /// Create a typed array of zero-filled elements of type `T` (eg, `MakeTypedArray<float>(4)`
511 /// creates a Float32Array; see js::TypedArray for the element types).
512 ///
513 /// @param length The number of elements (not bytes).
514 ///
515 /// @return Returns a new TypedArray (an empty wrapper if the context is gone).
516 ///
517 template <typename T>
518 TypedArray<T> MakeTypedArray(size_t length) const {
519 return TypedArray<T>(
520 Value::Adopt(ulCreateJSTypedArray(handle_, detail::kTypedArrayTypeOf<T>, length)));
521 }
522
523 ///
524 /// Create a typed array of elements of type `T` that shares a Buffer's bytes with JavaScript
525 /// without copying.
526 ///
527 /// Lifetime works as for MakeArrayBuffer().
528 ///
529 /// @param buffer The buffer to share (its size must be a multiple of `sizeof(T)`). An empty
530 /// buffer gives an ordinary empty typed array that keeps no reference.
531 ///
532 /// @return Returns a new TypedArray over the buffer's bytes (an empty wrapper if `buffer`
533 /// is null, its size isn't a multiple of `sizeof(T)`, or the context is gone).
534 ///
535 template <typename T>
537 if (!handle_)
538 return TypedArray<T>();
539 return TypedArray<T>(
540 Value::Adopt(detail::WrapBufferThrough(handle_, buffer, [&](ULBuffer shared) {
541 return ulCreateJSTypedArrayFromBuffer(handle_, detail::kTypedArrayTypeOf<T>, shared);
542 })));
543 }
544
545 ///
546 /// Create a JavaScript function backed by a C++ callable, to hand to the page (eg, as a
547 /// callback). Arguments convert the same way as for a js::API binding:
548 ///
549 /// ```
550 /// js::Value cb = ctx.MakeFunction("onTick", [](double dt) { ... });
551 /// ```
552 ///
553 /// @param name The function's `name`, also used in its conversion errors.
554 ///
555 /// @param fn The callable.
556 ///
557 /// @return Returns the function (an empty Value if the context is gone).
558 ///
559 /// \parblock
560 /// @note Only synchronous callables work here (returning a value or a js::Result). Bind async
561 /// functions (a js::Task or a trailing js::Resolver) through js::API.
562 /// \endparblock
563 ///
564 /// \parblock
565 /// @note The callable is destroyed on the Renderer's thread after the function is garbage
566 /// collected.
567 /// \endparblock
568 ///
569 template <typename Fn>
570 Value MakeFunction(const char* name, Fn&& fn) const {
571 using F = std::decay_t<Fn>;
572 using Traits = detail::CallableTraits<F>;
573 using Shape = detail::ParamShape<typename Traits::Params>;
574 static_assert(!Shape::kHasResolver
575 && !detail::kIsAsyncReturn<typename Traits::Return>,
576 "MakeFunction binds synchronous callables; bind async forms (js::Task, "
577 "trailing js::Resolver) through js::API");
578 [&]<size_t... Is>(std::index_sequence<Is...>) {
579 (detail::ValidateParam<std::tuple_element_t<Is, typename Shape::Converted>>(), ...);
580 }(std::make_index_sequence<Shape::kCount> {});
581 if (!handle_)
582 return Value();
583 auto* bound = new detail::BoundCallable<F> { std::forward<Fn>(fn),
584 std::string(name ? name : ""), {}, {} };
585 return Value::Adopt(ulCreateJSFunction(handle_, name, &detail::SyncTrampoline<F>, bound,
586 &detail::DestroyBoundCallable<F>));
587 }
588
589 ///
590 /// Count the live handles on this context, for finding leaks.
591 ///
592 /// Value handles you never destroy keep counting after the page goes away.
593 ///
594 /// @return Returns the counts (all zero for an empty Context).
595 ///
596 /// @see HandleStats
597 ///
599 HandleStats stats = {};
600 ULJSHandleStats raw_stats = {};
601 if (handle_ && ulJSContextGetHandleStats(handle_, &raw_stats)) {
602 stats.total_values = raw_stats.total_values;
603 for (size_t i = 0; i < kULJSType_Count; i++)
604 stats.values_by_type[i] = raw_stats.values_by_type[i];
605 stats.weak_refs = raw_stats.weak_refs;
606 }
607 return stats;
608 }
609
610 ///
611 /// Get the C API handle without transferring ownership.
612 ///
613 /// @return Returns the handle.
614 ///
615 ULJSContext raw() const { return handle_; }
616
617 ///
618 /// Give up ownership of the C API handle and return it.
619 ///
620 /// @return Returns the handle. You must call ulDestroyJSContext() when finished.
621 ///
623 ULJSContext handle = handle_;
624 handle_ = nullptr;
625 return handle;
626 }
627
628 private:
629 explicit Context(ULJSContext handle) : handle_(handle) {}
630
631 template <typename Fn>
632 static void TaskThunk(void* user_data, ULJSContext ctx) {
633 Fn& fn = *static_cast<Fn*>(user_data);
634 // The task runs inside the library's update: an exception must not unwind into it.
635 ultralight::detail::CallCatchingExceptions(
636 [&] {
637 if constexpr (std::is_invocable_v<Fn&, Context&>) {
638 Context borrowed = Context::FromBorrowed(ctx);
639 fn(borrowed);
640 } else {
641 fn();
642 }
643 },
644 [](const char* what) { detail::LogNativeException("js::Context::PostTask", what); });
645 }
646
647 template <typename Fn>
648 static void DeleteTaskCallable(void* user_data) {
649 delete static_cast<Fn*>(user_data);
650 }
651
652 ULJSContext handle_ = nullptr;
653};
654
656 return Context::FromBorrowed(ctx_);
657}
658
659} // namespace js
660} // namespace ultralight
struct C_JSContext * ULJSContext
Opaque handle to a JavaScript execution context (one page's script world in one View).
Definition View.h:25
A nullable smart pointer.
Definition RefPtr.h:126
Web-page container rendered to an offscreen surface.
Definition View.h:483
Handle to a JavaScript ArrayBuffer for sharing raw binary memory with the page.
Definition Buffer.h:88
ArrayBuffer()=default
Create an empty ArrayBuffer wrapper.
Context context() const
Get the calling context, to create values in it or to keep it after the call:
Definition Context.h:655
JavaScript execution environment for a page.
Definition Context.h:151
Value::Ref operator[](const char *name) const
Access a property of the global object (ctx["fn"](args) is the same as ctx.GlobalObject()["fn"](args)...
Definition Context.h:320
Value MakeArray(std::span< const Value > elements) const
Create a new JavaScript Array from a range (eg, a std::vector<js::Value>).
Definition Context.h:391
TypedArray< T > MakeTypedArray(const RefPtr< ultralight::Buffer > &buffer) const
Create a typed array of elements of type T that shares a Buffer's bytes with JavaScript without copyi...
Definition Context.h:536
Value Make(T &&value) const
Convert a C++ value to a JavaScript value through js::TypeTraits.
Definition Context.h:339
Value GlobalObject() const
Get the global object.
Definition Context.h:302
ArrayBuffer MakeArrayBuffer(const RefPtr< ultralight::Buffer > &buffer) const
Create an ArrayBuffer that shares a Buffer's bytes with JavaScript without copying.
Definition Context.h:486
Value MakeArray(const Value *elements, size_t count) const
Create a new JavaScript Array.
Definition Context.h:364
Result< Value > Evaluate(std::string_view script, const char *source_url=nullptr) const
Run a script and get its completion value.
Definition Context.h:256
Value MakeArray(std::initializer_list< Value > elements) const
Create a new JavaScript Array from a brace list (eg, ctx.MakeArray({ a, b })).
Definition Context.h:380
Context(const Context &other)
Copy constructor (refers to the same context).
Definition Context.h:207
ULJSContext raw() const
Get the C API handle without transferring ownership.
Definition Context.h:615
Context()=default
Create an empty Context.
Context & operator=(Context other) noexcept
Assignment (copies or moves other into this Context).
Definition Context.h:218
Context(Context &&other) noexcept
Move constructor (other becomes empty).
Definition Context.h:213
static Context Adopt(ULJSContext handle)
Take ownership of a context handle from the C API.
Definition Context.h:190
bool IsEmpty() const
Whether or not this Context holds nothing.
Definition Context.h:236
bool IsAlive() const
Whether or not this Context's page is still alive (the same test as operator bool).
Definition Context.h:244
HandleStats GetHandleStats() const
Count the live handles on this context, for finding leaks.
Definition Context.h:598
Value MakeObject() const
Create a new empty JavaScript object.
Definition Context.h:353
PendingPromise MakePromise() const
Create a pending Promise and the Resolver that settles it, to hand a Promise to the page outside a bo...
Definition Context.h:466
Context(View *view)
Get the context of a View's main frame.
Definition Context.h:167
Value MakeFunction(const char *name, Fn &&fn) const
Create a JavaScript function backed by a C++ callable, to hand to the page (eg, as a callback).
Definition Context.h:570
Context(const Value &value)
Get the context a value belongs to.
Definition Context.h:175
~Context()
Destructor (releases this handle).
Definition Context.h:226
void PostTask(F &&task) const
Run a function with this context during a later Renderer::Update().
Definition Context.h:444
Result< T > Evaluate(std::string_view script, const char *source_url=nullptr) const
Run a script and convert its completion value to a C++ type (see Value::To()).
Definition Context.h:289
Result< Value > MakeFromJSON(std::string_view json) const
Create a value from JSON text (the reverse of Value::ToJSON()):
Definition Context.h:407
static Context FromBorrowed(ULJSContext handle)
Add a reference to a context handle the library owns (eg, the context a C API callback receives) so y...
Definition Context.h:200
ArrayBuffer MakeArrayBuffer(const void *bytes, size_t length) const
Create an ArrayBuffer holding a copy of the given bytes.
Definition Context.h:505
ULJSContext LeakRef()
Give up ownership of the C API handle and return it.
Definition Context.h:622
TypedArray< T > MakeTypedArray(size_t length) const
Create a typed array of zero-filled elements of type T (eg, MakeTypedArray<float>(4) creates a Float3...
Definition Context.h:518
static Error AdoptException(ULJSValue exception)
Create an error from a JavaScript exception, taking ownership of the handle.
Definition Error.h:131
static Error PageGone()
Create a page-gone error (is_page_gone() returns true).
Definition Error.h:122
A handle that settles a JavaScript Promise.
Definition Resolver.h:97
static Resolver Adopt(ULJSPromiseResolver handle)
Take ownership of a resolver handle from the C API.
Definition Resolver.h:120
Handle to a JavaScript typed array on a page.
Definition Buffer.h:203
TypedArray()=default
Create an empty TypedArray wrapper.
A reference to a property of a Value (returned by Value::operator[]).
Definition Value.h:906
A handle to a live JavaScript value.
Definition Value.h:210
static Value Adopt(ULJSValue handle)
Take ownership of a handle from the C API without adding a reference.
Definition Value.h:799
bool IsEmpty() const
Whether or not this Value holds nothing (see "Handle States" above).
Definition Value.h:249
Value()
Create an empty Value.
Definition Value.h:215
Whether or not js::TypeTraits can convert T (ignoring const, volatile, and references).
Definition TypeTraits.h:275
Type-checked JavaScript bridge between C++ and web pages.
Definition JSInterop.h:141
Type
The type of a JavaScript value.
Definition Value.h:95
@ Symbol
Definition Value.h:102
@ String
Definition Value.h:101
@ Object
Definition Value.h:104
@ BigInt
Definition Value.h:103
Expected< T, Error > Result
The result of a JavaScript operation that can fail: a T or a js::Error.
Definition Error.h:520
Root namespace for every public Ultralight type, function, and enumeration.
Counts of the live handles on one context, for finding leaks (see Context::GetHandleStats()).
Definition Context.h:43
size_t weak_refs
Live weak references (0 once the context is gone).
Definition Context.h:46
size_t count(Type type) const
Get the number of live value handles of one type.
Definition Context.h:55
size_t ProtectedEstimate() const
Count the value handles that keep something from being garbage collected (strings,...
Definition Context.h:66
size_t total_values
Live value handles.
Definition Context.h:44
size_t values_by_type[kULJSType_Count]
Live value handles by js::Type (see count()).
Definition Context.h:45
A new pending Promise and the Resolver that settles it (see Context::MakePromise()).
Definition Context.h:75
Value promise
The Promise to hand to the page.
Definition Context.h:76
Resolver resolver
Settles promise (from any thread).
Definition Context.h:77
Type conversions between C++ and JavaScript across the bridge.
Definition TypeTraits.h:240