Skip to content

Commit de9a1be

Browse files
Fix self object.
1 parent 0fb6d21 commit de9a1be

File tree

9 files changed

+199
-36
lines changed

9 files changed

+199
-36
lines changed

Classes/JSBScriptingSupport.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
+ (JSContext *)globalContext;
1818

1919
JSExportAs(defineClass,
20-
+ (void)defineClass:(NSString *)declaration
21-
instanceMembers:(JSValue *)instanceMembers
22-
staticMembers:(JSValue *)staticMembers
20+
+ (id)defineClass:(NSString *)declaration
21+
instanceMembers:(JSValue *)instanceMembers
22+
staticMembers:(JSValue *)staticMembers
2323
);
2424

2525
@optional

Classes/JSBScriptingSupport.m

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414

1515
static JSContext *globalContext;
1616

17+
static NSString *mangledNameFromClass(Class cls)
18+
{
19+
return [NSString stringWithFormat:@"__JSB_%@", NSStringFromClass(cls)];
20+
}
21+
1722
static NSString *propertyNameFromSelector(SEL selector)
1823
{
1924
NSArray *split = [NSStringFromSelector(selector) componentsSeparatedByString:@":"];
@@ -140,6 +145,10 @@ static void setReturnValue(JSValue *value, NSInvocation *invocation)
140145
NSMethodSignature *methodSignature = invocation.methodSignature;
141146
const char *type = methodSignature.methodReturnType;
142147

148+
if (strcmp(type, @encode(void)) == 0) {
149+
return;
150+
}
151+
143152
if (strcmp(type, @encode(char)) == 0 ||
144153
strcmp(type, @encode(short)) == 0 ||
145154
strcmp(type, @encode(int)) == 0 ||
@@ -159,8 +168,10 @@ static void setReturnValue(JSValue *value, NSInvocation *invocation)
159168
BOOL returnValue = value.toBool;
160169
[invocation setReturnValue:&returnValue];
161170
} else if (strcmp(type, @encode(float)) == 0 ||
162-
strcmp(type, @encode(double)) == 0 ||
163171
strcmp(type, @encode(CGFloat)) == 0) {
172+
float returnValue = value.toDouble;
173+
[invocation setReturnValue:&returnValue];
174+
} else if (strcmp(type, @encode(double)) == 0) {
164175
double returnValue = value.toDouble;
165176
[invocation setReturnValue:&returnValue];
166177
} else {
@@ -169,7 +180,7 @@ static void setReturnValue(JSValue *value, NSInvocation *invocation)
169180
}
170181
}
171182

172-
static void setupForwardingImplementations(Class cls, JSValue *functions)
183+
static void setupForwardingImplementations(Class targetClass, Class cls, JSValue *functions)
173184
{
174185
unsigned int count = 0;
175186
Method *methods = class_copyMethodList(cls, &count);
@@ -180,7 +191,7 @@ static void setupForwardingImplementations(Class cls, JSValue *functions)
180191
NSString *propertyName = propertyNameFromSelector(description->name);
181192
JSValue *function = functions[propertyName];
182193
if (!function.isUndefined) {
183-
method_setImplementation(m, _objc_msgForward);
194+
class_addMethod(targetClass, description->name, _objc_msgForward, description->types);
184195
}
185196
}
186197
if (methods) {
@@ -189,19 +200,24 @@ static void setupForwardingImplementations(Class cls, JSValue *functions)
189200

190201
Class superClass = class_getSuperclass(cls);
191202
if (superClass) {
192-
setupForwardingImplementations(superClass, functions);
203+
setupForwardingImplementations(targetClass, superClass, functions);
193204
}
194205
}
195206

196207
static void forwardInvocation(id self, SEL _cmd, NSInvocation *invocation)
197208
{
209+
JSContext *context = globalContext;
210+
context[@"self"] = self;
211+
198212
NSString *propertyName = propertyNameFromSelector(invocation.selector);
199-
JSValue *value = globalContext[NSStringFromClass([self class])][@"instanceMembers"][propertyName];
213+
JSValue *value = globalContext[mangledNameFromClass([self class])][@"instanceMembers"][propertyName];
200214

201215
NSArray *arguments = extractArguments(invocation);
202216
JSValue *returnValue = [value callWithArguments:arguments];
203217

204218
setReturnValue(returnValue, invocation);
219+
220+
context[@"self"] = [NSNull null];
205221
}
206222

