If you need to offer some additional native functionality in JavaScript, you can extend Ejecta with your own Classes.
Subclasses of EJBindingBase
or EJBindingEventedBase
with the EJBinding
prefix will be automatically available in JavaScript. E.g. a Class named EJBindingSimpleTest
can be instantiated and used in JavaScript like this:
var simpleTest = new Ejecta.SimpleTest( 42 ); simpleTest.foo; // 42 simpleTest.foo = 2; simpleTest.getFooSquared(); // 4
EJBindingSimpleTest.h
#import "EJBindingBase.h" @interface EJBindingSimpleTest : EJBindingBase { int myFoo; } @end
EJBindingSimpleTest.m
#import "EJBindingSimpleTest.h" @implementation EJBindingSimpleTest - (id)initWithContext:(JSContextRef) ctx argc:(size_t)argc argv:(const JSValueRef [])argv { if( self = [super initWithContext:ctx argc:argc argv:argv] ) { if( argc > 0 ) { myFoo = JSValueToNumberFast(ctx, argv[0]); } } return self; } EJ_BIND_GET( foo, ctx ) { return JSValueMakeNumber( ctx, myFoo ); } EJ_BIND_SET( foo, ctx, value) { myFoo = JSValueToNumberFast( ctx, value); } EJ_BIND_FUNCTION( getFooSquared, ctx, argc, argv ) { return JSValueMakeNumber( ctx, myFoo * myFoo ); } @end
Note that you only need to provide your own constructor (initWithContext…
) if you want to handle parameters when your class is instantiated.
To expose functions, getters and setters, use the EJ_BIND_*
macros. These macros all take a name and parameter names for the JSContextRef and additional values. The additional parameter names should be left as-is; they are only there to help you see what's going on in the macro.
Defines an instance method on your class and exposes it to JavaScript.
name
the name of the function that is exposed to JavaScriptctx
the JSContextRef
passed to this function when calledargc
an int
, denoting the number of parameters this function was called withargv
an array of JSValueRef
that holds the actual parameter values when calledYou have to return a JSValueRef
or NULL
.
Defines a getter on your class and exposes it to JavaScript.
name
the name of the property that is exposed to JavaScriptctx
the JSContextRef
passed to this getter when this property is accessedYou have to return a JSValueRef
or NULL
.
If you do not define a setter with the same name, this property will be marked as read-only.
Defines a setter on your class and exposes it to JavaScript.
name
the name of the property that is exposed to JavaScriptctx
the JSContextRef
passed to this setter when this property is assignedvalue
the JSValueRef
that should be assigned to this propertyA setter returns nothing (void
).
Note that each setter must have a getter with the same name, or it will be ignored.
Get the value at the specified path, starting at the global object. E.g. to get the window.navigator.platform
value:
JSValueRef platform = [scriptView jsValueForPath:@"window.navigator.platform"]; // or simply, like this, since 'window' is the global object: JSValueRef platform = [scriptView jsValueForPath:@"navigator.platform"];
See here for the details
Ejecta provides some handy helper methods to convert JSValueRef
to native types and vice versa in addition to those provided by the JavaScriptCore API itself.
Takes a JSValueRef and returns an NSString instance. The NSString will be auto-released; call retain
if you need to hold on to it.
NSString * foo = JSValueToNSString( ctx, fooJSValue );
Takes an NSString and returns a JSValueRef. The JSValueRef will be garbage collected if no reference to will be retained in the JavaScript context. Use JSValueProtect()
if you need it internally longer than it may be present in the context.
JSValueRef fooJSValue = NSStringToJSValue( ctx, @"some test string" );
Takes a JSValueRef and returns a double.
Similar to the JavaScriptCore API's JSValueToNumber()
, but blindly assumes that the JSValueRef is a Number. Calling it with a JSValueRef
that is not a Number, will result in a bogus value. E.g. a String may be converted to 23422.2347678.
double foo = JSValueToNumberFast( ctx, fooJSValue );
Converts NSString, NSNumber, NSDictionary, NSArray and NSNull objects to a JSValueRef. Also handles nested Arrays or Dictionaries.
Converts Numbers, Strings, Arrays and Objects to NSObject. Also handles nested Arrays or Objects.