Browse files

Added toJS to convert ObjC objects to JS Values (NSNumber, NSString, …

…NSArray, NSDictionary, NSDate)
  • Loading branch information...
1 parent 5148f5c commit 09e6741a0d82171ae1f3ff5cfab0ca586bada203 @parmanoir committed Nov 6, 2011
View
6 JSCocoa/JSCocoaController.h
@@ -17,7 +17,8 @@
#import "JSCocoaFFIClosure.h"
-// JS value container, used by methods wanting a straight JSValue and not a converted JS->ObjC value.
+// JS context and value container, used by methods to get and return raw Javascript values
+// (No conversion happens)
struct JSValueRefAndContextRef
{
JSValueRef value;
@@ -136,6 +137,9 @@ typedef struct JSValueRefAndContextRef JSValueRefAndContextRef;
// Wrapper for unboxJSValueRef
- (id)toObject:(JSValueRef)value;
+// Convert a native ObjC object (NSNumber, NSString, NSArray, NSDictionary, NSDate) to its JS counterpart
+- (JSValueRefAndContextRef)toJS:(id)object;
+
//
// Framework
View
63 JSCocoa/JSCocoaController.m
@@ -855,6 +855,8 @@ - (id)unboxJSValueRef:(JSValueRef)value
return object;
}
+#pragma mark Data conversion Javascript -> C and ObjC values
+
//
// Conversion boolean / number / string
//
@@ -891,7 +893,68 @@ - (id)toObject:(JSValueRef)value
return [self unboxJSValueRef:value];
}
+#pragma mark Data conversion ObjC -> Javascript
+
+
+
+//
+// Convert a native ObjC object (NSNumber, NSString, NSArray, NSDictionary, NSDate) to its JS counterpart
+//
+- (JSValueRef)_toJS:(id)object {
+ if ([object isKindOfClass:[NSString class]]) {
+ NSString* string = (NSString*)object;
+ JSStringRef jsName = JSStringCreateWithUTF8CString([string UTF8String]);
+ JSValueRef jsString = JSValueMakeString(ctx, jsName);
+ JSStringRelease(jsName);
+ return jsString;
+ }
+ else if ([object isKindOfClass:[NSNumber class]]) {
+ NSNumber* number = (NSNumber*)object;
+ return JSValueMakeNumber(ctx, [number doubleValue]);
+ }
+ else if ([object isKindOfClass:[NSDate class]]) {
+ NSDate* date = (NSDate*)object;
+ JSObjectRef jsDate = JSValueToObject(ctx, [self evalJSString:@"new Date"], NULL);
+ NSString* str = [NSString stringWithFormat:@"this.setTime(%f*1000)", [date timeIntervalSince1970]];
+ [self anonEval:str withThis:jsDate];
+ return jsDate;
+ }
+ else if ([object isKindOfClass:[NSArray class]]) {
+ NSArray* array = (NSArray*)object;
+ JSObjectRef jsArray = JSValueToObject(ctx, [self evalJSString:@"[]"], NULL);
+ unsigned i = 0;
+ for (id o in array) {
+ JSValueRef convertedValue = [self _toJS:o];
+ JSObjectSetPropertyAtIndex(ctx, jsArray, i, convertedValue, NULL);
+ i++;
+ }
+ return jsArray;
+ }
+ else if ([object isKindOfClass:[NSDictionary class]]) {
+ NSDictionary* dict = (NSDictionary*)object;
+ JSObjectRef jsDict = JSValueToObject(ctx, [self evalJSString:@"[]"], NULL);
+ for (NSString* key in dict) {
+ id value = [dict valueForKey:key];
+ JSValueRef convertedValue = [self _toJS:value];
+ JSStringRef jsName = JSStringCreateWithUTF8CString([key UTF8String]);
+ JSObjectSetProperty(ctx, jsDict, jsName, convertedValue, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(jsName);
+ }
+ return jsDict;
+ }
+ NSLog(@"Don't know how to convert %@, boxing it", object);
+ return [self boxObject:object];
+}
+
+- (JSValueRefAndContextRef)toJS:(id)object {
+ JSValueRefAndContextRef valueAndContext = { JSValueMakeNull(ctx), NULL };
+ valueAndContext.value = [self _toJS:object];
+
+ return valueAndContext;
+}
+
+#pragma mark Setting named objects in context (ctx.name = value)
//
// Add/Remove an ObjC object variable to the global context
View
1 JSCocoa/JSCocoaFFIArgument.m
@@ -1354,4 +1354,5 @@ + (BOOL)unboxJSHash:(JSObjectRef)object toObject:(id*)o inContext:(JSContextRef)
+
@end
View
8 JSCocoa/jslint-jscocoa.js
@@ -2471,8 +2471,11 @@ members)?
if (!t.block) {
// ## Only warn about missing semicolons when next token is on same line and not a closing brace (like in one line closures)
if (nexttoken.id !== ';') {
+/*
if (token.line == nexttoken.line && nexttoken.id != '}')
- warningAt("Missing semicolon.", token.line, token.from + token.value.length);
+// alert('THERE')
+ warningAt("@@@Missing semicolon.", token.line, token.from + token.value.length);
+*/
//##
// warningAt("Missing semicolon.", token.line,
// token.from + token.value.length);
@@ -4590,7 +4593,8 @@ members)?
stmt('var', varstatement);
stmt('new', function () {
- warning("'new' should not be used as a statement.");
+ // JSCocoa can eval stuff like 'new Date' to get a date.
+// warning("'new' should not be used as a statement.");
});
View
BIN ....xcodeproj/project.xcworkspace/xcuserdata/mini.xcuserdatad/UserInterfaceState.xcuserstate
Binary file not shown.

0 comments on commit 09e6741

Please sign in to comment.