Ultralight C++ API 1.3.0
Loading...
Searching...
No Matches
JSHelpers.h
Go to the documentation of this file.
1/******************************************************************************
2 * This file is a part of Ultralight, an ultra-portable web-browser engine. *
3 * *
4 * See <https://ultralig.ht> for licensing and more. *
5 * *
6 * (C) 2023 Ultralight, Inc. *
7 *****************************************************************************/
8#pragma once
9#include <AppCore/Defines.h>
12#include <Ultralight/String.h>
13#include <functional>
14#include <memory>
15
16namespace ultralight {
17
18///
19/// Set the current JSContext.
20///
21/// Most JavaScriptCore C API calls require an active JavaScript execution
22/// context (JSContextRef). You can get the JSContextRef for a page via
23/// `View::LockJSContext()`. This context changes with each page navigation.
24///
25/// **Note**:
26/// You MUST set a JSContext before using most of the C++ API below.
27///
29
30///
31/// Get the current JSContext.
32///
34
35///
36/// JavaScript String wrapper that automatically manages JSStringRef lifetime
37/// and provides helpful conversions.
38///
40public:
41 /// Create empty string
43
44 /// Create from C-string
45 JSString(const char* str);
46
47 /// Create from Ultralight String
48 JSString(const String& str);
49
50 /// Create from existing JSStringRef
52
53 /// Copy constructor
54 JSString(const JSString& other);
55
56 /// Destructor
58
59 /// Assignment operator
60 JSString& operator=(const JSString& other);
61
62 /// Cast to String
63 operator String();
64
65 /// Cast to underlying JSStringRef
66 operator JSStringRef() const { return instance_; }
67
68protected:
70};
71
72class JSArray;
73class JSObject;
74class JSFunction;
75
76/// Tag type used with the JSValue constructor to create "Null" types
78
79/// Tag type used with the JSValue constructor to create "Undefined" types
81
82///
83/// JavaScript variant value wrapper that automatically manages JSValueRef
84/// lifetime and provides helpful conversions.
85///
87public:
88 /// Create null (empty) JSValue
90
91 /// Create null JSValue explicitly
93
94 /// Create undefined JSValue
96
97 /// Create boolean JSValue
98 JSValue(bool val);
99
100 /// Create unsigned integer JSValue (aka, Number) [will be cast to double]
101 JSValue(uint32_t val);
102
103 /// Create integer JSValue (aka, Number) [will be cast to double]
104 JSValue(int32_t val);
105
106 /// Create unsigned integer JSValue (aka, Number) [will be cast to double]
107 JSValue(uint64_t val);
108
109 /// Create integer JSValue (aka, Number) [will be cast to double]
110 JSValue(int64_t val);
111
112 /// Create double JSValue (aka, Number)
113 JSValue(double val);
114
115 /// Create string JSValue
116 JSValue(const char* val);
117
118 /// Create string JSValue
119 JSValue(const String& val);
120
121 /// Create string JSValue
123
124 /// Create from existing JSValueRef
126
127 /// Create object JSValue
129
130 /// Copy constructor, a shallow copy is made, the constructed JSValue will
131 /// point to the same JSValueRef.
132 JSValue(const JSValue& other);
133
134 /// Destructor
135 virtual ~JSValue();
136
137 /// A shallow copy is made, this JSValue will point to the same JSValueRef
138 virtual JSValue& operator=(const JSValue& other);
139
140 /// Whether or not the value is a JavaScript Null type.
141 bool IsNull() const;
142
143 /// Whether or not the value is a JavaScript Undefined type.
144 bool IsUndefined() const;
145
146 /// Whether or not the value is a JavaScript Boolean type.
147 bool IsBoolean() const;
148
149 /// Whether or not the value is a JavaScript Number type.
150 bool IsNumber() const;
151
152 /// Whether or not the value is a JavaScript String type.
153 bool IsString() const;
154
155 /// Whether or not the value is a JavaScript Object type.
156 bool IsObject() const;
157
158 /// Whether or not the value is a JavaScript Array type.
159 bool IsArray() const;
160
161 /// Whether or not the value is a JavaScript Function type.
162 bool IsFunction() const;
163
164 /// Get the value as a Boolean
165 bool ToBoolean() const;
166
167 /// Get the value as a Number (Double)
168 double ToNumber() const;
169
170 /// Get the value as a Number (Integer)
171 int64_t ToInteger() const { return static_cast<int64_t>(ToNumber()); }
172
173 /// Get the value as a String
175
176 /// Get the value as an Object (will debug assert if not an Object)
178
179 /// Get the value as an Array (will debug asset if not an Array)
181
182 /// Get the value as a Function (will debug asset if not a Function)
184
185 operator bool() const { return ToBoolean(); }
186
187 operator double() const { return ToNumber(); }
188
189 operator uint32_t() const { return static_cast<uint32_t>(ToNumber()); }
190
191 operator int32_t() const { return static_cast<uint32_t>(ToNumber()); }
192
193 operator uint64_t() const { return static_cast<uint64_t>(ToNumber()); }
194
195 operator int64_t() const { return ToInteger(); }
196
197 operator String() const { return ToString(); }
198
199 operator JSString() const { return ToString(); }
200
201 operator JSObject() const;
202
203 operator JSObjectRef() const;
204
205 operator JSArray() const;
206
207 operator JSFunction() const;
208
209 /// Get the underlying JSValueRef
210 operator JSValueRef() const { return instance(); }
211
212 ///
213 /// Get the bound context for this JSValue (it is cached at creation).
214 ///
215 JSContextRef context() const { return ctx_; }
216
217 ///
218 /// Set the JSContext for this JSValue.
219 ///
220 /// **Note**:
221 /// JSValues created from within a JSCallback have a temporary JSContext
222 /// that is destroyed when the callback returns. You will need to "move"
223 /// any JSValues created within these callbacks to the View's main context
224 /// (call set_context() with the main context) before using them outside
225 /// the callback.
226 ///
227 void set_context(JSContextRef context) { ctx_ = context; }
228
229protected:
232 virtual JSValueRef instance() const;
233
235 JSValueRef instance_ = nullptr;
236 friend class JSFunction;
237};
238
239///
240/// A vector of JSValues, used for passing around arguments in JSCallback.
241///
243public:
244 /// Create an empty list of JavaScript arguments
246
247 /// Create a list of JavaScript arguments using a C++ initializer list
248 JSArgs(const std::initializer_list<JSValue>& values);
249
250 /// Copy-constructor
251 JSArgs(const JSArgs& other);
252
253 /// Destructor
255
256 /// Assignment operator
257 JSArgs& operator=(const JSArgs& other);
258
259 ///
260 /// Access an element of the argument list by index.
261 ///
262 /// **Note**:
263 /// All JSValues are actually wrappers of JSValueRef instances so even
264 /// though this function doesn't return a JSValue& you are still operating
265 /// directly on the underlying JavaScript value instance.
266 ///
267 JSValue operator[](size_t pos);
268
269 ///
270 /// Access an element of the argument list by index. (const overload)
271 ///
272 /// **Note**:
273 /// All JSValues are actually wrappers of JSValueRef instances so even
274 /// though this function doesn't return a JSValue& you are still operating
275 /// directly on the underlying JavaScript value instance.
276 ///
277 const JSValue operator[](size_t pos) const;
278
279 /// Whether or not the argument list is empty.
280 bool empty() const;
281
282 /// The number of elements in the argument list.
283 size_t size() const;
284
285 /// Clear the argument list.
286 void clear();
287
288 /// Add a new argument to the end of the list.
289 void push_back(const JSValue& val);
290
291 /// Remove the last item from the end of the list.
292 void pop_back();
293
294 /// Get the argument list as a C-array of JSValues
296
297 /// Get the argument list as a C-array of JSValues (const overload)
298 const JSValue* data() const;
299protected:
301};
302
303///
304/// JSCallback typedef used for binding C++ callbacks to JavaScript functions.
305///
306/// Takes two arguments (const JSObject& thisObj, const JSArgs& args) and
307/// returns nothing (void).
308///
309typedef std::function<void(const JSObject&, const JSArgs&)> JSCallback;
310
311///
312/// JSCallbackWithRetval typedef used for binding C++ callbacks to JavaScript
313/// functions with an optional return value.
314///
315/// Takes two arguments (const JSObject& thisObj, const JSArgs& args) and
316/// returns a JSValue back to JavaScript.
317///
318typedef std::function<JSValue(const JSObject&, const JSArgs&)> JSCallbackWithRetval;
319
320///
321/// Macro to help bind C++ member functions to a JSCallback
322///
323/// Usage: JSCallback callback = BindJSCallback(&MyClass::MyMemberFunction);
324///
325/// **Note**: Expected to run from within an instance of 'MyClass', note the
326/// 'this' keyword in the macro.
327///
328#define BindJSCallback(fn) (JSCallback)std::bind(fn, this, std::placeholders::_1, std::placeholders::_2)
329
330///
331/// Macro to help bind C++ member functions to a JSCallbackWithRetval
332///
333/// Usage: JSCallback callback = BindJSCallback(&MyClass::MyMemberFunction);
334///
335/// **Note**: Expected to run from within an instance of 'MyClass', note the
336/// 'this' keyword in the macro.
337///
338#define BindJSCallbackWithRetval(fn) (JSCallbackWithRetval)std::bind(fn, this, std::placeholders::_1, std::placeholders::_2)
339
340///
341/// Wrapper for JSObject property value (JSValue subclass). Allows new value assignment
342/// to object property, binding C++ callbacks to object properties via function objects,
343/// as well as value query via the JSValue interface.
344///
346public:
348
349 /// Assign a new value to the property (internally calls JSObjectSetProperty)
350 virtual JSPropertyValue& operator=(const JSValue& value);
351
352 /// Bind to native C++ callback (creates a Function object that can be called from JS)
354
355 /// Bind to native C++ callback with return value (creates a Function object that can be called from JS)
357
358protected:
359 virtual JSValueRef instance() const;
360 JSPropertyValue(JSContextRef ctx, JSObjectRef proxy_obj, unsigned idx);
364
367 unsigned numeric_idx_;
369 friend class JSArray;
370 friend class JSObject;
371};
372
373///
374/// JSArray wrapper that automatically manages lifetime and provides
375/// convenient access to indices and Array functions.
376///
378public:
379 /// Create empty Array
381
382 /// Create Array from list of JSValues
383 JSArray(const std::initializer_list<JSValue>& values);
384
385 /// Create Array from existing JSObjectRef (JavaScriptCore C API)
387
388 /// Copy constructor (shallow copy, will point to same instance)
389 JSArray(const JSArray& other);
390
392
393 /// Assignment (shallow assignment, will point to same instance)
394 JSArray& operator=(const JSArray& other);
395
396 /// Get number of elements in the Array
397 unsigned length();
398
399 /// Push an element to back of Array
400 void push(const JSValue& val);
401
402 /// Find the index (location) of a certain value, will return -1 if not found
403 int indexOf(const JSValue& val, int start = 0) const;
404
405 /// Get a property by array index (numbering starts at 0)
406 JSPropertyValue operator[](unsigned idx) const;
407
408 /// Get the underlying JSObjectRef (JavaScriptCore C API)
409 operator JSObjectRef() const { return instance_; }
410
411 ///
412 /// Get the bound context for this JSArray (it is cached at creation).
413 ///
414 JSContextRef context() const { return ctx_; }
415
416 ///
417 /// Set the JSContext for this JSArray.
418 ///
419 /// **Note**:
420 /// JSArrays created from within a JSCallback have a temporary JSContext
421 /// that is destroyed when the callback returns. You will need to "move"
422 /// any JSArrays created within these callbacks to the View's main context
423 /// (call set_context() with the main context) before using them outside
424 /// the callback.
425 ///
426 void set_context(JSContextRef context) { ctx_ = context; }
427
428protected:
430
433 friend class JSValue;
434};
435
436///
437/// JSObject wrapper that automatically manages lifetime and provides
438/// convenient access to properties.
439///
441public:
442 /// Create empty Object
444
445 /// Create from existing JSObjectRef from JavaScriptCore C API
447
448 /// Copy constructor (shallow copy, will point to same instance)
449 JSObject(const JSObject& other);
450
452
453 /// Assignment (shallow assignment, will point to same instance)
455
456 /// Get a property by name
458
459 /// Check if a property exists
460 bool HasProperty(JSString propertyName) const;
461
462 /// Remove a property
463 bool DeleteProperty(JSString propertyName);
464
465 /// Get the underlying JSObjectRef (JavaScriptCore C API)
466 operator JSObjectRef() const { return instance_; }
467
468 ///
469 /// Get the bound context for this JSObject (it is cached at creation).
470 ///
471 JSContextRef context() const { return ctx_; }
472
473 ///
474 /// Set the JSContext for this JSObject.
475 ///
476 /// **Note**:
477 /// JSObjects created from within a JSCallback have a temporary JSContext
478 /// that is destroyed when the callback returns. You will need to "move"
479 /// any JSObjects created within these callbacks to the View's main context
480 /// (call set_context() with the main context) before using them outside
481 /// the callback.
482 ///
483 void set_context(JSContextRef context) { ctx_ = context; }
484
485protected:
488
491 friend class JSValue;
492 friend class JSPropertyValue;
493};
494
495///
496/// JSFunction wrapper that automatically manages lifetime and provides
497/// convenient function invocation operators.
498///
500public:
501 /// Create an empty Function.
502 /// NOTE: It is OKAY to create this without calling SetJSContext() first.
504
505 /// Copy constructor (shallow copy, will point to same instance)
506 JSFunction(const JSFunction& other);
507
509
510 /// Assignment (shallow assignment, will point to same instance)
512
513 /// Whether or not this is a valid, callable Function object.
514 bool IsValid() const;
515
516 /// Call function (using Global Object for 'this') and return the result.
518
519 /// Call function (with explicit object for 'this') and return the result
520 JSValue operator()(const JSObject& thisObject, const JSArgs& args);
521
522 /// Get the underlying JSObjectRef (JavaScriptCore C API)
523 operator JSObjectRef() const { return instance_; }
524
525 ///
526 /// Get the bound context for this JSFunction (it is cached at creation).
527 ///
528 JSContextRef context() const { return ctx_; }
529
530 ///
531 /// Set the JSContext for this JSFunction.
532 ///
533 /// **Note**:
534 /// JSFunctions created from within a JSCallback have a temporary JSContext
535 /// that is destroyed when the callback returns. You will need to "move"
536 /// any JSFunctions created within these callbacks to the View's main context
537 /// (call set_context() with the main context) before using them outside
538 /// the callback.
539 ///
540 void set_context(JSContextRef context) { ctx_ = context; }
541
542protected:
544
547 friend class JSValue;
548};
549
550///
551/// Get the Global Object for the current JSContext.
552/// In JavaScript, this would be equivalent to the "window" object.
553///
555
556///
557/// Evaluate a string of JavaScript and return a result.
558///
560
561} // namespace ultralight
#define AExport
Definition Defines.h:42
struct OpaqueJSString * JSStringRef
Definition JSBase.h:49
struct OpaqueJSValue * JSObjectRef
Definition JSBase.h:69
const struct OpaqueJSValue * JSValueRef
Definition JSBase.h:66
const struct OpaqueJSContext * JSContextRef
Definition JSBase.h:43
A vector of JSValues, used for passing around arguments in JSCallback.
Definition JSHelpers.h:242
JSValue operator[](size_t pos)
Access an element of the argument list by index.
bool empty() const
Whether or not the argument list is empty.
JSArgs(const JSArgs &other)
Copy-constructor.
~JSArgs()
Destructor.
void push_back(const JSValue &val)
Add a new argument to the end of the list.
void clear()
Clear the argument list.
void * instance_
Definition JSHelpers.h:300
const JSValue * data() const
Get the argument list as a C-array of JSValues (const overload)
JSArgs & operator=(const JSArgs &other)
Assignment operator.
JSValue * data()
Get the argument list as a C-array of JSValues.
JSArgs(const std::initializer_list< JSValue > &values)
Create a list of JavaScript arguments using a C++ initializer list.
const JSValue operator[](size_t pos) const
Access an element of the argument list by index.
JSArgs()
Create an empty list of JavaScript arguments.
size_t size() const
The number of elements in the argument list.
void pop_back()
Remove the last item from the end of the list.
JSArray wrapper that automatically manages lifetime and provides convenient access to indices and Arr...
Definition JSHelpers.h:377
JSArray()
Create empty Array.
unsigned length()
Get number of elements in the Array.
JSObjectRef instance_
Definition JSHelpers.h:432
JSPropertyValue operator[](unsigned idx) const
Get a property by array index (numbering starts at 0)
JSArray(JSObjectRef array_obj)
Create Array from existing JSObjectRef (JavaScriptCore C API)
JSArray(const JSArray &other)
Copy constructor (shallow copy, will point to same instance)
JSArray(const std::initializer_list< JSValue > &values)
Create Array from list of JSValues.
void push(const JSValue &val)
Push an element to back of Array.
JSArray(JSContextRef ctx, JSValueRef val)
JSArray & operator=(const JSArray &other)
Assignment (shallow assignment, will point to same instance)
JSContextRef context() const
Get the bound context for this JSArray (it is cached at creation).
Definition JSHelpers.h:414
JSContextRef ctx_
Definition JSHelpers.h:431
int indexOf(const JSValue &val, int start=0) const
Find the index (location) of a certain value, will return -1 if not found.
void set_context(JSContextRef context)
Set the JSContext for this JSArray.
Definition JSHelpers.h:426
JSFunction wrapper that automatically manages lifetime and provides convenient function invocation op...
Definition JSHelpers.h:499
JSFunction & operator=(const JSFunction &other)
Assignment (shallow assignment, will point to same instance)
bool IsValid() const
Whether or not this is a valid, callable Function object.
JSFunction(JSContextRef ctx, JSValueRef val)
JSFunction()
Create an empty Function.
void set_context(JSContextRef context)
Set the JSContext for this JSFunction.
Definition JSHelpers.h:540
JSValue operator()(const JSArgs &args)
Call function (using Global Object for 'this') and return the result.
JSContextRef ctx_
Definition JSHelpers.h:545
JSObjectRef instance_
Definition JSHelpers.h:546
JSFunction(const JSFunction &other)
Copy constructor (shallow copy, will point to same instance)
JSContextRef context() const
Get the bound context for this JSFunction (it is cached at creation).
Definition JSHelpers.h:528
JSValue operator()(const JSObject &thisObject, const JSArgs &args)
Call function (with explicit object for 'this') and return the result.
JSObject wrapper that automatically manages lifetime and provides convenient access to properties.
Definition JSHelpers.h:440
JSObjectRef instance_
Definition JSHelpers.h:490
JSObject(JSContextRef ctx, JSObjectRef obj)
JSObject(JSContextRef ctx, JSValueRef val)
void set_context(JSContextRef context)
Set the JSContext for this JSObject.
Definition JSHelpers.h:483
JSContextRef ctx_
Definition JSHelpers.h:489
bool DeleteProperty(JSString propertyName)
Remove a property.
JSObject()
Create empty Object.
JSObject(JSObjectRef obj)
Create from existing JSObjectRef from JavaScriptCore C API.
JSObject & operator=(const JSObject &other)
Assignment (shallow assignment, will point to same instance)
JSContextRef context() const
Get the bound context for this JSObject (it is cached at creation).
Definition JSHelpers.h:471
JSObject(const JSObject &other)
Copy constructor (shallow copy, will point to same instance)
JSPropertyValue operator[](JSString propertyName) const
Get a property by name.
bool HasProperty(JSString propertyName) const
Check if a property exists.
Wrapper for JSObject property value (JSValue subclass).
Definition JSHelpers.h:345
JSString string_idx_
Definition JSHelpers.h:368
JSPropertyValue & operator=(const JSCallback &callback)
Bind to native C++ callback (creates a Function object that can be called from JS)
JSPropertyValue(const JSPropertyValue &)=default
virtual JSPropertyValue & operator=(const JSValue &value)
Assign a new value to the property (internally calls JSObjectSetProperty)
JSPropertyValue & operator=(const JSCallbackWithRetval &callback)
Bind to native C++ callback with return value (creates a Function object that can be called from JS)
JSPropertyValue & operator=(const JSPropertyValue &)=delete
unsigned numeric_idx_
Definition JSHelpers.h:367
JSPropertyValue(JSContextRef ctx, JSObjectRef proxy_obj, unsigned idx)
virtual JSValueRef instance() const
bool using_numeric_idx_
Definition JSHelpers.h:366
JSPropertyValue(JSContextRef ctx, JSObjectRef proxy_obj, JSString idx)
JSObject * proxyObj_
Definition JSHelpers.h:365
JavaScript String wrapper that automatically manages JSStringRef lifetime and provides helpful conver...
Definition JSHelpers.h:39
~JSString()
Destructor.
JSStringRef instance_
Definition JSHelpers.h:69
JSString(const JSString &other)
Copy constructor.
JSString(const char *str)
Create from C-string.
JSString()
Create empty string.
JSString(JSStringRef str)
Create from existing JSStringRef.
JSString(const String &str)
Create from Ultralight String.
JSString & operator=(const JSString &other)
Assignment operator.
JavaScript variant value wrapper that automatically manages JSValueRef lifetime and provides helpful ...
Definition JSHelpers.h:86
bool IsBoolean() const
Whether or not the value is a JavaScript Boolean type.
virtual JSValue & operator=(const JSValue &other)
A shallow copy is made, this JSValue will point to the same JSValueRef.
JSValue(const JSValue &other)
Copy constructor, a shallow copy is made, the constructed JSValue will point to the same JSValueRef.
JSValue(JSValueRef val)
Create from existing JSValueRef.
JSValue()
Create null (empty) JSValue.
JSValue(JSValueNullTag)
Create null JSValue explicitly.
JSValue(uint64_t val)
Create unsigned integer JSValue (aka, Number) [will be cast to double].
bool IsString() const
Whether or not the value is a JavaScript String type.
JSValue(bool val)
Create boolean JSValue.
int64_t ToInteger() const
Get the value as a Number (Integer)
Definition JSHelpers.h:171
bool IsNumber() const
Whether or not the value is a JavaScript Number type.
JSString ToString() const
Get the value as a String.
void set_context(JSContextRef context)
Set the JSContext for this JSValue.
Definition JSHelpers.h:227
bool IsObject() const
Whether or not the value is a JavaScript Object type.
JSValue(uint32_t val)
Create unsigned integer JSValue (aka, Number) [will be cast to double].
JSValue(int64_t val)
Create integer JSValue (aka, Number) [will be cast to double].
bool IsNull() const
Whether or not the value is a JavaScript Null type.
JSContextRef context() const
Get the bound context for this JSValue (it is cached at creation).
Definition JSHelpers.h:215
JSObject ToObject() const
Get the value as an Object (will debug assert if not an Object)
JSValue(int32_t val)
Create integer JSValue (aka, Number) [will be cast to double].
virtual JSValueRef instance() const
JSValue(JSContextRef ctx)
JSValue(const char *val)
Create string JSValue.
JSFunction ToFunction() const
Get the value as a Function (will debug asset if not a Function)
JSArray ToArray() const
Get the value as an Array (will debug asset if not an Array)
bool ToBoolean() const
Get the value as a Boolean.
bool IsArray() const
Whether or not the value is a JavaScript Array type.
JSValue(JSObjectRef obj)
Create object JSValue.
double ToNumber() const
Get the value as a Number (Double)
bool IsUndefined() const
Whether or not the value is a JavaScript Undefined type.
JSValue(const String &val)
Create string JSValue.
JSValue(JSValueUndefinedTag)
Create undefined JSValue.
JSValue(double val)
Create double JSValue (aka, Number)
bool IsFunction() const
Whether or not the value is a JavaScript Function type.
JSValue(JSContextRef ctx, JSValueRef val)
JSContextRef ctx_
Definition JSHelpers.h:234
virtual ~JSValue()
Destructor.
JSValue(JSString val)
Create string JSValue.
UTF-8 String container with conversions for UTF-16 and UTF-32.
Definition String.h:21
Definition App.h:14
std::function< void(const JSObject &, const JSArgs &)> JSCallback
JSCallback typedef used for binding C++ callbacks to JavaScript functions.
Definition JSHelpers.h:309
JSValue JSEval(const JSString &str)
Evaluate a string of JavaScript and return a result.
JSContextRef GetJSContext()
Get the current JSContext.
JSObject JSGlobalObject()
Get the Global Object for the current JSContext.
void SetJSContext(JSContextRef ctx)
Set the current JSContext.
std::function< JSValue(const JSObject &, const JSArgs &)> JSCallbackWithRetval
JSCallbackWithRetval typedef used for binding C++ callbacks to JavaScript functions with an optional ...
Definition JSHelpers.h:318
Tag type used with the JSValue constructor to create "Null" types.
Definition JSHelpers.h:77
Tag type used with the JSValue constructor to create "Undefined" types.
Definition JSHelpers.h:80