207223
static NSMethodSignature *methodSignatureForSelector(id self, SEL _cmd, SEL selector)
@@ -221,7 +237,7 @@ static void forwardInvocation(id self, SEL _cmd, NSInvocation *invocation)
221237
static BOOL respondsToSelector(id self, SEL _cmd, SEL selector)
222238
{
223239
NSString *propertyName = propertyNameFromSelector(selector);
224-
JSValue *value = globalContext[NSStringFromClass([self class])][@"instanceMembers"][propertyName];
240+
JSValue *value = globalContext[mangledNameFromClass([self class])][@"instanceMembers"][propertyName];
225241

226242
return !value.isUndefined;
227243
}
@@ -243,11 +259,15 @@ + (void)initialize
243259

244260
globalContext[@"JSB"] = [JSBScriptingSupport class];
245261
[globalContext evaluateScript:
246-
@"JSB.Class = {};"
262+
@"JSB.Class = (function() {"
263+
@" var namespace = {"
264+
@" define: function(declaration, instanceMembers, staticMembers) {"
265+
@" return JSB.defineClass(declaration, instanceMembers, staticMembers);"
266+
@" }"
267+
@" };"
247268
@""
248-
@"JSB.Class.define = function(declaration, instanceMembers, staticMembers) {"
249-
@" JSB.defineClass(declaration, instanceMembers, staticMembers);"
250-
@"};"
269+
@" return namespace;"
270+
@"})();"
251271
];
252272
});
253273
}
@@ -259,9 +279,9 @@ + (JSContext *)globalContext
259279
return globalContext;
260280
}
261281

262-
+ (void)defineClass:(NSString *)declaration
263-
instanceMembers:(JSValue *)instanceMembers
264-
staticMembers:(JSValue *)staticMembers
282+
+ (id)defineClass:(NSString *)declaration
283+
instanceMembers:(JSValue *)instanceMembers
284+
staticMembers:(JSValue *)staticMembers
265285
{
266286
NSScanner *scanner = [NSScanner scannerWithString:declaration];
267287

@@ -289,7 +309,7 @@ + (void)defineClass:(NSString *)declaration
289309

290310
Class superClass = class_getSuperclass(cls);
291311
if (superClass) {
292-
setupForwardingImplementations(superClass, instanceMembers);
312+
setupForwardingImplementations(cls, superClass, instanceMembers);
293313
}
294314

295315
NSString *types;
@@ -309,14 +329,15 @@ + (void)defineClass:(NSString *)declaration
309329
}
310330

311331
class_addProtocol(cls, @protocol(JSBNSObject));
312-
#if DEBUG
313-
class_addProtocol(cls, @protocol(JSBScriptingSupport));
314-
#endif
315332

316-
globalContext[className] = cls;
317-
globalContext[className][@"instanceMembers"] = instanceMembers;
333+
globalContext[mangledNameFromClass(cls)] = cls;
334+
globalContext[mangledNameFromClass(cls)][@"instanceMembers"] = instanceMembers;
335+
336+
return cls;
318337
}
319338

339+
#pragma mark - for debug
340+
320341
+ (void)dump:(id)object
321342
{
322343
NSLog(@"%@", object);

Examples/UICatalog/UICatalog.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
149AE1091876E8BC00018A8C /* buttonsViewController.js in Resources */ = {isa = PBXBuildFile; fileRef = 149AE1081876E8BC00018A8C /* buttonsViewController.js */; };
1011
149C53A51875C5870003EE16 /* JSBScriptingSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 149C53A21875C5870003EE16 /* JSBScriptingSupport.m */; };
1112
149C53A61875C5870003EE16 /* JSContext+Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = 149C53A41875C5870003EE16 /* JSContext+Helper.m */; };
1213
149C56691875C5BB0003EE16 /* JSBAVFoundation.m in Sources */ = {isa = PBXBuildFile; fileRef = 149C53DC1875C5B90003EE16 /* JSBAVFoundation.m */; };
@@ -51,6 +52,7 @@
5152
/* End PBXBuildFile section */
5253

