Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIMOB-9314] Support for mixed JS and Obj-C modules. #2343

Merged
merged 2 commits into from
Jun 8, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
68 changes: 48 additions & 20 deletions iphone/Classes/KrollBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -791,19 +791,19 @@ -(id)require:(KrollContext*)kroll path:(NSString*)path
if (moduleClass!=nil)
{
module = [[moduleClass alloc] _initWithPageContext:self];
// we might have a module that's simply a JS native module wrapper
// in which case we simply load it and don't register our native module

// Load any JS associated with the module if there, so that it
// can be exported
if ([module isJSModule])
{
data = [module moduleJS];
}
else
{
[module setHost:host];
[module _setName:moduleClassName];
// register it
[modules setObject:module forKey:path];
}

[module setHost:host];
[module _setName:moduleClassName];
// register it
[modules setObject:module forKey:path];

[module autorelease];
}
}
Expand All @@ -825,29 +825,57 @@ -(id)require:(KrollContext*)kroll path:(NSString*)path
NSString* urlPath = (filepath != nil) ? filepath : path;
NSURL *url_ = [TiHost resourceBasedURL:urlPath baseURL:NULL];
const char *urlCString = [[url_ absoluteString] UTF8String];
if ([[self host] debugMode]) {
KrollWrapper* wrapper = nil;

if ([[self host] debugMode] && ![module isJSModule]) {
TiDebuggerBeginScript([self krollContext],urlCString);
}

NSString * dataContents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
module = [self loadCommonJSModule:dataContents withPath:path];
wrapper = [self loadCommonJSModule:dataContents withPath:path];
[dataContents release];

if ([[self host] debugMode]) {
if ([[self host] debugMode] && ![module isJSModule]) {
TiDebuggerEndScript([self krollContext]);
}

if (![module respondsToSelector:@selector(replaceValue:forKey:notification:)]) {
if (![wrapper respondsToSelector:@selector(replaceValue:forKey:notification:)]) {
@throw [NSException exceptionWithName:@"org.appcelerator.kroll" reason:[NSString stringWithFormat:@"Module \"%@\" failed to leave a valid exports object",path] userInfo:nil];
}

// register it
[modules setObject:module forKey:path];
if (filepath!=nil && module!=nil)
{
// uri is optional but we point it to where we loaded it
[module replaceValue:[NSString stringWithFormat:@"app://%@",filepath] forKey:@"uri" notification:NO];
}
// register the module if it's pure JS
if (module == nil) {
module = (id)wrapper;

[modules setObject:module forKey:path];
if (filepath!=nil && module!=nil)
{
// uri is optional but we point it to where we loaded it
[module replaceValue:[NSString stringWithFormat:@"app://%@",filepath] forKey:@"uri" notification:NO];
}
}
else {
// For right now, we need to mix any compiled JS on top of a compiled module, so that both components
// are accessible. We store the exports object and then put references to its properties on the toplevel
// object.

TiContextRef jsContext = [[self krollContext] context];
TiObjectRef jsObject = [wrapper jsobject];
KrollObject* moduleObject = [module krollObjectForContext:[self krollContext]];
[moduleObject noteObject:jsObject forTiString:kTiStringExportsKey context:jsContext];

TiPropertyNameArrayRef properties = TiObjectCopyPropertyNames(jsContext, jsObject);
size_t count = TiPropertyNameArrayGetCount(properties);
for (size_t i=0; i < count; i++) {
// Mixin the property onto the module JS object if it's not already there
TiStringRef propertyName = TiPropertyNameArrayGetNameAtIndex(properties, i);
if (!TiObjectHasProperty(jsContext, [moduleObject jsobject], propertyName)) {
TiValueRef property = TiObjectGetProperty(jsContext, jsObject, propertyName, NULL);
TiObjectSetProperty([[self krollContext] context], [moduleObject jsobject], propertyName, property, kTiPropertyAttributeReadOnly, NULL);
}
}
TiPropertyNameArrayRelease(properties);
}
}

if (module!=nil)
Expand Down
1 change: 1 addition & 0 deletions iphone/Classes/KrollObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

@class KrollContext, KrollCallback;
extern TiClassRef KrollObjectClassRef;
extern TiStringRef kTiStringExportsKey;

void KrollFinalizer(TiObjectRef ref);
void KrollInitializer(TiContextRef ctx, TiObjectRef object);
Expand Down
10 changes: 10 additions & 0 deletions iphone/Classes/KrollObject.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
TiStringRef kTiStringTiPropertyKey;
TiStringRef kTiStringPropertyKey;
TiStringRef kTiStringEventKey;
TiStringRef kTiStringExportsKey;


id TiValueToId(KrollContext* context, TiValueRef v);
Expand Down Expand Up @@ -413,6 +414,14 @@ TiValueRef KrollGetProperty(TiContextRef jsContext, TiObjectRef object, TiString
{
return NULL;
}

// Attempt to retrieve the property from the exports, before going through
// the routing
TiObjectRef exports = [o objectForTiString:kTiStringExportsKey context:jsContext];
if ((exports != NULL) && TiObjectHasProperty(jsContext, exports, prop)) {
return TiObjectGetProperty(jsContext, exports, prop, NULL);
}


NSString* name = (NSString*)TiStringCopyCFString(kCFAllocatorDefault, prop);
[name autorelease];
Expand Down Expand Up @@ -617,6 +626,7 @@ +(void)initialize
kTiStringTiPropertyKey = TiStringCreateWithUTF8CString("__TI");
kTiStringPropertyKey = TiStringCreateWithUTF8CString("__PR");
kTiStringEventKey = TiStringCreateWithUTF8CString("__EV");
kTiStringExportsKey = TiStringCreateWithUTF8CString("__EX");
}
}

Expand Down
12 changes: 8 additions & 4 deletions support/iphone/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,10 +408,14 @@ def is_indexing_enabled(tiapp, simulator_dir, **kwargs):
mount_point_status = {}
for i in range(0, len(lines), 2):
mount_point = lines[i].rstrip(':')
status = lines[i+1].strip('\t.')
# Only add mount points that the simulator_dir starts with
if simulator_dir.startswith(mount_point):
mount_point_status[mount_point] = status
if len(lines) > (i+1):
status = lines[i+1].strip('\t.')
# Only add mount points that the simulator_dir starts with
if simulator_dir.startswith(mount_point):
mount_point_status[mount_point] = status
# mdutil must be disabled if we don't get the right amount of output
else:
return False

if len(mount_point_status) > 0:
# There may be multiple volumes that have a mount point that the
Expand Down
4 changes: 2 additions & 2 deletions support/iphone/tools.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

import os, sys, codecs, shutil, filecmp
import os, sys, codecs, shutil, filecmp, subprocess

# the template_dir is the path where this file lives on disk
template_dir = os.path.abspath(os.path.dirname(sys._getframe(0).f_code.co_filename))

def ensure_dev_path(debug=True):
rc = os.system("xcode-select -print-path >/dev/null 2>/dev/null")
rc = subprocess.call(["xcode-select", "-print-path"], stdout=open(os.devnull, 'w'), stderr=open(os.devnull, 'w'))
if rc == 0 :
return
if debug:
Expand Down