Evaluating a String of JS
Using View::EvaluateScript()
The easiest way to evaluate a string of JavaScript in C++ is by using View::EvaluateScript()
// Use LoadListener::OnDOMReady to wait for page scripts to load
void MyApp::OnDOMReady(View* view) {
// Execute a string of JavaScript
view->EvaluateScript("document.body.innerHTML = 'Ultralight rocks!';");
}
Handling Results
View::EvaluateScript()
can return the result from a script execution, if any.
The result is returned in the form of a JSValueRef
which you can use with JavaScriptCore's API to convert into native C types.
// Use LoadListener::OnDOMReady to wait for page scripts to load
void MyApp::OnDOMReady(View* view) {
// Execute a string of JavaScript, store result in 'result
JSValueRef result = view->EvaluateScript("1 + 1");
// Convert result to a Number ('double' in C)
double num = JSValueToNumber(view->js_context(), result, 0);
// 'num' should now equal '2.0'
}
Using JSEvaluateScript() Directly
View::EvaluateScript()
is really just a wrapper for JavaScriptCore's JSEvaluateScript()
. This API function offers lower-level control over script execution (exception handling, overriding this
object, etc.).
Read the API declaration for JSEvaluateScript()
here.
To use this API function we're going to need to create a JavaScript string with JSStringCreateWithUTF8CString()
and then pass it to JSEvaluateScript()
.
// Use LoadListener::OnDOMReady to wait for page scripts to load
void MyApp::OnDOMReady(View* view) {
// Get the JS execution context for the current page
JSContextRef ctx = view->js_context();
const char* script = "document.body.innerHTML = 'Ultralight rocks!';";
// Create our string of JavaScript
JSStringRef str = JSStringCreateWithUTF8CString(script);
// Execute it with JSEvaluateScript, ignoring other parameters for now
JSEvaluateScript(ctx, str, 0, 0, 0, 0);
// Release our string (we only Release what we Create)
JSStringRelease(str);
}
Managing string lifetime with Retain / Release
The API follows a simple rule-- anything you "Create" you must "Release".
For example, in the above code snippet we called JSStringCreateWithUTF8CString
. This API function has the word Create
in it so we must release the created object with JSStringRelease()
to avoid a memory leak.
If you want to increase the ref-count (to retain the object in a C++ wrapper, for instance), you can call JSStringRetain()
.
The API provides a JSRetainPtr<>
for C++ that automatically manages lifetime for you. Just call adopt()
with any of the JSStringCreate
methods to create a managed string object.
#include <JavaScriptCore/JSRetainPtr.h>
// Use LoadListener::OnDOMReady to wait for page scripts to load
void MyApp::OnDOMReady(View* view) {
// Get the JS execution context for the current page
JSContextRef ctx = view->js_context();
const char* script = "document.body.innerHTML = 'Ultralight rocks!';";
// Create our string of JavaScript, automatically managed by JSRetainPtr
JSRetainPtr<JSStringRef> str = adopt(
JSStringCreateWithUTF8CString(script));
// Execute it with JSEvaluateScript, ignoring other parameters for now
JSEvaluateScript(ctx, str.get(), 0, 0, 0, 0);
}
Updated over 5 years ago