5354
/* Begin PBXFileReference section */
55+
149AE1081876E8BC00018A8C /* buttonsViewController.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = buttonsViewController.js; sourceTree = "<group>"; };
5456
149C539F1875C5870003EE16 /* JavaScriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JavaScriptBridge.h; path = ../../../Classes/JavaScriptBridge.h; sourceTree = "<group>"; };
5557
149C53A01875C5870003EE16 /* JSBNSObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSBNSObject.h; path = ../../../Classes/JSBNSObject.h; sourceTree = "<group>"; };
5658
149C53A11875C5870003EE16 /* JSBScriptingSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSBScriptingSupport.h; path = ../../../Classes/JSBScriptingSupport.h; sourceTree = "<group>"; };
@@ -1743,6 +1745,7 @@
17431745
14B5CD2E1875C3740019A135 /* AppDelegate.h */,
17441746
14B5CD2F1875C3740019A135 /* AppDelegate.m */,
17451747
14B5CD4E1875C3FF0019A135 /* main.js */,
1748+
149AE1081876E8BC00018A8C /* buttonsViewController.js */,
17461749
14B5CD311875C3740019A135 /* Images.xcassets */,
17471750
14B5CD261875C3740019A135 /* Supporting Files */,
17481751
149C53A71875C59C0003EE16 /* Vendor */,
@@ -1812,6 +1815,7 @@
18121815
isa = PBXResourcesBuildPhase;
18131816
buildActionMask = 2147483647;
18141817
files = (
1818+
149AE1091876E8BC00018A8C /* buttonsViewController.js in Resources */,
18151819
14B5CD4F1875C3FF0019A135 /* main.js in Resources */,
18161820
14B5CD2A1875C3740019A135 /* InfoPlist.strings in Resources */,
18171821
14B5CD321875C3740019A135 /* Images.xcassets in Resources */,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"images" : [
3+
{
4+
"idiom" : "universal",
5+
"scale" : "1x",
6+
"filename" : "blueButton.png"
7+
},
8+
{
9+
"idiom" : "universal",
10+
"scale" : "2x"
11+
}
12+
],
13+
"info" : {
14+
"version" : 1,
15+
"author" : "xcode"
16+
}
17+
}
1.43 KB
Loading
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"images" : [
3+
{
4+
"idiom" : "universal",
5+
"scale" : "1x",
6+
"filename" : "whiteButton.png"
7+
},
8+
{
9+
"idiom" : "universal",
10+
"scale" : "2x"
11+
}
12+
],
13+
"info" : {
14+
"version" : 1,
15+
"author" : "xcode"
16+
}
17+
}
1.4 KB
Loading
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
(function() {
2+
var ButtonsViewController = JSB.Class.define('ButtonsViewController : UITableViewController', {
3+
viewDidLoad: function() {
4+
self.navigationItem.title = 'Buttons';
5+
6+
this.dataSourceArray = [];
7+
8+
var buttonBackground = UIImage.imageNamed('whiteButton');
9+
var buttonBackgroundPressed = UIImage.imageNamed('blueButton');
10+
11+
var frame = {x: 0, y: 5, width: 106, height: 40};
12+
13+
var button = UIButton.alloc().initWithFrame(frame);
14+
15+
button.contentVerticalAlignment = 0;
16+
button.contentHorizontalAlignment = 0;
17+
button.setTitleForState('Gray', 0);
18+
button.setTitleColorForState(UIColor.blackColor(), 0);
19+
20+
var newImage = buttonBackground.stretchableImageWithLeftCapWidthTopCapHeight(12, 0);
21+
button.setBackgroundImageForState(newImage, 0);
22+
23+
var newPressedImage = buttonBackgroundPressed.stretchableImageWithLeftCapWidthTopCapHeight(12, 0);
24+
button.setBackgroundImageForState(newPressedImage, 1 << 0);
25+
26+
button.backgroundColor = UIColor.clearColor();
27+
button.tag = 1;
28+
29+
dataSourceArray.push({
30+
sectionTitleKey: 'UIButton',
31+
labelKey: 'Background Image',
32+
sourceKey: 'ButtonsViewController.m:\r(UIButton *)grayButton',
33+
viewKey: button
34+
});
35+
},
36+
numberOfSectionsInTableView: function(tableView) {
37+
return dataSourceArray.length;
38+
},
39+
tableViewNumberOfRowsInSection: function(tableView, section) {
40+
return 2;
41+
},
42+
tableViewTitleForHeaderInSection: function(tableView, section) {
43+
return dataSourceArray[section]['sectionTitleKey'];
44+
},
45+
tableViewHeightForRowAtIndexPath: function(tableView, indexPath) {
46+
return (indexPath.row == 0) ? 50 : 38;
47+
},
48+
tableViewCellForRowAtIndexPath: function(tableView, indexPath) {
49+
if (indexPath.row == 0) {
50+
var cell = UITableViewCell.alloc().initWithStyleReuseIdentifier(0, 'DisplayCellID');
51+
cell.selectionStyle = 0;
52+
53+
var viewToRemove = null;
54+
viewToRemove = cell.contentView.viewWithTag(1);
55+
if (viewToRemove) {
56+
viewToRemove.removeFromSuperview();
57+
}
58+
59+
cell.textLabel.text = dataSourceArray[indexPath.section]['labelKey'];
60+
var button = dataSourceArray[indexPath.section]['viewKey'];
61+
62+
var newFrame = button.frame;
63+
newFrame.x = cell.contentView.frame.width - newFrame.width - 10;
64+
button.frame = newFrame;
65+
66+
button.autoresizingMask = 1 << 0;
67+
68+
cell.contentView.addSubview(button);
69+
70+
return cell;
71+
} else {
72+
var cell = UITableViewCell.alloc().initWithStyleReuseIdentifier(0, 'SourceCellID');
73+
cell.selectionStyle = 0;
74+
75+
cell.textLabel.opaque = false;
76+
cell.textLabel.textAlignment = 1;
77+
cell.textLabel.textColor = UIColor.grayColor();
78+
cell.textLabel.numberOfLines = 2;
79+
cell.textLabel.highlightedTextColor = UIColor.blackColor();
80+
cell.textLabel.font = UIFont.systemFontOfSize(12);
81+
cell.textLabel.text = menuList[indexPath.section]['sourceKey'];
82+
83+
return cell;
84+
}
85+
}
86+
});
87+
})();
88+

