Impact

If you need to offer some additional native functionality in JavaScript, you can extend Ejecta with your own Classes.

Example

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.

EJ_BIND_* Macros

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.

EJ_BIND_FUNCTION( name, ctx, argc, argv ) { … }

Defines an instance method on your class and exposes it to JavaScript.

You have to return a JSValueRef or NULL.

EJ_BIND_GET( name, ctx ) { … }

Defines a getter on your class and exposes it to JavaScript.

You 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.

EJ_BIND_SET( name, ctx, value ) { … }

Defines a setter on your class and exposes it to JavaScript.

A setter returns nothing (void).

Note that each setter must have a getter with the same name, or it will be ignored.

Convenience Methods

[scriptView jsValueForPath:(NSString *)objectPath]

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"];

[scriptView createFunctionWithBlock:block]

See here for the details

Conversion from and to JavaScript values

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.

NSString * JSValueToNSString( JSContextRef ctx, JSValueRef v )

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 );

JSValueRef NSStringToJSValue( JSContextRef ctx, NSString * string )

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" );

double JSValueToNumberFast( JSContextRef ctx, JSValueRef v );

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 );

JSValueRef NSObjectToJSValue( JSContextRef ctx, NSObject *object );

Converts NSString, NSNumber, NSDictionary, NSArray and NSNull objects to a JSValueRef. Also handles nested Arrays or Dictionaries.

NSObject * JSValueToNSObject( JSContextRef ctx, JSValueRef v );

Converts Numbers, Strings, Arrays and Objects to NSObject. Also handles nested Arrays or Objects.