Examples/UICatalog/UICatalog/main.js

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,34 @@
1-
JSB.Class.define('MainViewController : UITableViewController',
2-
{
3-
numberOfSectionsInTableView: function (tableView) {
4-
return 2;
5-
},
6-
tableViewNumberOfRowsInSection: function (tableView, section) {
7-
return 10;
8-
},
9-
tableViewCellForRowAtIndexPath: function (tableView, indexPath) {
10-
var cell = UITableViewCell.new();
11-
return cell;
12-
}
13-
},
14-
{
151

2+
JSB.Module.require('buttonsViewController');
3+
4+
var MainViewController = JSB.Class.define('MainViewController : UITableViewController', {
5+
viewDidLoad: function() {
6+
self.navigationItem.title = 'UICatalog';
7+
8+
this.menuList = [];
9+
10+
var viewController = ButtonsViewController.new();
11+
menuList.push({
12+
title: 'Buttons',
13+
explanation: 'Various uses of UIButton',
14+
viewController: viewController
15+
});
16+
},
17+
tableViewNumberOfRowsInSection: function(tableView, section) {
18+
return menuList.length;
19+
},
20+
tableViewCellForRowAtIndexPath: function(tableView, indexPath) {
21+
var cell = UITableViewCell.alloc().initWithStyleReuseIdentifier(3, 'Cell');
22+
cell.accessoryType = 1;
23+
cell.textLabel.text = menuList[indexPath.row]['title'];
24+
cell.detailTextLabel.text = menuList[indexPath.row]['explanation'];
25+
26+
return cell;
27+
},
28+
tableViewDidSelectRowAtIndexPath: function(tableView, indexPath) {
29+
var targetViewController = menuList[indexPath.row]['viewController'];
30+
self.navigationController.pushViewControllerAnimated(targetViewController, true);
31+
}
1632
});
1733

1834
var window = UIWindow.alloc().initWithFrame(UIScreen.mainScreen().bounds);

0 commit comments

Comments
 (0)