├── JSBridgeTest ├── html │ ├── index.html │ ├── script.js │ └── jquery-1.4.4.min.js ├── JSBridgeTest_Prefix.pch ├── main.m ├── Classes │ ├── RootViewController.h │ ├── JSBridgeTestAppDelegate.h │ ├── JSBridgeTestAppDelegate.m │ └── RootViewController.m ├── JSBridgeTest-Info.plist ├── JSBridgeTest.xcodeproj │ └── project.pbxproj ├── RootViewController.xib └── MainWindow.xib ├── JavaScriptBridge ├── NSStringAdditions.h ├── Util.h ├── JavaScriptBridgeReceiver.h ├── JavaScriptBridgeURLConnectionDelegate.h ├── JavaScriptBridge.h ├── JavaScriptBridgeReceiver.m ├── NSStringAdditions.m ├── JavaScriptBridgeURLConnectionDelegate.m └── JavaScriptBridge.m └── README.md /JSBridgeTest/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | js-objc-bridge 4 | 5 | 6 | 7 | 8 |

js-objc-bridge

9 |

10 | 
11 | 
12 | 


--------------------------------------------------------------------------------
/JSBridgeTest/JSBridgeTest_Prefix.pch:
--------------------------------------------------------------------------------
 1 | //
 2 | // Prefix header for all source files of the 'JSBridgeTest' target in the 'JSBridgeTest' project
 3 | //
 4 | #import 
 5 | 
 6 | #ifndef __IPHONE_3_0
 7 | #warning "This project uses features only available in iPhone SDK 3.0 and later."
 8 | #endif
 9 | 
10 | 
11 | #ifdef __OBJC__
12 |     #import 
13 |     #import 
14 | #endif
15 | 


--------------------------------------------------------------------------------
/JSBridgeTest/main.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  main.m
 3 | //  JSBridgeTest
 4 | //
 5 | //  Created by Toru Hisai on 11/03/25.
 6 | //  Copyright 2011 Kronecker's Delta Studio. All rights reserved.
 7 | //
 8 | 
 9 | #import 
10 | 
11 | int main(int argc, char *argv[]) {
12 |     
13 |     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
14 |     int retVal = UIApplicationMain(argc, argv, nil, nil);
15 |     [pool release];
16 |     return retVal;
17 | }
18 | 


--------------------------------------------------------------------------------
/JavaScriptBridge/NSStringAdditions.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  NSStringAdditions.h
 3 | //  JSBridgeTest
 4 | //
 5 | //  Created by Toru Hisai on 11/03/27.
 6 | //  Copyright 2011 Kronecker's Delta Studio. All rights reserved.
 7 | //
 8 | 
 9 | // copied from http://stackoverflow.com/questions/392464/any-base64-library-on-iphone-sdk
10 | 
11 | #import 
12 | 
13 | @interface NSString (NSStringAdditions)
14 | 
15 | + (NSString *) base64StringFromData:(NSData *)data length:(int)length;
16 | 
17 | @end
18 | 


--------------------------------------------------------------------------------
/JavaScriptBridge/Util.h:
--------------------------------------------------------------------------------
 1 | /*
 2 |  *  Util.h
 3 |  *  JSBridgeTest
 4 |  *
 5 |  *  Created by Toru Hisai on 11/04/15.
 6 |  *  Copyright 2011 Kronecker's Delta Studio. All rights reserved.
 7 |  *
 8 |  */
 9 | 
10 | #ifdef DEBUG_MODE
11 | #define DebugLog( s, ... ) NSLog( @"<%s : (%d)> %@",__func__, __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
12 | #else
13 | #define DebugLog( s, ... ) 
14 | #endif
15 | 
16 | #define ErrorLog( s, ... ) NSLog( @" %@",__func__, __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
17 | 


--------------------------------------------------------------------------------
/JavaScriptBridge/JavaScriptBridgeReceiver.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  JavaScriptBridgeReceiver.h
 3 | //  JSBridgeTest
 4 | //
 5 | //  Created by Toru Hisai on 11/03/25.
 6 | //  Copyright 2011 Kronecker's Delta Studio. All rights reserved.
 7 | //
 8 | 
 9 | #import 
10 | #import "JavaScriptBridge.h"
11 | 
12 | @interface JavaScriptBridgeReceiver : NSObject {
13 |     JavaScriptBridge *bridge;
14 | }
15 | 
16 | @property(nonatomic, retain) JavaScriptBridge *bridge;
17 | 
18 | - (void)feedInstructions:(NSArray *)instructions;
19 | 
20 | @end
21 | 


--------------------------------------------------------------------------------
/JSBridgeTest/Classes/RootViewController.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  RootViewController.h
 3 | //  JSBridgeTest
 4 | //
 5 | //  Created by Toru Hisai on 11/03/25.
 6 | //  Copyright 2011 Kronecker's Delta Studio. All rights reserved.
 7 | //
 8 | 
 9 | #import 
10 | #import "JavaScriptBridgeReceiver.h"
11 | 
12 | @interface RootViewController : UITableViewController {
13 |     UIWebView *webView;
14 |     JavaScriptBridgeReceiver *receiver;
15 | }
16 | 
17 | @property(nonatomic, retain) UIWebView *webView;
18 | @property(nonatomic, retain) JavaScriptBridgeReceiver *receiver;
19 | 
20 | @end
21 | 


--------------------------------------------------------------------------------
/JSBridgeTest/Classes/JSBridgeTestAppDelegate.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  JSBridgeTestAppDelegate.h
 3 | //  JSBridgeTest
 4 | //
 5 | //  Created by Toru Hisai on 11/03/25.
 6 | //  Copyright 2011 Kronecker's Delta Studio. All rights reserved.
 7 | //
 8 | 
 9 | #import 
10 | 
11 | @interface JSBridgeTestAppDelegate : NSObject  {
12 |     
13 |     UIWindow *window;
14 |     UINavigationController *navigationController;
15 | }
16 | 
17 | @property (nonatomic, retain) IBOutlet UIWindow *window;
18 | @property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
19 | 
20 | @end
21 | 
22 | 


--------------------------------------------------------------------------------
/JSBridgeTest/JSBridgeTest-Info.plist:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 | 
 4 | 
 5 | 	CFBundleDevelopmentRegion
 6 | 	English
 7 | 	CFBundleDisplayName
 8 | 	${PRODUCT_NAME}
 9 | 	CFBundleExecutable
10 | 	${EXECUTABLE_NAME}
11 | 	CFBundleIconFile
12 | 	
13 | 	CFBundleIdentifier
14 | 	jp.torus.elepaio
15 | 	CFBundleInfoDictionaryVersion
16 | 	6.0
17 | 	CFBundleName
18 | 	${PRODUCT_NAME}
19 | 	CFBundlePackageType
20 | 	APPL
21 | 	CFBundleSignature
22 | 	????
23 | 	CFBundleVersion
24 | 	1.0
25 | 	LSRequiresIPhoneOS
26 | 	
27 | 	NSMainNibFile
28 | 	MainWindow
29 | 
30 | 
31 | 


--------------------------------------------------------------------------------
/JavaScriptBridge/JavaScriptBridgeURLConnectionDelegate.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  JavaScriptBridgeURLConnectionHandler.h
 3 | //  JSBridgeTest
 4 | //
 5 | //  Created by Toru Hisai on 11/03/27.
 6 | //  Copyright 2011 Kronecker's Delta Studio. All rights reserved.
 7 | //
 8 | 
 9 | #import 
10 | 
11 | 
12 | @interface JavaScriptBridgeURLConnectionDelegate : NSObject {
13 |     UIWebView *webView;
14 |     NSUInteger connectionID;
15 | }
16 | 
17 | @property(nonatomic, retain) UIWebView *webView;
18 | @property NSUInteger connectionID;
19 | 
20 | - (id)initWithWebView:(UIWebView *)webView;
21 | 
22 | - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
23 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
24 | - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
25 | - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
26 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection;
27 | 
28 | 
29 | @end
30 | 


--------------------------------------------------------------------------------
/JavaScriptBridge/JavaScriptBridge.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  JavaScriptBridge.h
 3 | //  Untitled
 4 | //
 5 | //  Created by Toru Hisai on 3/25/11.
 6 | //  Copyright 2011 Avatar Reality Inc. All rights reserved.
 7 | //
 8 | 
 9 | #import 
10 | 
11 | 
12 | @interface JavaScriptBridge : NSObject {
13 | 	NSMutableArray *stack;
14 |     UIWebView *webView;
15 |     UIViewController *viewController;
16 | }
17 | 
18 | @property(nonatomic, retain) NSMutableArray *stack;
19 | @property(nonatomic, retain) UIWebView *webView;
20 | @property(nonatomic, retain) UIViewController *viewController;
21 | 
22 | - (void)push:(id)operand;
23 | - (id)pop;
24 | - (int)stackDepth;
25 | - (void)operate:(NSString*)op;
26 | - (void)error:(NSString*)mesg;
27 | - (void)eval:(NSString*)expr;
28 | 
29 | - (void)op_callback;
30 | 
31 | - (void)op_num;
32 | - (void)op_int;
33 | - (void)op_str;
34 | - (void)op_hexstr;
35 | - (void)op_hexifydata;
36 | - (void)op_base64data;
37 | 
38 | - (void)op_hmac_sha1;
39 | - (void)op_http_get;
40 | - (void)op_http_post;
41 | - (void)op_http_send;
42 | - (void)op_store_twitter_credential;
43 | - (void)op_twitter_credential;
44 | - (void)op_open_url_in_new_browser;
45 | - (void)op_close_browser;
46 | - (void)op_close_browser;
47 | 
48 | - (void)op_create_instance;
49 | 
50 | 
51 | @end
52 | 
53 | 


--------------------------------------------------------------------------------
/JavaScriptBridge/JavaScriptBridgeReceiver.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  JavaScriptBridgeReceiver.m
 3 | //  JSBridgeTest
 4 | //
 5 | //  Created by Toru Hisai on 11/03/25.
 6 | //  Copyright 2011 Kronecker's Delta Studio. All rights reserved.
 7 | //
 8 | 
 9 | #import "Util.h"
10 | #import "JavaScriptBridgeReceiver.h"
11 | 
12 | @implementation JavaScriptBridgeReceiver
13 | 
14 | @synthesize bridge;
15 | 
16 | - (id)init {
17 |     [super init];
18 |     
19 |     JavaScriptBridge *brdg = [[JavaScriptBridge alloc] init];
20 |     [self setBridge:brdg];
21 |     [brdg release];
22 | 
23 |     return self;
24 | }
25 | 
26 | - (void)dealloc {
27 |     [super dealloc];
28 |     [self setBridge:nil];
29 | }
30 | 
31 | - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
32 |     NSURL *url = [request URL];
33 |     NSString *scheme = [url scheme];
34 |     DebugLog(@"url: %@", url);
35 |     
36 |     if ([scheme isEqualToString:@"bridge"]) {
37 |         NSArray *path = [url pathComponents];
38 |         DebugLog(@"path: %@", path);
39 |         
40 |         [self performSelector:@selector(feedInstructions:) withObject:path afterDelay:0];
41 |         
42 |         return NO;
43 |     } else if ([scheme isEqualToString:@"bridge-callback"]) {
44 |         NSString *func = [url host];// host part indicates function
45 |         NSString *q = [url query];
46 |         
47 |         [[self bridge] push:[q dataUsingEncoding:NSUTF8StringEncoding]];
48 |         [[self bridge] operate:@"hexifydata"];
49 |         [[self bridge] push:func];
50 |         [[self bridge] push:[NSNumber numberWithInt:1]];
51 |         [[self bridge] operate:@"callback"];
52 |         
53 |         return NO;
54 |     }
55 |     
56 |     return YES;
57 | //    return NO;// always returns NO. Create a new UIWebView to show other web pages.
58 | }
59 | 
60 | - (void)feedInstructions:(NSArray *)instructions {
61 |     for (NSString *str in instructions) {
62 |         unichar head = [str characterAtIndex:0];
63 |         NSString *tail = [str substringFromIndex:1];
64 |         DebugLog(@"-- begin %@", str);
65 |         switch (head) {
66 |             case '-':// operand
67 |                 [[self bridge] push:tail];
68 |                 break;
69 |             case '@':// operator
70 |                 [[self bridge] operate:tail];
71 |                 break;
72 |             default:
73 |                 break;
74 |         }
75 |         DebugLog(@"-- end %@", str);
76 |     }
77 | }
78 | 
79 | @end
80 | 


--------------------------------------------------------------------------------
/JavaScriptBridge/NSStringAdditions.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  NSStringAdditions.m
 3 | //  JSBridgeTest
 4 | //
 5 | //  Created by Toru Hisai on 11/03/27.
 6 | //  Copyright 2011 Kronecker's Delta Studio. All rights reserved.
 7 | //
 8 | 
 9 | #import "NSStringAdditions.h"
10 | 
11 | 
12 | static char base64EncodingTable[64] = {
13 |     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
14 |     'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
15 |     'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
16 |     'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
17 | };
18 | 
19 | @implementation NSString (NSStringAdditions)
20 | 
21 | + (NSString *) base64StringFromData: (NSData *)data length: (int)length {
22 |     unsigned long ixtext, lentext;
23 |     long ctremaining;
24 |     unsigned char input[3], output[4];
25 |     short i, charsonline = 0, ctcopy;
26 |     const unsigned char *raw;
27 |     NSMutableString *result;
28 |     
29 |     lentext = [data length]; 
30 |     if (lentext < 1)
31 |         return @"";
32 |     result = [NSMutableString stringWithCapacity: lentext];
33 |     raw = [data bytes];
34 |     ixtext = 0; 
35 |     
36 |     while (true) {
37 |         ctremaining = lentext - ixtext;
38 |         if (ctremaining <= 0) 
39 |             break;        
40 |         for (i = 0; i < 3; i++) { 
41 |             unsigned long ix = ixtext + i;
42 |             if (ix < lentext)
43 |                 input[i] = raw[ix];
44 |             else
45 |                 input[i] = 0;
46 |         }
47 |         output[0] = (input[0] & 0xFC) >> 2;
48 |         output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
49 |         output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
50 |         output[3] = input[2] & 0x3F;
51 |         ctcopy = 4;
52 |         switch (ctremaining) {
53 |             case 1: 
54 |                 ctcopy = 2; 
55 |                 break;
56 |             case 2: 
57 |                 ctcopy = 3; 
58 |                 break;
59 |         }
60 |         
61 |         for (i = 0; i < ctcopy; i++)
62 |             [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
63 |         
64 |         for (i = ctcopy; i < 4; i++)
65 |             [result appendString: @"="];
66 |         
67 |         ixtext += 3;
68 |         charsonline += 4;
69 |         
70 |         if ((length > 0) && (charsonline >= length))
71 |             charsonline = 0;
72 |     }     
73 |     return result;
74 | }
75 | 
76 | @end
77 | 


--------------------------------------------------------------------------------
/JavaScriptBridge/JavaScriptBridgeURLConnectionDelegate.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  JavaScriptBridgeURLConnectionHandler.m
 3 | //  JSBridgeTest
 4 | //
 5 | //  Created by Toru Hisai on 11/03/27.
 6 | //  Copyright 2011 Kronecker's Delta Studio. All rights reserved.
 7 | //
 8 | 
 9 | #import "JavaScriptBridgeURLConnectionDelegate.h"
10 | #import "Util.h"
11 | 
12 | @implementation JavaScriptBridgeURLConnectionDelegate
13 | 
14 | @synthesize webView, connectionID;
15 | 
16 | - (id)initWithWebView:(UIWebView *)webView_ {
17 |     static NSUInteger connid = 0;
18 |     
19 |     self = [super init];
20 |     if (self) {
21 |         [self setWebView:webView_];
22 |         [self setConnectionID:connid++];
23 |     }
24 |     return self;
25 | }
26 | 
27 | - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
28 |     NSString *err = [NSString stringWithFormat:@"%@", error];
29 |     DebugLog(@"didFailWithError: %@", err);
30 |     [[self webView] stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"connectionDidFailWithError(%d, \"%@\")", [self connectionID], err]];
31 | }
32 | 
33 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
34 |     NSMutableString *str = [[NSMutableString alloc] init];
35 |     const unsigned char *bytes = [data bytes];
36 |     NSUInteger len = [data length];
37 |     
38 |     for (NSUInteger i = 0; i < len; i ++) {
39 |         unsigned char ch = bytes[i];
40 |         [str appendFormat:@"%02x", ch];
41 |     }
42 | 
43 |     [[self webView] stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"connectionDidReceiveData(%d, __hex(\"%@\"))", [self connectionID], str]];
44 | }
45 | 
46 | - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
47 |     [[self webView] stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"connectionDidReceiveResponse(%d)", [self connectionID]]];
48 | }
49 | 
50 | - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
51 |     [[self webView] stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"connectionDidSendBodyData(%d)", [self connectionID]]];
52 | }
53 | 
54 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
55 |     [[self webView] stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"connectionDidFinishLoading(%d)", [self connectionID]]];
56 | }
57 | 
58 | - (void)dealloc {
59 |     [self setWebView:nil];
60 |     [super dealloc];
61 | }
62 | 
63 | @end
64 | 


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
 1 | JavaScript-Objective-C Bridge
 2 | =============================
 3 | 
 4 | The JavaScript-Objective-C bridge lets you call Objective-C functions from JavaScript code loaded in a UIWebView instance.
 5 | 
 6 | Note that this project is currently VERY VERY ALPHA state. Please don't use it:)
 7 | 
 8 | Demo Video
 9 | -----------
10 | 
11 | [See on YouTube](http://www.youtube.com/watch?v=sbs7L4WUhU4)
12 | 
13 | Low Level API
14 | -------------
15 | 
16 | Pass operands and operators through the `location.href` property.
17 | The path part of the specifined URL is used to represent a sequence of instruction.
18 | JavaScript-Objective-C bridge bridge works as a stack machine.
19 | 
20 | For example:
21 | 
22 |     location.href = "bridge:///-123/-456/@add/-hoge/-1/@callback"
23 | 
24 | In this example, list of instructions is represented as `-123/-456/@add/-hoge/-1/@callback`.
25 | A path component beginning with `-` means a operand, and a path component beginning with `@` means operator.
26 | 
27 | Operators are defined as methods of the `JavaScriptBridge` class.  See the source code for more detail.
28 | 
29 | 
30 | How It Works
31 | -------------------
32 | 
33 | JavaScript code sends a list of instructions to the delegate object through the `location.href` property.
34 | Each instruction is packed in a path part in a URL.
35 | This list of instructions is processed by a stack machine implemented in the delegate object.
36 | 
37 | Objective-C code sends message via `stringByEvaluatingJavaScriptFromString:` method on UIWebView class.
38 | 
39 | 
40 | License (BSD License)
41 | -------
42 | 
43 | Copyright (c) 2011, Toru Hisai
44 | All rights reserved.
45 | 
46 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
47 | 
48 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
49 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
50 | 
51 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 | 
53 | 
54 | Author
55 | ---------
56 | 
57 | Toru Hisai [@torus](http://twitter.com/torus)
58 | 


--------------------------------------------------------------------------------
/JSBridgeTest/Classes/JSBridgeTestAppDelegate.m:
--------------------------------------------------------------------------------
 1 | //
 2 | //  JSBridgeTestAppDelegate.m
 3 | //  JSBridgeTest
 4 | //
 5 | //  Created by Toru Hisai on 11/03/25.
 6 | //  Copyright 2011 Kronecker's Delta Studio. All rights reserved.
 7 | //
 8 | 
 9 | #import "JSBridgeTestAppDelegate.h"
10 | #import "RootViewController.h"
11 | 
12 | 
13 | @implementation JSBridgeTestAppDelegate
14 | 
15 | @synthesize window;
16 | @synthesize navigationController;
17 | 
18 | 
19 | #pragma mark -
20 | #pragma mark Application lifecycle
21 | 
22 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
23 |     
24 |     // Override point for customization after application launch.
25 |     
26 |     // Add the navigation controller's view to the window and display.
27 |     [self.window addSubview:navigationController.view];
28 |     [self.window makeKeyAndVisible];
29 | 
30 |     return YES;
31 | }
32 | 
33 | 
34 | - (void)applicationWillResignActive:(UIApplication *)application {
35 |     /*
36 |      Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
37 |      Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
38 |      */
39 | }
40 | 
41 | 
42 | - (void)applicationDidEnterBackground:(UIApplication *)application {
43 |     /*
44 |      Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
45 |      If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
46 |      */
47 | }
48 | 
49 | 
50 | - (void)applicationWillEnterForeground:(UIApplication *)application {
51 |     /*
52 |      Called as part of  transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
53 |      */
54 | }
55 | 
56 | 
57 | - (void)applicationDidBecomeActive:(UIApplication *)application {
58 |     /*
59 |      Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
60 |      */
61 | }
62 | 
63 | 
64 | - (void)applicationWillTerminate:(UIApplication *)application {
65 |     /*
66 |      Called when the application is about to terminate.
67 |      See also applicationDidEnterBackground:.
68 |      */
69 | }
70 | 
71 | 
72 | #pragma mark -
73 | #pragma mark Memory management
74 | 
75 | - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
76 |     /*
77 |      Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
78 |      */
79 | }
80 | 
81 | 
82 | - (void)dealloc {
83 | 	[navigationController release];
84 | 	[window release];
85 | 	[super dealloc];
86 | }
87 | 
88 | 
89 | @end
90 | 
91 | 


--------------------------------------------------------------------------------
/JSBridgeTest/Classes/RootViewController.m:
--------------------------------------------------------------------------------
  1 | //
  2 | //  RootViewController.m
  3 | //  JSBridgeTest
  4 | //
  5 | //  Created by Toru Hisai on 11/03/25.
  6 | //  Copyright 2011 Kronecker's Delta Studio. All rights reserved.
  7 | //
  8 | 
  9 | #import "RootViewController.h"
 10 | 
 11 | @implementation RootViewController
 12 | 
 13 | @synthesize webView, receiver;
 14 | 
 15 | #pragma mark -
 16 | #pragma mark View lifecycle
 17 | 
 18 | - (void)viewDidLoad {
 19 |     [super viewDidLoad];
 20 | 
 21 |     // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
 22 |     // self.navigationItem.rightBarButtonItem = self.editButtonItem;
 23 | 
 24 |     UIWebView *wv = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 340, 200)];
 25 |     [[self view] addSubview:wv];
 26 |     [self setWebView: wv];
 27 |     [wv release];
 28 |     
 29 |     JavaScriptBridgeReceiver *recv = [[JavaScriptBridgeReceiver alloc] init];
 30 |     [wv setDelegate:recv];
 31 |     [self setReceiver:recv];
 32 |     [recv release];
 33 |     
 34 |     [[recv bridge] setWebView:wv];
 35 |     [[recv bridge] setViewController:self];
 36 | 
 37 |     [wv loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]]]];
 38 | }
 39 | 
 40 | /*
 41 | - (void)viewWillAppear:(BOOL)animated {
 42 |     [super viewWillAppear:animated];
 43 | }
 44 | */
 45 | /*
 46 | - (void)viewDidAppear:(BOOL)animated {
 47 |     [super viewDidAppear:animated];
 48 | }
 49 | */
 50 | /*
 51 | - (void)viewWillDisappear:(BOOL)animated {
 52 | 	[super viewWillDisappear:animated];
 53 | }
 54 | */
 55 | /*
 56 | - (void)viewDidDisappear:(BOOL)animated {
 57 | 	[super viewDidDisappear:animated];
 58 | }
 59 | */
 60 | 
 61 | /*
 62 |  // Override to allow orientations other than the default portrait orientation.
 63 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 64 | 	// Return YES for supported orientations.
 65 | 	return (interfaceOrientation == UIInterfaceOrientationPortrait);
 66 | }
 67 |  */
 68 | 
 69 | 
 70 | #pragma mark -
 71 | #pragma mark Table view data source
 72 | 
 73 | // Customize the number of sections in the table view.
 74 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
 75 |     return 1;
 76 | }
 77 | 
 78 | 
 79 | // Customize the number of rows in the table view.
 80 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
 81 |     return 0;
 82 | }
 83 | 
 84 | 
 85 | // Customize the appearance of table view cells.
 86 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 87 |     
 88 |     static NSString *CellIdentifier = @"Cell";
 89 |     
 90 |     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
 91 |     if (cell == nil) {
 92 |         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
 93 |     }
 94 |     
 95 | 	// Configure the cell.
 96 | 
 97 |     return cell;
 98 | }
 99 | 
100 | 
101 | /*
102 | // Override to support conditional editing of the table view.
103 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
104 |     // Return NO if you do not want the specified item to be editable.
105 |     return YES;
106 | }
107 | */
108 | 
109 | 
110 | /*
111 | // Override to support editing the table view.
112 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
113 |     
114 |     if (editingStyle == UITableViewCellEditingStyleDelete) {
115 |         // Delete the row from the data source.
116 |         [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
117 |     }   
118 |     else if (editingStyle == UITableViewCellEditingStyleInsert) {
119 |         // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
120 |     }   
121 | }
122 | */
123 | 
124 | 
125 | /*
126 | // Override to support rearranging the table view.
127 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
128 | }
129 | */
130 | 
131 | 
132 | /*
133 | // Override to support conditional rearranging of the table view.
134 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
135 |     // Return NO if you do not want the item to be re-orderable.
136 |     return YES;
137 | }
138 | */
139 | 
140 | 
141 | #pragma mark -
142 | #pragma mark Table view delegate
143 | 
144 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
145 |     
146 | 	/*
147 | 	 <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
148 |      // ...
149 |      // Pass the selected object to the new view controller.
150 | 	 [self.navigationController pushViewController:detailViewController animated:YES];
151 | 	 [detailViewController release];
152 | 	 */
153 | }
154 | 
155 | 
156 | #pragma mark -
157 | #pragma mark Memory management
158 | 
159 | - (void)didReceiveMemoryWarning {
160 |     // Releases the view if it doesn't have a superview.
161 |     [super didReceiveMemoryWarning];
162 |     
163 |     // Relinquish ownership any cached data, images, etc that aren't in use.
164 | }
165 | 
166 | - (void)viewDidUnload {
167 |     // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
168 |     // For example: self.myOutlet = nil;
169 |     [[[self receiver] bridge] setWebView:nil];
170 |     [self setWebView:nil];
171 |     [self setReceiver:nil];
172 | }
173 | 
174 | 
175 | - (void)dealloc {
176 |     [super dealloc];
177 | 
178 |     [[[self receiver] bridge] setWebView:nil];
179 |     [self setWebView:nil];
180 |     [self setReceiver:nil];
181 | }
182 | 
183 | 
184 | @end
185 | 
186 | 


--------------------------------------------------------------------------------
/JSBridgeTest/JSBridgeTest.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
  1 | // !$*UTF8*$!
  2 | {
  3 | 	archiveVersion = 1;
  4 | 	classes = {
  5 | 	};
  6 | 	objectVersion = 45;
  7 | 	objects = {
  8 | 
  9 | /* Begin PBXBuildFile section */
 10 | 		1D3623260D0F684500981E51 /* JSBridgeTestAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* JSBridgeTestAppDelegate.m */; };
 11 | 		1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
 12 | 		1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
 13 | 		1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
 14 | 		2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; };
 15 | 		28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD735F0D9D9599002E5188 /* MainWindow.xib */; };
 16 | 		28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; };
 17 | 		28F335F11007B36200424DE2 /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28F335F01007B36200424DE2 /* RootViewController.xib */; };
 18 | 		9CB12DBF13432DF3001F9BA9 /* jquery-1.4.4.min.js in Resources */ = {isa = PBXBuildFile; fileRef = 9CB12DBD13432DEA001F9BA9 /* jquery-1.4.4.min.js */; };
 19 | 		9CDE08C3133DDB5800BC5FFC /* JavaScriptBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CDE08C2133DDB5800BC5FFC /* JavaScriptBridge.m */; };
 20 | 		9CDE08DB133DEE1D00BC5FFC /* JavaScriptBridgeReceiver.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CDE08DA133DEE1D00BC5FFC /* JavaScriptBridgeReceiver.m */; };
 21 | 		9CDE08F8133DF83F00BC5FFC /* index.html in Resources */ = {isa = PBXBuildFile; fileRef = 9CDE08F6133DF83F00BC5FFC /* index.html */; };
 22 | 		9CDE08FA133DF85500BC5FFC /* script.js in Resources */ = {isa = PBXBuildFile; fileRef = 9CDE08F7133DF83F00BC5FFC /* script.js */; };
 23 | 		9CDE09A6133F4A6200BC5FFC /* NSStringAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CDE09A5133F4A6200BC5FFC /* NSStringAdditions.m */; };
 24 | 		9CDE09D7133FF87800BC5FFC /* JavaScriptBridgeURLConnectionDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CDE09D6133FF87800BC5FFC /* JavaScriptBridgeURLConnectionDelegate.m */; };
 25 | /* End PBXBuildFile section */
 26 | 
 27 | /* Begin PBXFileReference section */
 28 | 		1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
 29 | 		1D3623240D0F684500981E51 /* JSBridgeTestAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBridgeTestAppDelegate.h; sourceTree = ""; };
 30 | 		1D3623250D0F684500981E51 /* JSBridgeTestAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSBridgeTestAppDelegate.m; sourceTree = ""; };
 31 | 		1D6058910D05DD3D006BFB54 /* JSBridgeTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JSBridgeTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
 32 | 		1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
 33 | 		2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
 34 | 		28A0AAE50D9B0CCF005BE974 /* JSBridgeTest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBridgeTest_Prefix.pch; sourceTree = ""; };
 35 | 		28AD735F0D9D9599002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; };
 36 | 		28C286DF0D94DF7D0034E888 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; };
 37 | 		28C286E00D94DF7D0034E888 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; };
 38 | 		28F335F01007B36200424DE2 /* RootViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RootViewController.xib; sourceTree = ""; };
 39 | 		29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
 40 | 		8D1107310486CEB800E47090 /* JSBridgeTest-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "JSBridgeTest-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; };
 41 | 		9C5882A813599B1C000E1184 /* Util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Util.h; path = ../JavaScriptBridge/Util.h; sourceTree = SOURCE_ROOT; };
 42 | 		9CB12DBD13432DEA001F9BA9 /* jquery-1.4.4.min.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = "jquery-1.4.4.min.js"; path = "html/jquery-1.4.4.min.js"; sourceTree = ""; };
 43 | 		9CDE08C1133DDB5800BC5FFC /* JavaScriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JavaScriptBridge.h; path = ../JavaScriptBridge/JavaScriptBridge.h; sourceTree = SOURCE_ROOT; };
 44 | 		9CDE08C2133DDB5800BC5FFC /* JavaScriptBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JavaScriptBridge.m; path = ../JavaScriptBridge/JavaScriptBridge.m; sourceTree = SOURCE_ROOT; };
 45 | 		9CDE08D9133DEE1D00BC5FFC /* JavaScriptBridgeReceiver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JavaScriptBridgeReceiver.h; path = ../JavaScriptBridge/JavaScriptBridgeReceiver.h; sourceTree = SOURCE_ROOT; };
 46 | 		9CDE08DA133DEE1D00BC5FFC /* JavaScriptBridgeReceiver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JavaScriptBridgeReceiver.m; path = ../JavaScriptBridge/JavaScriptBridgeReceiver.m; sourceTree = SOURCE_ROOT; };
 47 | 		9CDE08F6133DF83F00BC5FFC /* index.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = index.html; path = html/index.html; sourceTree = ""; };
 48 | 		9CDE08F7133DF83F00BC5FFC /* script.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = script.js; path = html/script.js; sourceTree = ""; };
 49 | 		9CDE09A4133F4A6200BC5FFC /* NSStringAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSStringAdditions.h; path = ../JavaScriptBridge/NSStringAdditions.h; sourceTree = SOURCE_ROOT; };
 50 | 		9CDE09A5133F4A6200BC5FFC /* NSStringAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSStringAdditions.m; path = ../JavaScriptBridge/NSStringAdditions.m; sourceTree = SOURCE_ROOT; };
 51 | 		9CDE09D5133FF87800BC5FFC /* JavaScriptBridgeURLConnectionDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JavaScriptBridgeURLConnectionDelegate.h; path = ../JavaScriptBridge/JavaScriptBridgeURLConnectionDelegate.h; sourceTree = SOURCE_ROOT; };
 52 | 		9CDE09D6133FF87800BC5FFC /* JavaScriptBridgeURLConnectionDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JavaScriptBridgeURLConnectionDelegate.m; path = ../JavaScriptBridge/JavaScriptBridgeURLConnectionDelegate.m; sourceTree = SOURCE_ROOT; };
 53 | /* End PBXFileReference section */
 54 | 
 55 | /* Begin PBXFrameworksBuildPhase section */
 56 | 		1D60588F0D05DD3D006BFB54 /* Frameworks */ = {
 57 | 			isa = PBXFrameworksBuildPhase;
 58 | 			buildActionMask = 2147483647;
 59 | 			files = (
 60 | 				1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
 61 | 				1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
 62 | 				2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */,
 63 | 			);
 64 | 			runOnlyForDeploymentPostprocessing = 0;
 65 | 		};
 66 | /* End PBXFrameworksBuildPhase section */
 67 | 
 68 | /* Begin PBXGroup section */
 69 | 		080E96DDFE201D6D7F000001 /* Classes */ = {
 70 | 			isa = PBXGroup;
 71 | 			children = (
 72 | 				9CDE09D5133FF87800BC5FFC /* JavaScriptBridgeURLConnectionDelegate.h */,
 73 | 				9CDE09D6133FF87800BC5FFC /* JavaScriptBridgeURLConnectionDelegate.m */,
 74 | 				9CDE08C1133DDB5800BC5FFC /* JavaScriptBridge.h */,
 75 | 				9CDE08C2133DDB5800BC5FFC /* JavaScriptBridge.m */,
 76 | 				28C286DF0D94DF7D0034E888 /* RootViewController.h */,
 77 | 				28C286E00D94DF7D0034E888 /* RootViewController.m */,
 78 | 				1D3623240D0F684500981E51 /* JSBridgeTestAppDelegate.h */,
 79 | 				1D3623250D0F684500981E51 /* JSBridgeTestAppDelegate.m */,
 80 | 				9CDE08D9133DEE1D00BC5FFC /* JavaScriptBridgeReceiver.h */,
 81 | 				9CDE08DA133DEE1D00BC5FFC /* JavaScriptBridgeReceiver.m */,
 82 | 				9CDE09A4133F4A6200BC5FFC /* NSStringAdditions.h */,
 83 | 				9CDE09A5133F4A6200BC5FFC /* NSStringAdditions.m */,
 84 | 			);
 85 | 			path = Classes;
 86 | 			sourceTree = "";
 87 | 		};
 88 | 		19C28FACFE9D520D11CA2CBB /* Products */ = {
 89 | 			isa = PBXGroup;
 90 | 			children = (
 91 | 				1D6058910D05DD3D006BFB54 /* JSBridgeTest.app */,
 92 | 			);
 93 | 			name = Products;
 94 | 			sourceTree = "";
 95 | 		};
 96 | 		29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
 97 | 			isa = PBXGroup;
 98 | 			children = (
 99 | 				080E96DDFE201D6D7F000001 /* Classes */,
100 | 				29B97315FDCFA39411CA2CEA /* Other Sources */,
101 | 				29B97317FDCFA39411CA2CEA /* Resources */,
102 | 				29B97323FDCFA39411CA2CEA /* Frameworks */,
103 | 				19C28FACFE9D520D11CA2CBB /* Products */,
104 | 			);
105 | 			name = CustomTemplate;
106 | 			sourceTree = "";
107 | 		};
108 | 		29B97315FDCFA39411CA2CEA /* Other Sources */ = {
109 | 			isa = PBXGroup;
110 | 			children = (
111 | 				28A0AAE50D9B0CCF005BE974 /* JSBridgeTest_Prefix.pch */,
112 | 				29B97316FDCFA39411CA2CEA /* main.m */,
113 | 				9C5882A813599B1C000E1184 /* Util.h */,
114 | 			);
115 | 			name = "Other Sources";
116 | 			sourceTree = "";
117 | 		};
118 | 		29B97317FDCFA39411CA2CEA /* Resources */ = {
119 | 			isa = PBXGroup;
120 | 			children = (
121 | 				9CDE08F6133DF83F00BC5FFC /* index.html */,
122 | 				9CDE08F7133DF83F00BC5FFC /* script.js */,
123 | 				9CB12DBD13432DEA001F9BA9 /* jquery-1.4.4.min.js */,
124 | 				28F335F01007B36200424DE2 /* RootViewController.xib */,
125 | 				28AD735F0D9D9599002E5188 /* MainWindow.xib */,
126 | 				8D1107310486CEB800E47090 /* JSBridgeTest-Info.plist */,
127 | 			);
128 | 			name = Resources;
129 | 			sourceTree = "";
130 | 		};
131 | 		29B97323FDCFA39411CA2CEA /* Frameworks */ = {
132 | 			isa = PBXGroup;
133 | 			children = (
134 | 				1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
135 | 				1D30AB110D05D00D00671497 /* Foundation.framework */,
136 | 				2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */,
137 | 			);
138 | 			name = Frameworks;
139 | 			sourceTree = "";
140 | 		};
141 | /* End PBXGroup section */
142 | 
143 | /* Begin PBXNativeTarget section */
144 | 		1D6058900D05DD3D006BFB54 /* JSBridgeTest */ = {
145 | 			isa = PBXNativeTarget;
146 | 			buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "JSBridgeTest" */;
147 | 			buildPhases = (
148 | 				1D60588D0D05DD3D006BFB54 /* Resources */,
149 | 				1D60588E0D05DD3D006BFB54 /* Sources */,
150 | 				1D60588F0D05DD3D006BFB54 /* Frameworks */,
151 | 			);
152 | 			buildRules = (
153 | 			);
154 | 			dependencies = (
155 | 			);
156 | 			name = JSBridgeTest;
157 | 			productName = JSBridgeTest;
158 | 			productReference = 1D6058910D05DD3D006BFB54 /* JSBridgeTest.app */;
159 | 			productType = "com.apple.product-type.application";
160 | 		};
161 | /* End PBXNativeTarget section */
162 | 
163 | /* Begin PBXProject section */
164 | 		29B97313FDCFA39411CA2CEA /* Project object */ = {
165 | 			isa = PBXProject;
166 | 			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "JSBridgeTest" */;
167 | 			compatibilityVersion = "Xcode 3.1";
168 | 			developmentRegion = English;
169 | 			hasScannedForEncodings = 1;
170 | 			knownRegions = (
171 | 				English,
172 | 				Japanese,
173 | 				French,
174 | 				German,
175 | 				en,
176 | 			);
177 | 			mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
178 | 			projectDirPath = "";
179 | 			projectRoot = "";
180 | 			targets = (
181 | 				1D6058900D05DD3D006BFB54 /* JSBridgeTest */,
182 | 			);
183 | 		};
184 | /* End PBXProject section */
185 | 
186 | /* Begin PBXResourcesBuildPhase section */
187 | 		1D60588D0D05DD3D006BFB54 /* Resources */ = {
188 | 			isa = PBXResourcesBuildPhase;
189 | 			buildActionMask = 2147483647;
190 | 			files = (
191 | 				9CB12DBF13432DF3001F9BA9 /* jquery-1.4.4.min.js in Resources */,
192 | 				9CDE08F8133DF83F00BC5FFC /* index.html in Resources */,
193 | 				9CDE08FA133DF85500BC5FFC /* script.js in Resources */,
194 | 				28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */,
195 | 				28F335F11007B36200424DE2 /* RootViewController.xib in Resources */,
196 | 			);
197 | 			runOnlyForDeploymentPostprocessing = 0;
198 | 		};
199 | /* End PBXResourcesBuildPhase section */
200 | 
201 | /* Begin PBXSourcesBuildPhase section */
202 | 		1D60588E0D05DD3D006BFB54 /* Sources */ = {
203 | 			isa = PBXSourcesBuildPhase;
204 | 			buildActionMask = 2147483647;
205 | 			files = (
206 | 				1D60589B0D05DD56006BFB54 /* main.m in Sources */,
207 | 				1D3623260D0F684500981E51 /* JSBridgeTestAppDelegate.m in Sources */,
208 | 				28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */,
209 | 				9CDE08C3133DDB5800BC5FFC /* JavaScriptBridge.m in Sources */,
210 | 				9CDE08DB133DEE1D00BC5FFC /* JavaScriptBridgeReceiver.m in Sources */,
211 | 				9CDE09A6133F4A6200BC5FFC /* NSStringAdditions.m in Sources */,
212 | 				9CDE09D7133FF87800BC5FFC /* JavaScriptBridgeURLConnectionDelegate.m in Sources */,
213 | 			);
214 | 			runOnlyForDeploymentPostprocessing = 0;
215 | 		};
216 | /* End PBXSourcesBuildPhase section */
217 | 
218 | /* Begin XCBuildConfiguration section */
219 | 		1D6058940D05DD3E006BFB54 /* Debug */ = {
220 | 			isa = XCBuildConfiguration;
221 | 			buildSettings = {
222 | 				ALWAYS_SEARCH_USER_PATHS = NO;
223 | 				COPY_PHASE_STRIP = NO;
224 | 				GCC_DYNAMIC_NO_PIC = NO;
225 | 				GCC_OPTIMIZATION_LEVEL = 0;
226 | 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
227 | 				GCC_PREFIX_HEADER = JSBridgeTest_Prefix.pch;
228 | 				INFOPLIST_FILE = "JSBridgeTest-Info.plist";
229 | 				PRODUCT_NAME = JSBridgeTest;
230 | 			};
231 | 			name = Debug;
232 | 		};
233 | 		1D6058950D05DD3E006BFB54 /* Release */ = {
234 | 			isa = XCBuildConfiguration;
235 | 			buildSettings = {
236 | 				ALWAYS_SEARCH_USER_PATHS = NO;
237 | 				COPY_PHASE_STRIP = YES;
238 | 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
239 | 				GCC_PREFIX_HEADER = JSBridgeTest_Prefix.pch;
240 | 				INFOPLIST_FILE = "JSBridgeTest-Info.plist";
241 | 				PRODUCT_NAME = JSBridgeTest;
242 | 				VALIDATE_PRODUCT = YES;
243 | 			};
244 | 			name = Release;
245 | 		};
246 | 		C01FCF4F08A954540054247B /* Debug */ = {
247 | 			isa = XCBuildConfiguration;
248 | 			buildSettings = {
249 | 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
250 | 				CODE_SIGN_IDENTITY = "iPhone Developer: Toru Hisai (2LA63FS7DX)";
251 | 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Toru Hisai (2LA63FS7DX)";
252 | 				GCC_C_LANGUAGE_STANDARD = c99;
253 | 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
254 | 				GCC_WARN_UNUSED_VARIABLE = YES;
255 | 				PREBINDING = NO;
256 | 				PROVISIONING_PROFILE = "51C8F8EF-1AA1-4493-9906-C985757C8B41";
257 | 				"PROVISIONING_PROFILE[sdk=iphoneos*]" = "51C8F8EF-1AA1-4493-9906-C985757C8B41";
258 | 				SDKROOT = iphoneos;
259 | 			};
260 | 			name = Debug;
261 | 		};
262 | 		C01FCF5008A954540054247B /* Release */ = {
263 | 			isa = XCBuildConfiguration;
264 | 			buildSettings = {
265 | 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
266 | 				CODE_SIGN_IDENTITY = "iPhone Developer: Toru Hisai (2LA63FS7DX)";
267 | 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Toru Hisai (2LA63FS7DX)";
268 | 				GCC_C_LANGUAGE_STANDARD = c99;
269 | 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
270 | 				GCC_WARN_UNUSED_VARIABLE = YES;
271 | 				OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
272 | 				PREBINDING = NO;
273 | 				PROVISIONING_PROFILE = "51C8F8EF-1AA1-4493-9906-C985757C8B41";
274 | 				"PROVISIONING_PROFILE[sdk=iphoneos*]" = "51C8F8EF-1AA1-4493-9906-C985757C8B41";
275 | 				SDKROOT = iphoneos;
276 | 			};
277 | 			name = Release;
278 | 		};
279 | /* End XCBuildConfiguration section */
280 | 
281 | /* Begin XCConfigurationList section */
282 | 		1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "JSBridgeTest" */ = {
283 | 			isa = XCConfigurationList;
284 | 			buildConfigurations = (
285 | 				1D6058940D05DD3E006BFB54 /* Debug */,
286 | 				1D6058950D05DD3E006BFB54 /* Release */,
287 | 			);
288 | 			defaultConfigurationIsVisible = 0;
289 | 			defaultConfigurationName = Release;
290 | 		};
291 | 		C01FCF4E08A954540054247B /* Build configuration list for PBXProject "JSBridgeTest" */ = {
292 | 			isa = XCConfigurationList;
293 | 			buildConfigurations = (
294 | 				C01FCF4F08A954540054247B /* Debug */,
295 | 				C01FCF5008A954540054247B /* Release */,
296 | 			);
297 | 			defaultConfigurationIsVisible = 0;
298 | 			defaultConfigurationName = Release;
299 | 		};
300 | /* End XCConfigurationList section */
301 | 	};
302 | 	rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
303 | }
304 | 


--------------------------------------------------------------------------------
/JSBridgeTest/RootViewController.xib:
--------------------------------------------------------------------------------
  1 | 
  2 | 
  3 | 	
  4 | 		784
  5 | 		10D541
  6 | 		760
  7 | 		1038.29
  8 | 		460.00
  9 | 		
 10 | 			com.apple.InterfaceBuilder.IBCocoaTouchPlugin
 11 | 			81
 12 | 		
 13 | 		
 14 | 			YES
 15 | 			
 16 | 		
 17 | 		
 18 | 			YES
 19 | 			com.apple.InterfaceBuilder.IBCocoaTouchPlugin
 20 | 		
 21 | 		
 22 | 			YES
 23 | 			
 24 | 				YES
 25 | 			
 26 | 			
 27 | 				YES
 28 | 			
 29 | 		
 30 | 		
 31 | 			YES
 32 | 			
 33 | 				IBFilesOwner
 34 | 				IBCocoaTouchFramework
 35 | 			
 36 | 			
 37 | 				IBFirstResponder
 38 | 				IBCocoaTouchFramework
 39 | 			
 40 | 			
 41 | 				
 42 | 				274
 43 | 				{320, 247}
 44 | 				
 45 | 				
 46 | 					3
 47 | 					MQA
 48 | 				
 49 | 				NO
 50 | 				YES
 51 | 				NO
 52 | 				IBCocoaTouchFramework
 53 | 				NO
 54 | 				1
 55 | 				0
 56 | 				YES
 57 | 				44
 58 | 				22
 59 | 				22
 60 | 			
 61 | 		
 62 | 		
 63 | 			
 64 | 				YES
 65 | 				
 66 | 					
 67 | 						view
 68 | 						
 69 | 						
 70 | 					
 71 | 					3
 72 | 				
 73 | 				
 74 | 					
 75 | 						dataSource
 76 | 						
 77 | 						
 78 | 					
 79 | 					4
 80 | 				
 81 | 				
 82 | 					
 83 | 						delegate
 84 | 						
 85 | 						
 86 | 					
 87 | 					5
 88 | 				
 89 | 			
 90 | 			
 91 | 				
 92 | 					YES
 93 | 					
 94 | 						0
 95 | 						
 96 | 						
 97 | 						
 98 | 					
 99 | 					
100 | 						-1
101 | 						
102 | 						
103 | 						File's Owner
104 | 					
105 | 					
106 | 						-2
107 | 						
108 | 						
109 | 					
110 | 					
111 | 						2
112 | 						
113 | 						
114 | 					
115 | 				
116 | 			
117 | 			
118 | 				YES
119 | 				
120 | 					YES
121 | 					-1.CustomClassName
122 | 					-2.CustomClassName
123 | 					2.IBEditorWindowLastContentRect
124 | 					2.IBPluginDependency
125 | 				
126 | 				
127 | 					YES
128 | 					RootViewController
129 | 					UIResponder
130 | 					{{144, 609}, {320, 247}}
131 | 					com.apple.InterfaceBuilder.IBCocoaTouchPlugin
132 | 				
133 | 			
134 | 			
135 | 				YES
136 | 				
137 | 				
138 | 					YES
139 | 				
140 | 			
141 | 			
142 | 			
143 | 				YES
144 | 				
145 | 				
146 | 					YES
147 | 				
148 | 			
149 | 			
150 | 			5
151 | 		
152 | 		
153 | 			
154 | 				YES
155 | 				
156 | 					RootViewController
157 | 					UITableViewController
158 | 					
159 | 						IBProjectSource
160 | 						Classes/RootViewController.h
161 | 					
162 | 				
163 | 			
164 | 			
165 | 				YES
166 | 				
167 | 					NSObject
168 | 					
169 | 						IBFrameworkSource
170 | 						Foundation.framework/Headers/NSError.h
171 | 					
172 | 				
173 | 				
174 | 					NSObject
175 | 					
176 | 						IBFrameworkSource
177 | 						Foundation.framework/Headers/NSFileManager.h
178 | 					
179 | 				
180 | 				
181 | 					NSObject
182 | 					
183 | 						IBFrameworkSource
184 | 						Foundation.framework/Headers/NSKeyValueCoding.h
185 | 					
186 | 				
187 | 				
188 | 					NSObject
189 | 					
190 | 						IBFrameworkSource
191 | 						Foundation.framework/Headers/NSKeyValueObserving.h
192 | 					
193 | 				
194 | 				
195 | 					NSObject
196 | 					
197 | 						IBFrameworkSource
198 | 						Foundation.framework/Headers/NSKeyedArchiver.h
199 | 					
200 | 				
201 | 				
202 | 					NSObject
203 | 					
204 | 						IBFrameworkSource
205 | 						Foundation.framework/Headers/NSNetServices.h
206 | 					
207 | 				
208 | 				
209 | 					NSObject
210 | 					
211 | 						IBFrameworkSource
212 | 						Foundation.framework/Headers/NSObject.h
213 | 					
214 | 				
215 | 				
216 | 					NSObject
217 | 					
218 | 						IBFrameworkSource
219 | 						Foundation.framework/Headers/NSPort.h
220 | 					
221 | 				
222 | 				
223 | 					NSObject
224 | 					
225 | 						IBFrameworkSource
226 | 						Foundation.framework/Headers/NSRunLoop.h
227 | 					
228 | 				
229 | 				
230 | 					NSObject
231 | 					
232 | 						IBFrameworkSource
233 | 						Foundation.framework/Headers/NSStream.h
234 | 					
235 | 				
236 | 				
237 | 					NSObject
238 | 					
239 | 						IBFrameworkSource
240 | 						Foundation.framework/Headers/NSThread.h
241 | 					
242 | 				
243 | 				
244 | 					NSObject
245 | 					
246 | 						IBFrameworkSource
247 | 						Foundation.framework/Headers/NSURL.h
248 | 					
249 | 				
250 | 				
251 | 					NSObject
252 | 					
253 | 						IBFrameworkSource
254 | 						Foundation.framework/Headers/NSURLConnection.h
255 | 					
256 | 				
257 | 				
258 | 					NSObject
259 | 					
260 | 						IBFrameworkSource
261 | 						Foundation.framework/Headers/NSXMLParser.h
262 | 					
263 | 				
264 | 				
265 | 					NSObject
266 | 					
267 | 						IBFrameworkSource
268 | 						UIKit.framework/Headers/UIAccessibility.h
269 | 					
270 | 				
271 | 				
272 | 					NSObject
273 | 					
274 | 						IBFrameworkSource
275 | 						UIKit.framework/Headers/UINibLoading.h
276 | 					
277 | 				
278 | 				
279 | 					NSObject
280 | 					
281 | 						IBFrameworkSource
282 | 						UIKit.framework/Headers/UIResponder.h
283 | 					
284 | 				
285 | 				
286 | 					UIResponder
287 | 					NSObject
288 | 					
289 | 				
290 | 				
291 | 					UIScrollView
292 | 					UIView
293 | 					
294 | 						IBFrameworkSource
295 | 						UIKit.framework/Headers/UIScrollView.h
296 | 					
297 | 				
298 | 				
299 | 					UISearchBar
300 | 					UIView
301 | 					
302 | 						IBFrameworkSource
303 | 						UIKit.framework/Headers/UISearchBar.h
304 | 					
305 | 				
306 | 				
307 | 					UISearchDisplayController
308 | 					NSObject
309 | 					
310 | 						IBFrameworkSource
311 | 						UIKit.framework/Headers/UISearchDisplayController.h
312 | 					
313 | 				
314 | 				
315 | 					UITableView
316 | 					UIScrollView
317 | 					
318 | 						IBFrameworkSource
319 | 						UIKit.framework/Headers/UITableView.h
320 | 					
321 | 				
322 | 				
323 | 					UITableViewController
324 | 					UIViewController
325 | 					
326 | 						IBFrameworkSource
327 | 						UIKit.framework/Headers/UITableViewController.h
328 | 					
329 | 				
330 | 				
331 | 					UIView
332 | 					
333 | 						IBFrameworkSource
334 | 						UIKit.framework/Headers/UITextField.h
335 | 					
336 | 				
337 | 				
338 | 					UIView
339 | 					UIResponder
340 | 					
341 | 						IBFrameworkSource
342 | 						UIKit.framework/Headers/UIView.h
343 | 					
344 | 				
345 | 				
346 | 					UIViewController
347 | 					
348 | 						IBFrameworkSource
349 | 						UIKit.framework/Headers/UINavigationController.h
350 | 					
351 | 				
352 | 				
353 | 					UIViewController
354 | 					
355 | 						IBFrameworkSource
356 | 						UIKit.framework/Headers/UITabBarController.h
357 | 					
358 | 				
359 | 				
360 | 					UIViewController
361 | 					UIResponder
362 | 					
363 | 						IBFrameworkSource
364 | 						UIKit.framework/Headers/UIViewController.h
365 | 					
366 | 				
367 | 			
368 | 		
369 | 		0
370 | 		IBCocoaTouchFramework
371 | 		
372 | 			com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS
373 | 			
374 | 		
375 | 		
376 | 			com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3
377 | 			
378 | 		
379 | 		YES
380 | 		JSBridgeTest.xcodeproj
381 | 		3
382 | 		81
383 | 	
384 | 
385 | 


--------------------------------------------------------------------------------
/JSBridgeTest/html/script.js:
--------------------------------------------------------------------------------
  1 | var connectionDelegate = {}
  2 | 
  3 | function __hex (hexdata) {
  4 |     var data = hexdata.replace (/([a-f0-9]){2}/ig, function (x) {
  5 |         return String.fromCharCode (parseInt (x, 16))
  6 |     })
  7 | 
  8 |     return data
  9 | }
 10 | 
 11 | // event must be one of following: fail, recv, response, sent, finish
 12 | function add_connection_handler (connid, event, func) {
 13 |     if (! connectionDelegate[connid])
 14 |         connectionDelegate[connid] = {}
 15 |     connectionDelegate[connid][event] = func
 16 | }
 17 | 
 18 | function connectionDidFailWithError (connid, err) {
 19 |     var hndl = connectionDelegate[connid]
 20 |     if (hndl && hndl.fail) {
 21 |         hndl.fail (connid, err)
 22 |     } else {
 23 |         $("pre").append ("\nconnectionDidFailWithError: " + connid + ": " + err)
 24 |     }
 25 | }
 26 | 
 27 | function connectionDidReceiveData (connid, data) {
 28 |     var hndl = connectionDelegate[connid]
 29 |     if (hndl && hndl.recv) {
 30 |         hndl.recv (connid, data)
 31 |     } else {
 32 |         $("pre").append ("\nconnectionDidReceiveData: " + connid + ": " + data)
 33 |     }
 34 | }
 35 | 
 36 | function connectionDidReceiveResponse (connid) {
 37 |     var hndl = connectionDelegate[connid]
 38 |     if (hndl && hndl.response) {
 39 |         hndl.response (connid)
 40 |     } else {
 41 |         $("pre").append ("\nconnectionDidReceiveResponse: " + connid)
 42 |     }
 43 | }
 44 | 
 45 | function connectionDidSendBodyData (connid) {
 46 |     var hndl = connectionDelegate[connid]
 47 |     if (hndl && hndl.sent) {
 48 |         hndl.sent (connid)
 49 |     } else {
 50 |         $("pre").append ("\nconnectionDidSendBodyData: " + connid)
 51 |     }
 52 | }
 53 | 
 54 | function connectionDidFinishLoading (connid) {
 55 |     var hndl = connectionDelegate[connid]
 56 |     if (hndl && hndl.finish) {
 57 |         hndl.finish (connid)
 58 |     } else {
 59 |         $("pre").append ("\nconnectionDidFinishLoading: " + connid)
 60 |     }
 61 | }
 62 | 
 63 | ////////////////////
 64 | 
 65 | function create_stack () {
 66 |     return []
 67 | }
 68 | 
 69 | function stack_push_raw_string (st, val) {
 70 |     st.push ("-" + val)
 71 | }
 72 | 
 73 | function stack_push_operator (st, op) {
 74 |     st.push ("@" + op)
 75 | }
 76 | 
 77 | function hexify (str) {
 78 |     var hex = ""
 79 |     for (var i = 0; i < str.length; i ++) {
 80 |         hex += str.charCodeAt (i).toString (16)
 81 |     }
 82 | 
 83 |     return hex
 84 | }
 85 | 
 86 | function stack_push_string (st, op) {
 87 |     if (typeof (op) != "string")
 88 |         op = op.toString ()
 89 | 
 90 |     if (op.match (/^[a-zA-Z0-9!@#$%^&*()_+{}|\[\]\:";'<>?,]*$/)) {
 91 |         stack_push_raw_string (st, op)
 92 |     } else {
 93 |         stack_push_raw_string (st, hexify (op))
 94 |         stack_push_operator (st, "hexstr")
 95 |         stack_push_operator (st, "str")
 96 |     }
 97 | }
 98 | 
 99 | function stack_push_data (st, op) {
100 |     if (typeof (op) != "string")
101 |         op = op.toString ()
102 | 
103 |     stack_push_raw_string (st, hexify (op))
104 |     stack_push_operator (st, "hexstr")
105 | }
106 | 
107 | function stack_execute (st) {
108 |     var uri = "bridge:///" + st.join ("/")
109 | 
110 |     setTimeout (function () {
111 |         location.href = uri
112 |     }, 100)
113 | }
114 | 
115 | JSBridgeStack = function () {
116 |     this.stack = create_stack ()
117 | }
118 | 
119 | JSBridgeStack.prototype.push = function () {
120 |     for (var i = 0; i < arguments.length; i ++) {
121 |         stack_push_string (this.stack, arguments[i])
122 |     }
123 |     return this
124 | }
125 | 
126 | JSBridgeStack.prototype.pushdata = function () {
127 |     for (var i = 0; i < arguments.length; i ++) {
128 |         stack_push_data (this.stack, arguments[i])
129 |     }
130 |     return this
131 | }
132 | 
133 | JSBridgeStack.prototype.operate = function (op) {
134 |     stack_push_operator (this.stack, op)
135 |     return this
136 | }
137 | 
138 | JSBridgeStack.prototype.pushcallback = function (name, numargs) {
139 |     return this.push (name, numargs).operate ("callback")
140 | }
141 | 
142 | JSBridgeStack.prototype.execute = function () {
143 |     stack_execute (this.stack)
144 | }
145 | 
146 | ///////////////////
147 | 
148 | function escape_utf8 (str) {
149 |     return encodeURIComponent (str)
150 | }
151 | 
152 | function oauth_make_signature_base (url, method, params, request_body) {
153 |     var params_sorted = []
154 |     for (var i in params) {
155 |         params_sorted.push ([i, params[i]])
156 |     }
157 |     params_sorted.sort (function (a, b) {return a > b ? 1 : -1})
158 | 
159 |     console.debug (params_sorted)
160 | 
161 |     var body = $.map (params_sorted, function (a) {
162 |         return a[0] + "=" + escape_utf8 (a[1])
163 |     }).join ("&")
164 | 
165 |     if (request_body)
166 |         body += "&" + request_body
167 | 
168 |     var base = $.map ([method, url, body], escape_utf8).join ("&")
169 | 
170 |     return base
171 | }
172 | 
173 | CALLBACK = []
174 | var GLOBAL = this
175 | function make_callback (func) {
176 |     CALLBACK.push (func)
177 |     var name = "CALLBACK_" + (CALLBACK.length - 1).toString ()
178 |     GLOBAL[name] = function () {
179 |         try {
180 |             return func.apply (this, arguments)
181 |         } catch (err) {
182 |             alert (err)
183 |         }
184 |     }
185 |     return name
186 | }
187 | 
188 | function test_twitter_oauth () {
189 |     var consumer_secret = "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98"
190 |     var url = "https://api.twitter.com/oauth/request_token"
191 |     var method = "POST"
192 |     var params = {
193 |         oauth_callback: "http://localhost:3005/the_dance/process_callback?service_provider_id=11",
194 |         oauth_consumer_key: "GDdmIQH6jhtmLUypg82g",
195 |         oauth_nonce: "QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk",
196 |         oauth_signature_method: "HMAC-SHA1",
197 |         oauth_timestamp: "1272323042",
198 |         oauth_version: "1.0"
199 |     }
200 | 
201 |     var base = oauth_make_signature_base (url, method, params)
202 |     console.assert (base == "POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_callback%3Dhttp%253A%252F%252Flocalhost%253A3005%252Fthe_dance%252Fprocess_callback%253Fservice_provider_id%253D11%26oauth_consumer_key%3DGDdmIQH6jhtmLUypg82g%26oauth_nonce%3DQP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1272323042%26oauth_version%3D1.0")
203 | 
204 |         // console.assert (sig == "8wUi7m5HFQy76nowoCThusfgB+Q=")
205 | 
206 | }
207 | 
208 | function disassemble_response (res) {
209 |     var dest = {}
210 |     var arr = res.split ("&")
211 |     for (var i in arr) {
212 |         var namevalue = arr[i].split ("=", 2)
213 |         dest[namevalue[0]] = namevalue[1]
214 |     }
215 | 
216 |     return dest
217 | }
218 | 
219 | function http_get (url, header, cont) {
220 |     var cb2 = make_callback (function (connhandle, connid) {
221 |         var res = ""
222 | 
223 |         add_connection_handler (connid, "recv", function (connid, data) {
224 |             res += data.toString ()
225 |         })
226 | 
227 |         add_connection_handler (connid, "finish", function (connid) {
228 |             if (cont)
229 |                 cont (res)
230 |         })
231 | 
232 |         new JSBridgeStack ().push (connhandle).operate ("http_send").execute ()
233 |     })
234 | 
235 |     var jsb = new JSBridgeStack ()
236 |     var n = 0
237 |     for (var f in header) {
238 |         jsb.push (header[f], f)
239 |         n ++
240 |     }
241 |     jsb.push (n, url).operate ("http_get").pushcallback (cb2, 2).execute ()
242 | }
243 | 
244 | function http_post (url, header, body, cont) {
245 |     var cb2 = make_callback (function (connhandle, connid) {
246 |         var res = ""
247 | 
248 |         add_connection_handler (connid, "recv", function (connid, data) {
249 |             res += data.toString ()
250 |         })
251 | 
252 |         add_connection_handler (connid, "finish", function (connid) {
253 |             if (cont)
254 |                 cont (res)
255 |         })
256 | 
257 |         new JSBridgeStack ().push (connhandle).operate ("http_send").execute ()
258 |     })
259 | 
260 |     var jsb = new JSBridgeStack ()
261 |     jsb.pushdata (body)
262 |     var n = 0
263 |     for (var f in header) {
264 |         jsb.push (header[f], f)
265 |         n ++
266 |     }
267 |     jsb.push (n, url).operate ("http_post").pushcallback (cb2, 2).execute ()
268 | }
269 | 
270 | function make_oauth_header (params, sig) {
271 |     var x = []
272 |     for (var name in params) {
273 |         var value = params[name]
274 |         x.push (name + "=\"" + escape_utf8 (value) + "\"")
275 |     }
276 |     x.push ("oauth_signature" + "=\"" + escape_utf8 (sig) + "\"")
277 |     var auth = "OAuth " + x.join (", ")
278 | 
279 |     return auth
280 | }
281 | 
282 | function tweet (consumer_key, consumer_secret, oauth_token, oauth_token_secret, text, cont) {
283 |     var params = {
284 |         oauth_consumer_key: consumer_key,
285 |         oauth_nonce: "tweet" + Date.now (),
286 |         oauth_signature_method: "HMAC-SHA1",
287 |         oauth_token: oauth_token,
288 |         oauth_timestamp: Math.floor (Date.now () / 1000).toString (),
289 |         oauth_version: "1.0"
290 |     }
291 | 
292 |     var url = "http://api.twitter.com/1/statuses/update.json"
293 |     var method = "POST"
294 |     var body = "status=" + escape_utf8 (text)
295 |     var base = oauth_make_signature_base (url, method, params, body)
296 | 
297 |     new JSBridgeStack ().push (base).push(consumer_secret + "&" + oauth_token_secret).operate ("hmac_sha1").operate ("base64data").pushcallback (
298 |         make_callback (function (sig) {
299 |             var auth = make_oauth_header (params, sig)
300 | 
301 |             http_post (url, {Authorization: auth}, body, function (res) {
302 |                 var data = eval ("(" + res + ")")
303 | 
304 |                 if (cont)
305 |                     cont (data)
306 |             })
307 |         }), 1).execute ()
308 | }
309 | 
310 | function oauth_request_token_params (consumer_key, oauth_cb) {
311 |     var params = {
312 |         oauth_callback: "bridge-callback://" + oauth_cb + "/",
313 |         oauth_consumer_key: consumer_key,
314 |         oauth_nonce: "hoge" + Date.now (),
315 |         oauth_signature_method: "HMAC-SHA1",
316 |         oauth_timestamp: Math.floor (Date.now () / 1000).toString (),
317 |         oauth_version: "1.0"
318 |     }
319 | 
320 |     return params
321 | }
322 | 
323 | function oauth_access_token_params (consumer_key, oauth_token, oauth_verifier) {
324 |     var params = {
325 |         oauth_consumer_key: consumer_key,
326 |         oauth_nonce: "hoge2" + Date.now (),
327 |         oauth_signature_method: "HMAC-SHA1",
328 |         oauth_token: oauth_token,
329 |         oauth_timestamp: Math.floor (Date.now () / 1000).toString (),
330 |         oauth_verifier: oauth_verifier,
331 |         oauth_version: "1.0"
332 |     }
333 | 
334 |     return params
335 | }
336 | 
337 | function oauth_access_token (consumer_key, consumer_secret, oauth_token_secret, oauth_token, oauth_verifier, cont) {
338 |     var params = oauth_access_token_params (consumer_key, oauth_token, oauth_verifier)
339 | 
340 |     var url = "https://api.twitter.com/oauth/access_token"
341 |     var method = "POST"
342 |     var base = oauth_make_signature_base (url, method, params)
343 | 
344 |     new JSBridgeStack ().push (base, consumer_secret + "&" + oauth_token_secret).operate ("hmac_sha1").operate ("base64data").pushcallback (make_callback (function (sig) {
345 |         var auth = make_oauth_header (params, sig)
346 | 
347 |         http_post (url, {Authorization: auth}, "", function (res) {
348 |             var data = disassemble_response (res)
349 | 
350 |             if (cont) {
351 |                 cont (data.oauth_token, data.oauth_token_secret)
352 |             }
353 |         })
354 | 
355 |     }), 1).execute ()
356 | }
357 | 
358 | function oauth_request_token (consumer_key, consumer_secret, cont) {
359 |     var stat = {}
360 | 
361 |     var params = oauth_request_token_params (consumer_key, cont (stat))
362 |     var url = "http://api.twitter.com/oauth/request_token"
363 |     var method = "POST"
364 |     var base = oauth_make_signature_base (url, method, params)
365 | 
366 |     new JSBridgeStack ().push (base, consumer_secret + "&").operate ("hmac_sha1").operate ("base64data").pushcallback (make_callback (function (sig) {
367 |         // $("pre").append ("\n" + "oauth_request_token: signature: " + sig)
368 | 
369 |         var auth = make_oauth_header (params, sig)
370 | 
371 |         http_post (url, {Authorization: auth}, "", function (res) {
372 |             var data = disassemble_response (res)
373 |             stat.oauth_token_secret = data.oauth_token_secret
374 | 
375 |             // new JSBridgeStack ().push (data.oauth_token_secret, data.oauth_token).operate ("store_oauth_token").pushcallback (make_callback (function () {
376 |                 new JSBridgeStack ().push ("http://api.twitter.com/oauth/authorize?oauth_token=" + data.oauth_token).operate ("open_url_in_new_browser").
377 |                     pushcallback (make_callback (function (hndl) {
378 |                         stat.browser_handle = hndl;
379 |                     }), 1).execute ()
380 |             // }), 0).execute ()
381 |         })
382 |     }), 1).execute ()
383 | }
384 | 
385 | function twitter_oauth (consumer_key, consumer_secret, cont) {
386 |     oauth_request_token (consumer_key, consumer_secret, function (stat) {
387 |         return make_callback (function (data) {
388 |             var browser_handle = stat.browser_handle
389 |             var oauth_token_secret = stat.browser_handle
390 | 
391 |             var res = __hex (data)
392 |             // $("pre").append ("\n" + "OAuth callback: " + res)
393 | 
394 |             new JSBridgeStack ().push ("OAuth callback: " + res).operate ("print").
395 |                 push (browser_handle).operate ("close_browser").
396 |                 execute ()
397 | 
398 |             var token = disassemble_response (res)
399 | 
400 |             oauth_access_token (consumer_key, consumer_secret, oauth_token_secret, token.oauth_token, token.oauth_verifier, cont)
401 |         })
402 |     })
403 | }
404 | 
405 | function home_timeline (consumer_key, consumer_secret, oauth_token, oauth_token_secret, cont) {
406 |     // $("pre").append ("\nhome_timeline: \n -" + [consumer_key, consumer_secret, oauth_token, oauth_token_secret, cont].join ("\n -"))
407 | 
408 |     var params = {
409 |         oauth_consumer_key: consumer_key,
410 |         oauth_nonce: "timeline" + Date.now (),
411 |         oauth_signature_method: "HMAC-SHA1",
412 |         oauth_token: oauth_token,
413 |         oauth_timestamp: Math.floor (Date.now () / 1000).toString (),
414 |         oauth_version: "1.0"
415 |     }
416 | 
417 |     var url = "http://api.twitter.com/1/statuses/home_timeline.json"
418 |     var method = "GET"
419 |     var base = oauth_make_signature_base (url, method, params)
420 | 
421 |     new JSBridgeStack ().push (base).push(consumer_secret + "&" + oauth_token_secret).operate ("hmac_sha1").operate ("base64data").pushcallback (
422 |         make_callback (function (sig) {
423 |             var auth = make_oauth_header (params, sig)
424 | 
425 |             http_get (url, {Authorization: auth}, function (res) {
426 |                 var data = eval ("(" + res + ")")
427 | 
428 |                 if (cont)
429 |                     cont (data)
430 |             })
431 |         }), 1).execute ()
432 | }
433 | 
434 | //////////////////////
435 | 
436 | function make_tweet_elem (t) {
437 |     var id = t.id
438 |     var text = t.text
439 |     var screen_name = t.user.screen_name
440 |     var elem = $("
").css ({margin: "0px", "max-width": "320px"}). 441 | append ($("

").css ({margin: "0px"}).text ("@" + screen_name)). 442 | append ($("

").css ({margin: "0px"}).text (text)) 443 | 444 | return elem 445 | } 446 | 447 | function test_objc (tweets) { 448 | var tweet_map = {} 449 | 450 | new JSBridgeStack (). 451 | push ("UITableViewController").operate ("look_up_class").operate ("create_instance"). 452 | push (make_callback (function (selector) { 453 | var f = ({ 454 | numberOfSectionsInTableView: function () { 455 | return 1; 456 | }, 457 | tableView_numberOfRowsInSection: function (section) { 458 | return tweets.length; 459 | }, 460 | tableView_cellForRowAtIndexPath: function (section, row) { 461 | var t = tweets[row] 462 | var elem = tweet_map[t.id] 463 | if (! elem) { 464 | elem = make_tweet_elem (t) 465 | tweet_map[t.id] = elem 466 | } 467 | var outer = $("").append ($("").css ({margin: "0px", padding: "0px"})).append (elem) 468 | return outer.html () 469 | }, 470 | tableView_heightForRowAtIndexPath: function (section, row) { 471 | var t = tweets[row] 472 | var elem = tweet_map[t.id] 473 | if (! elem) { 474 | elem = make_tweet_elem (t) 475 | tweet_map[t.id] = elem 476 | } 477 | var outer = $("

").append (elem) 478 | $("body").append (outer) 479 | var height = outer.innerHeight () 480 | outer.remove () 481 | return height 482 | } 483 | })[selector] 484 | 485 | var args = [] 486 | for (var i = 1; i < arguments.length; i ++) { 487 | args.push (arguments[i]) 488 | } 489 | var ret = f.apply (this, args) 490 | return ret 491 | })).operate ("xxx_pushtable"). 492 | // operate ("self") 493 | // operate ("send_mesg") 494 | pushcallback (make_callback (function (hndl) { 495 | $("pre").append ("\ntable view controller: " + hndl) 496 | }), 1).execute () 497 | } 498 | 499 | ////////////////////// 500 | 501 | 502 | //////////////////// 503 | 504 | $(document).ready (function () { 505 | var consumer_secret = "QBvGYz4yTwFx1tGabhbsxE3ZXmaG01h3VRjfJoph0" 506 | var consumer_key = "7IoQbg88rT3GJ01HlTOc9A" 507 | 508 | try { 509 | // test_objc ([1, 2, 3]) 510 | // throw ("done") 511 | 512 | new JSBridgeStack ().operate ("twitter_credential").pushcallback (make_callback (function (oauth_token, oauth_token_secret) { 513 | if (oauth_token && oauth_token.length > 0 && oauth_token_secret && oauth_token_secret.length > 0) { 514 | // tweet (consumer_key, consumer_secret, oauth_token, oauth_token_secret, "てすと。 " + Date.now (), function (res) { 515 | // $("pre").append ("\nTweet: " + res.id + " " + res) 516 | // }) 517 | 518 | home_timeline (consumer_key, consumer_secret, oauth_token, oauth_token_secret, function (data) { 519 | test_objc (data) 520 | // new JSBridgeStack ().push (data.toString ()).operate ("print").execute () 521 | }) 522 | } else { 523 | twitter_oauth (consumer_key, consumer_secret, function (oauth_token, oauth_token_secret) { 524 | new JSBridgeStack ().push (oauth_token_secret, oauth_token).operate ("store_twitter_credential").execute () 525 | tweet (consumer_key, consumer_secret, oauth_token, oauth_token_secret, "setting up my twitter 私のさえずりを設定する " + Date.now (), function (res) { 526 | $("pre").append ("\nTweet: " + res.id + " " + res) 527 | }) 528 | }) 529 | } 530 | }), 2).execute () 531 | } catch (err) { 532 | alert (err) 533 | } 534 | }) 535 | -------------------------------------------------------------------------------- /JavaScriptBridge/JavaScriptBridge.m: -------------------------------------------------------------------------------- 1 | // 2 | // JavaScriptBridge.m 3 | // Untitled 4 | // 5 | // Created by Toru Hisai on 3/25/11. 6 | // Copyright 2011 Avatar Reality Inc. All rights reserved. 7 | // 8 | 9 | #import "Util.h" 10 | #import "JavaScriptBridge.h" 11 | #import "NSStringAdditions.h" 12 | #import "JavaScriptBridgeURLConnectionDelegate.h" 13 | 14 | #include 15 | #include 16 | 17 | @implementation JavaScriptBridge 18 | 19 | @synthesize stack, webView, viewController; 20 | 21 | - (id)init { 22 | [super init]; 23 | [self setStack:[[NSMutableArray alloc] init]]; 24 | DebugLog(@"init: %@", self); 25 | return self; 26 | } 27 | 28 | - (void)push:(NSString*)operand { 29 | [[self stack] addObject:operand]; 30 | DebugLog(@"pushed: %@, [%d]", operand, [self stackDepth]); 31 | } 32 | 33 | - (id)pop { 34 | id obj = [[[[self stack] lastObject] retain] autorelease]; 35 | [[self stack] removeLastObject]; 36 | 37 | return obj; 38 | } 39 | 40 | - (int)stackDepth { 41 | return [[self stack] count]; 42 | } 43 | 44 | - (void)operate:(NSString*)op { 45 | DebugLog(@"--> [%d]", [self stackDepth]); 46 | NSString *func = [NSString stringWithFormat:@"op_%@", op]; 47 | char buf[128]; 48 | [func getCString:buf maxLength:sizeof(buf) encoding:NSUTF8StringEncoding]; 49 | SEL sel = sel_getUid(buf); 50 | if ([self respondsToSelector:sel]) { 51 | objc_msgSend(self, sel); 52 | } else { 53 | DebugLog(@"unknown operator: %@", op); 54 | } 55 | DebugLog(@"--> [%d]", [self stackDepth]); 56 | } 57 | 58 | - (void)error:(NSString*)mesg { 59 | DebugLog(@"JavaScript bridge error: %@", mesg); 60 | } 61 | 62 | #define CHECK_STACK_DEPTH_WITH_FAIL(n, fail) \ 63 | do {\ 64 | const char *name = sel_getName(_cmd);\ 65 | DebugLog(@"method = %s", name);\ 66 | if ([self stackDepth] < (n)) {\ 67 | [self error:[NSString stringWithFormat:@"%s: stack underflow", name]];\ 68 | return fail;\ 69 | }\ 70 | } while (0) 71 | 72 | #define CHECK_STACK_DEPTH(n) CHECK_STACK_DEPTH_WITH_FAIL(n,) 73 | 74 | - (void)op_call { 75 | } 76 | 77 | // string -> number 78 | - (void)op_num { 79 | CHECK_STACK_DEPTH(1); 80 | 81 | NSString *str = [self pop]; 82 | [self push:[NSNumber numberWithDouble:[str doubleValue]]]; 83 | } 84 | 85 | // string -> integer 86 | - (void)op_int { 87 | CHECK_STACK_DEPTH(1); 88 | 89 | NSString *str = [self pop]; 90 | [self push:[NSNumber numberWithInteger:[str integerValue]]]; 91 | } 92 | 93 | // data -> str 94 | - (void)op_str { 95 | CHECK_STACK_DEPTH(1); 96 | 97 | NSData *dat = [self pop]; 98 | NSString *str = [[[NSString alloc] initWithData:dat encoding:NSUTF8StringEncoding] retain]; 99 | [self push:str]; 100 | [str release]; 101 | } 102 | 103 | // a:number/string, b:number/string -> a+b:number 104 | - (void)op_add { 105 | CHECK_STACK_DEPTH(2); 106 | 107 | NSNumber *n1 = [self pop]; 108 | NSNumber *n2 = [self pop]; 109 | [self push:[NSNumber numberWithDouble:[n1 doubleValue] + [n2 doubleValue]]]; 110 | } 111 | 112 | // any -> (none) 113 | - (void)op_print { 114 | CHECK_STACK_DEPTH(1); 115 | 116 | DebugLog(@"print: %@", [NSString stringWithFormat:@"%@", [self pop]]); 117 | } 118 | 119 | // src:string -> data 120 | - (void)op_hexstr { 121 | CHECK_STACK_DEPTH(1); 122 | 123 | NSString *str = [self pop]; 124 | 125 | NSUInteger len = [str lengthOfBytesUsingEncoding:NSASCIIStringEncoding]; 126 | NSMutableData *data = [[NSMutableData alloc] init]; 127 | 128 | if (len % 2 > 0) { 129 | [self error:@"odd number of character"]; 130 | } else { 131 | int p = 0; 132 | while (p < len) { 133 | NSScanner *scan = [NSScanner scannerWithString:[str substringWithRange:NSMakeRange(p, 2)]]; 134 | unsigned int val = 0; 135 | [scan scanHexInt:&val]; 136 | p += 2; 137 | unsigned char chr = val; 138 | [data appendBytes:&chr length:1]; 139 | } 140 | } 141 | 142 | DebugLog(@"hexstr: %@", data); 143 | [self push:data]; 144 | [data release]; 145 | } 146 | 147 | // numargs:int/string, funcname:string, arg:string[, ...] -> (none) 148 | - (void)op_callback { 149 | CHECK_STACK_DEPTH(2); 150 | 151 | NSNumber *num = [self pop]; 152 | NSString *funcname = [self pop]; 153 | 154 | NSInteger n = [num integerValue]; 155 | 156 | DebugLog(@"callback: [%d] num: %@, %d, func: %@", [self stackDepth], num, n, funcname); 157 | 158 | CHECK_STACK_DEPTH(n); 159 | 160 | NSMutableArray *args = [[NSMutableArray alloc] init]; 161 | 162 | for (int i = 0; i < n; i ++) { 163 | NSString *arg = [self pop]; 164 | if (!arg) { 165 | arg = @""; 166 | } 167 | // arg must be a *safe* string, which doesn't contain any control charactor nor ", \, etc... 168 | [args addObject:arg]; 169 | } 170 | 171 | NSString *arglist = n > 0 ? [NSString stringWithFormat:@"\"%@\"", [args componentsJoinedByString:@"\",\""]] : @""; 172 | NSString *expr = [NSString stringWithFormat:@"%@(%@)", funcname, arglist]; 173 | DebugLog(@"callback: %@", expr); 174 | [self performSelector:@selector(eval:) withObject:expr afterDelay:0]; 175 | [args release]; 176 | } 177 | 178 | - (void)eval:(NSString*)expr { 179 | DebugLog(@"eval: %@ -> webView: %@", expr, [self webView]); 180 | [[self webView] stringByEvaluatingJavaScriptFromString:expr]; 181 | } 182 | 183 | // data -> hexstr:string 184 | - (void)op_hexifydata { 185 | CHECK_STACK_DEPTH(1); 186 | 187 | NSData *dat = [self pop]; 188 | 189 | NSMutableString *str = [[NSMutableString alloc] init]; 190 | const unsigned char *bytes = [dat bytes]; 191 | NSUInteger len = [dat length]; 192 | 193 | for (NSUInteger i = 0; i < len; i ++) { 194 | unsigned char ch = bytes[i]; 195 | [str appendFormat:@"%02x", ch]; 196 | } 197 | 198 | [self push:str]; 199 | [str release]; 200 | } 201 | 202 | // data -> base64:string 203 | - (void)op_base64data { 204 | CHECK_STACK_DEPTH(1); 205 | 206 | NSData *dat = [self pop]; 207 | NSString *str = [NSString base64StringFromData:dat length:[dat length]]; 208 | 209 | [self push:str]; 210 | } 211 | 212 | // key:string / data:string -> data 213 | - (void)op_hmac_sha1 { 214 | CHECK_STACK_DEPTH(2); 215 | 216 | NSString *key = [self pop]; 217 | DebugLog(@"hmac_sha1: key: %@", key); 218 | 219 | // The length does not include space for a terminating NULL character. 220 | NSInteger keylen = [key lengthOfBytesUsingEncoding:NSASCIIStringEncoding]; 221 | char *keybuf = malloc(keylen + 1); 222 | // The maximum number of bytes in the string to return in buffer (including the NULL termination byte). 223 | [key getCString:keybuf maxLength:keylen + 1 encoding:NSASCIIStringEncoding]; 224 | 225 | NSString *str = [self pop]; 226 | DebugLog(@"hmac_sha1: str: %@", str); 227 | 228 | // The length does not include space for a terminating NULL character. 229 | NSInteger datalen = [str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; 230 | char *databuf = malloc(datalen + 1); 231 | // The maximum number of bytes in the string to return in buffer (including the NULL termination byte). 232 | [str getCString:databuf maxLength:datalen + 1 encoding:NSUTF8StringEncoding]; 233 | 234 | uint8_t digest[CC_SHA1_DIGEST_LENGTH]; 235 | CCHmac(kCCHmacAlgSHA1, keybuf, keylen, databuf, datalen, digest); 236 | 237 | free(keybuf); 238 | free(databuf); 239 | 240 | NSData *dest = [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH]; 241 | [self push:dest]; 242 | } 243 | 244 | static NSMutableURLRequest* 245 | prepareHTTPConnection (JavaScriptBridge* self, SEL _cmd) 246 | { 247 | CHECK_STACK_DEPTH_WITH_FAIL(2, nil); 248 | 249 | NSString *url_str = [self pop]; 250 | NSInteger n = [[self pop] integerValue]; 251 | 252 | NSURL *url = [NSURL URLWithString:url_str]; 253 | NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; 254 | 255 | CHECK_STACK_DEPTH_WITH_FAIL(n * 2, nil); 256 | for (NSInteger i = 0; i < n; i ++) { 257 | NSString *field = [self pop]; 258 | NSString *value = [self pop]; 259 | [req addValue:value forHTTPHeaderField:field]; 260 | } 261 | 262 | return req; 263 | } 264 | 265 | static void 266 | returnHTTPHandle (JavaScriptBridge *self, SEL _cmd, NSURLRequest *req) 267 | { 268 | JavaScriptBridgeURLConnectionDelegate *hndl = [[JavaScriptBridgeURLConnectionDelegate alloc] initWithWebView:[self webView]]; 269 | NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:req delegate:hndl startImmediately:NO]; 270 | 271 | [self push:[NSString stringWithFormat:@"%d", [hndl connectionID]]]; 272 | [self push:[NSString stringWithFormat:@"%d", conn]]; 273 | } 274 | 275 | // url:string, num_header:number, header_field:string, header_value:string, ... -> connection_handle:string, connectionID:string 276 | - (void)op_http_get { 277 | NSURLRequest *req = prepareHTTPConnection(self, _cmd); 278 | if (!req) {// fail 279 | return; 280 | } 281 | 282 | returnHTTPHandle(self, _cmd, req); 283 | } 284 | 285 | // url:string, num_header:number, header_field:string, header_value:string, ..., request_body:string -> connection_handle:string, connectionID:string 286 | - (void)op_http_post { 287 | NSMutableURLRequest *req = prepareHTTPConnection(self, _cmd); 288 | if (!req) {// fail 289 | return; 290 | } 291 | 292 | CHECK_STACK_DEPTH(1); 293 | NSData *body = [self pop]; 294 | [req setHTTPBody:body]; 295 | [req setHTTPMethod:@"POST"]; 296 | 297 | returnHTTPHandle(self, _cmd, req); 298 | } 299 | 300 | // request_handle:string -> (none) 301 | - (void)op_http_send { 302 | CHECK_STACK_DEPTH(1); 303 | NSURLConnection *conn = (NSURLConnection*)[[self pop] integerValue]; 304 | 305 | [conn start]; 306 | } 307 | 308 | // oauth_token:string, oauth_token_secret:string -> (none) 309 | - (void)op_store_twitter_credential { 310 | CHECK_STACK_DEPTH(2); 311 | NSString *token = [self pop]; 312 | NSString *secret = [self pop]; 313 | 314 | DebugLog(@"token = %@, secret = %@", token, secret); 315 | 316 | NSUserDefaults *def = [NSUserDefaults standardUserDefaults]; 317 | [def setValue:token forKey:@"oauth_token"]; 318 | [def setValue:secret forKey:@"oauth_token_secret"]; 319 | } 320 | 321 | // (none) -> oauth_token:string, oauth_token_secret:string 322 | - (void)op_twitter_credential { 323 | NSUserDefaults *def = [NSUserDefaults standardUserDefaults]; 324 | NSString *token = [def stringForKey:@"oauth_token"]; 325 | NSString *secret = [def stringForKey:@"oauth_token_secret"]; 326 | 327 | if (!secret) secret = @""; 328 | if (!token) token = @""; 329 | 330 | [self push:secret]; 331 | [self push:token]; 332 | } 333 | 334 | // url:string -> handle:string 335 | - (void)op_open_url_in_new_browser { 336 | CHECK_STACK_DEPTH(1); 337 | NSString *url = [self pop]; 338 | 339 | UIWebView *newWebView = [[UIWebView alloc] initWithFrame:[[self webView] frame]]; 340 | [newWebView setDelegate:[[self webView] delegate]]; 341 | [[self webView] addSubview:newWebView]; 342 | [newWebView release]; 343 | 344 | [newWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]]; 345 | [self push:[NSString stringWithFormat:@"%d", newWebView]]; 346 | } 347 | 348 | // handle:string -> (none) 349 | - (void)op_close_browser { 350 | CHECK_STACK_DEPTH(1); 351 | NSInteger hndl = [[self pop] integerValue]; 352 | UIWebView *wv = (UIWebView*)hndl; 353 | 354 | [wv removeFromSuperview]; 355 | } 356 | 357 | 358 | #pragma mark View Controller 359 | 360 | // (none) -> nav_controller:id 361 | - (void)navigation_controller { 362 | [self push:[[self viewController] navigationController]]; 363 | } 364 | 365 | // class:string -> handle:string 366 | - (void)op_create_instance { 367 | CHECK_STACK_DEPTH(1); 368 | 369 | Class cls = (Class)[self pop]; 370 | 371 | if (cls) { 372 | id x = class_createInstance(cls, 0); 373 | [self push:x]; 374 | } else { 375 | [self push:nil]; 376 | } 377 | } 378 | 379 | // class_name:string -> class:string 380 | - (void)op_look_up_class { 381 | CHECK_STACK_DEPTH(1); 382 | NSString *clsname = [self pop]; 383 | Class cls = objc_lookUpClass([clsname cStringUsingEncoding:NSUTF8StringEncoding]); 384 | 385 | [self push:cls]; 386 | } 387 | 388 | /////////////// 389 | #pragma mark - 390 | #pragma mark UITableViewDataSource methods 391 | // Customize the number of sections in the table view. 392 | static NSInteger 393 | numberOfSectionsInTableView(id self, SEL sel, UITableView *tableView) 394 | { 395 | Class cls = objc_getClass("TwitterTimeLineTableView"); 396 | UIWebView *wv = object_getIvar(self, class_getInstanceVariable(cls, "webView")); 397 | NSString *hndl = object_getIvar(self, class_getInstanceVariable(cls, "handler")); 398 | NSString *ret = [wv stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@(\"numberOfSectionsInTableView\")", hndl]]; 399 | DebugLog(@"numberOfSectionsInTableView: hndl: %@, ret: %@", hndl, ret); 400 | return [ret integerValue]; 401 | } 402 | 403 | 404 | // Customize the number of rows in the table view. 405 | static NSInteger 406 | tableView_numberOfRowsInSection(id self, SEL sel, UITableView *tableView, NSInteger section) 407 | { 408 | Class cls = objc_getClass("TwitterTimeLineTableView"); 409 | UIWebView *wv = object_getIvar(self, class_getInstanceVariable(cls, "webView")); 410 | NSString *hndl = object_getIvar(self, class_getInstanceVariable(cls, "handler")); 411 | NSString *ret = [wv stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@(\"tableView_numberOfRowsInSection\", %d)", hndl, section]]; 412 | DebugLog(@"tableView_numberOfRowsInSection: hndl: %@, ret: %@, section: %d", hndl, ret, section); 413 | return [ret integerValue]; 414 | } 415 | 416 | static CGFloat tableView_heightForRowAtIndexPath(id self, SEL sel, UITableView *tableView, NSIndexPath *indexPath); 417 | 418 | // Customize the appearance of table view cells. 419 | static UITableViewCell * 420 | tableView_cellForRowAtIndexPath(id self, SEL sel, UITableView *tableView, NSIndexPath *indexPath) 421 | { 422 | static NSString *CellIdentifier = @"Cell"; 423 | enum { 424 | TWITTER_TABLE_CELL_WEBVIEW = 1, 425 | }; 426 | 427 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 428 | if (cell == nil) { 429 | cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 430 | CGRect webViewFrame = [[cell contentView] frame]; 431 | UIWebView *wv = [[UIWebView alloc] initWithFrame:webViewFrame]; 432 | [cell addSubview:wv]; 433 | [wv setTag:TWITTER_TABLE_CELL_WEBVIEW]; 434 | [wv release]; 435 | } 436 | 437 | // Configure the cell. 438 | Class cls = objc_getClass("TwitterTimeLineTableView"); 439 | UIWebView *wv = object_getIvar(self, class_getInstanceVariable(cls, "webView")); 440 | NSString *hndl = object_getIvar(self, class_getInstanceVariable(cls, "handler")); 441 | NSString *ret = [wv stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@(\"tableView_cellForRowAtIndexPath\", %d, %d)", 442 | hndl, [indexPath section], [indexPath row]]]; 443 | 444 | CGFloat height = tableView_heightForRowAtIndexPath(self, sel, tableView, indexPath); 445 | 446 | UIWebView *cell_wv = (UIWebView*)[cell viewWithTag:TWITTER_TABLE_CELL_WEBVIEW]; 447 | CGRect rect = [cell frame]; 448 | rect.origin.x = 0; 449 | rect.origin.y = 0; 450 | rect.size.height = height; 451 | [cell_wv setFrame:rect]; 452 | // DebugLog(@"row: %d, HTML: %@", [indexPath row], ret); 453 | [cell_wv loadHTMLString:ret baseURL:nil]; 454 | 455 | return cell; 456 | } 457 | #pragma mark UITableViewDelegate methods 458 | 459 | static CGFloat 460 | tableView_heightForRowAtIndexPath(id self, SEL sel, UITableView *tableView, NSIndexPath *indexPath) 461 | { 462 | // DebugLog(@"tableView_heightForRowAtIndexPath: %@, %@", tableView, indexPath); 463 | Class cls = objc_getClass("TwitterTimeLineTableView"); 464 | UIWebView *wv = object_getIvar(self, class_getInstanceVariable(cls, "webView")); 465 | NSString *hndl = object_getIvar(self, class_getInstanceVariable(cls, "handler")); 466 | NSString *ret = [wv stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"%@(\"tableView_heightForRowAtIndexPath\", %d, %d)", 467 | hndl, indexPath.section, indexPath.row]]; 468 | // DebugLog(@"tableView_heightForRowAtIndexPath: hndl: %@, ret: %@, section: %d", hndl, ret, indexPath.section, indexPath.row); 469 | return [ret floatValue]; 470 | } 471 | 472 | //////////////////////// 473 | #pragma mark - 474 | 475 | // func:string, controller:UITableViewController -> table:? 476 | - (void)op_xxx_pushtable { 477 | CHECK_STACK_DEPTH(2); 478 | NSString *func = [self pop]; 479 | UITableViewController *cont = [self pop]; 480 | DebugLog(@"xxx_pushtable: %@, %@", func, cont); 481 | 482 | UIBarButtonItem *back = [[UIBarButtonItem alloc] initWithTitle:nil style:UIBarButtonItemStyleDone target:nil action:nil]; 483 | [[[self viewController] navigationItem] setBackBarButtonItem:back]; 484 | [[self viewController] setTitle:@"Top"]; 485 | 486 | Class hogeClass = objc_allocateClassPair([NSObject class], "TwitterTimeLineTableView", 0); 487 | class_addProtocol(hogeClass, objc_getProtocol("UITableViewDataSource")); 488 | class_addProtocol(hogeClass, objc_getProtocol("UITableViewDelegate")); 489 | 490 | BOOL res1 = class_addMethod(hogeClass, @selector(numberOfSectionsInTableView:), (IMP)numberOfSectionsInTableView, "i@:@"); 491 | BOOL res2 = class_addMethod(hogeClass, @selector(tableView:numberOfRowsInSection:), (IMP)tableView_numberOfRowsInSection, "i@:@i"); 492 | BOOL res3 = class_addMethod(hogeClass, @selector(tableView:cellForRowAtIndexPath:), (IMP)tableView_cellForRowAtIndexPath, "i@:@@"); 493 | 494 | BOOL res4 = class_addIvar(hogeClass, "handler", sizeof(id), log2(sizeof(id)), "@"); 495 | BOOL res5 = class_addIvar(hogeClass, "webView", sizeof(id), log2(sizeof(id)), "@"); 496 | 497 | BOOL res6 = class_addMethod(hogeClass, @selector(tableView:heightForRowAtIndexPath:), (IMP)tableView_heightForRowAtIndexPath, "f@:@@"); 498 | 499 | DebugLog(@"res = %d, %d, %d, %d, %d, %d", res1, res2, res3, res4, res5, res6); 500 | if (!(res1 && res2 && res3 && res4 && res5 && res6)) { 501 | ErrorLog(@"Failed to create a class: %d, %d, %d, %d, %d, %d", res1, res2, res3, res4, res5, res6); 502 | } 503 | 504 | objc_registerClassPair(hogeClass); 505 | 506 | id tbl = class_createInstance(hogeClass, 0); 507 | [tbl init]; 508 | object_setIvar(tbl, class_getInstanceVariable(hogeClass, "handler"), [func retain]); 509 | object_setIvar(tbl, class_getInstanceVariable(hogeClass, "webView"), [[self webView] retain]); 510 | DebugLog(@"tbl %@", tbl); 511 | [[cont tableView] setDataSource:tbl]; 512 | [[cont tableView] setDelegate:tbl]; 513 | 514 | UINavigationController *navcont = [[self viewController] navigationController]; 515 | [navcont pushViewController:cont animated:YES]; 516 | 517 | [self push:@"hoge"]; 518 | } 519 | 520 | // handle:string, selector:string, numargs:integer, arg:id, ... -> id 521 | - (void)op_send_mesg { 522 | CHECK_STACK_DEPTH(2); 523 | id obj = (id)[[self pop] integerValue]; 524 | SEL mesg = (SEL)[[self pop] integerValue]; 525 | int n = [[self pop] integerValue]; 526 | id ret = nil; 527 | 528 | CHECK_STACK_DEPTH(n); 529 | 530 | switch (n) { 531 | case 0: 532 | ret = objc_msgSend(obj, mesg); 533 | break; 534 | 535 | case 1: 536 | ret = objc_msgSend(obj, mesg, [self pop]); 537 | break; 538 | 539 | case 2: 540 | ret = objc_msgSend(obj, mesg, [self pop], [self pop]); 541 | break; 542 | 543 | case 3: 544 | ret = objc_msgSend(obj, mesg, [self pop], [self pop], [self pop]); 545 | break; 546 | 547 | default: 548 | break; 549 | } 550 | 551 | [self push:ret]; 552 | } 553 | 554 | 555 | 556 | @end 557 | -------------------------------------------------------------------------------- /JSBridgeTest/MainWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1024 5 | 10D571 6 | 786 7 | 1038.29 8 | 460.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 112 12 | 13 | 14 | YES 15 | 16 | 17 | 18 | YES 19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 20 | 21 | 22 | YES 23 | 24 | YES 25 | 26 | 27 | YES 28 | 29 | 30 | 31 | YES 32 | 33 | IBFilesOwner 34 | IBCocoaTouchFramework 35 | 36 | 37 | IBFirstResponder 38 | IBCocoaTouchFramework 39 | 40 | 41 | IBCocoaTouchFramework 42 | 43 | 44 | 45 | 1316 46 | 47 | {320, 480} 48 | 49 | 1 50 | MSAxIDEAA 51 | 52 | NO 53 | NO 54 | 55 | IBCocoaTouchFramework 56 | YES 57 | 58 | 59 | 60 | 61 | 1 62 | 63 | IBCocoaTouchFramework 64 | NO 65 | 66 | 67 | 256 68 | {0, 0} 69 | NO 70 | YES 71 | YES 72 | IBCocoaTouchFramework 73 | 74 | 75 | YES 76 | 77 | 78 | 79 | IBCocoaTouchFramework 80 | 81 | 82 | RootViewController 83 | 84 | 85 | 1 86 | 87 | IBCocoaTouchFramework 88 | NO 89 | 90 | 91 | 92 | 93 | 94 | 95 | YES 96 | 97 | 98 | delegate 99 | 100 | 101 | 102 | 4 103 | 104 | 105 | 106 | window 107 | 108 | 109 | 110 | 5 111 | 112 | 113 | 114 | navigationController 115 | 116 | 117 | 118 | 15 119 | 120 | 121 | 122 | 123 | YES 124 | 125 | 0 126 | 127 | 128 | 129 | 130 | 131 | 2 132 | 133 | 134 | YES 135 | 136 | 137 | 138 | 139 | -1 140 | 141 | 142 | File's Owner 143 | 144 | 145 | 3 146 | 147 | 148 | 149 | 150 | -2 151 | 152 | 153 | 154 | 155 | 9 156 | 157 | 158 | YES 159 | 160 | 161 | 162 | 163 | 164 | 165 | 11 166 | 167 | 168 | 169 | 170 | 13 171 | 172 | 173 | YES 174 | 175 | 176 | 177 | 178 | 179 | 14 180 | 181 | 182 | 183 | 184 | 185 | 186 | YES 187 | 188 | YES 189 | -1.CustomClassName 190 | -2.CustomClassName 191 | 11.IBPluginDependency 192 | 13.CustomClassName 193 | 13.IBPluginDependency 194 | 2.IBAttributePlaceholdersKey 195 | 2.IBEditorWindowLastContentRect 196 | 2.IBPluginDependency 197 | 3.CustomClassName 198 | 3.IBPluginDependency 199 | 9.IBEditorWindowLastContentRect 200 | 9.IBPluginDependency 201 | 202 | 203 | YES 204 | UIApplication 205 | UIResponder 206 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 207 | RootViewController 208 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 209 | 210 | YES 211 | 212 | 213 | YES 214 | 215 | 216 | {{673, 376}, {320, 480}} 217 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 218 | JSBridgeTestAppDelegate 219 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 220 | {{186, 376}, {320, 480}} 221 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 222 | 223 | 224 | 225 | YES 226 | 227 | 228 | YES 229 | 230 | 231 | 232 | 233 | YES 234 | 235 | 236 | YES 237 | 238 | 239 | 240 | 16 241 | 242 | 243 | 244 | YES 245 | 246 | RootViewController 247 | UITableViewController 248 | 249 | IBProjectSource 250 | Classes/RootViewController.h 251 | 252 | 253 | 254 | UIWindow 255 | UIView 256 | 257 | IBUserSource 258 | 259 | 260 | 261 | 262 | JSBridgeTestAppDelegate 263 | NSObject 264 | 265 | YES 266 | 267 | YES 268 | navigationController 269 | window 270 | 271 | 272 | YES 273 | UINavigationController 274 | UIWindow 275 | 276 | 277 | 278 | YES 279 | 280 | YES 281 | navigationController 282 | window 283 | 284 | 285 | YES 286 | 287 | navigationController 288 | UINavigationController 289 | 290 | 291 | window 292 | UIWindow 293 | 294 | 295 | 296 | 297 | IBProjectSource 298 | Classes/JSBridgeTestAppDelegate.h 299 | 300 | 301 | 302 | 303 | YES 304 | 305 | NSObject 306 | 307 | IBFrameworkSource 308 | Foundation.framework/Headers/NSError.h 309 | 310 | 311 | 312 | NSObject 313 | 314 | IBFrameworkSource 315 | Foundation.framework/Headers/NSFileManager.h 316 | 317 | 318 | 319 | NSObject 320 | 321 | IBFrameworkSource 322 | Foundation.framework/Headers/NSKeyValueCoding.h 323 | 324 | 325 | 326 | NSObject 327 | 328 | IBFrameworkSource 329 | Foundation.framework/Headers/NSKeyValueObserving.h 330 | 331 | 332 | 333 | NSObject 334 | 335 | IBFrameworkSource 336 | Foundation.framework/Headers/NSKeyedArchiver.h 337 | 338 | 339 | 340 | NSObject 341 | 342 | IBFrameworkSource 343 | Foundation.framework/Headers/NSObject.h 344 | 345 | 346 | 347 | NSObject 348 | 349 | IBFrameworkSource 350 | Foundation.framework/Headers/NSRunLoop.h 351 | 352 | 353 | 354 | NSObject 355 | 356 | IBFrameworkSource 357 | Foundation.framework/Headers/NSThread.h 358 | 359 | 360 | 361 | NSObject 362 | 363 | IBFrameworkSource 364 | Foundation.framework/Headers/NSURL.h 365 | 366 | 367 | 368 | NSObject 369 | 370 | IBFrameworkSource 371 | Foundation.framework/Headers/NSURLConnection.h 372 | 373 | 374 | 375 | NSObject 376 | 377 | IBFrameworkSource 378 | UIKit.framework/Headers/UIAccessibility.h 379 | 380 | 381 | 382 | NSObject 383 | 384 | IBFrameworkSource 385 | UIKit.framework/Headers/UINibLoading.h 386 | 387 | 388 | 389 | NSObject 390 | 391 | IBFrameworkSource 392 | UIKit.framework/Headers/UIResponder.h 393 | 394 | 395 | 396 | UIApplication 397 | UIResponder 398 | 399 | IBFrameworkSource 400 | UIKit.framework/Headers/UIApplication.h 401 | 402 | 403 | 404 | UIBarButtonItem 405 | UIBarItem 406 | 407 | IBFrameworkSource 408 | UIKit.framework/Headers/UIBarButtonItem.h 409 | 410 | 411 | 412 | UIBarItem 413 | NSObject 414 | 415 | IBFrameworkSource 416 | UIKit.framework/Headers/UIBarItem.h 417 | 418 | 419 | 420 | UINavigationBar 421 | UIView 422 | 423 | IBFrameworkSource 424 | UIKit.framework/Headers/UINavigationBar.h 425 | 426 | 427 | 428 | UINavigationController 429 | UIViewController 430 | 431 | IBFrameworkSource 432 | UIKit.framework/Headers/UINavigationController.h 433 | 434 | 435 | 436 | UINavigationItem 437 | NSObject 438 | 439 | 440 | 441 | UIResponder 442 | NSObject 443 | 444 | 445 | 446 | UISearchBar 447 | UIView 448 | 449 | IBFrameworkSource 450 | UIKit.framework/Headers/UISearchBar.h 451 | 452 | 453 | 454 | UISearchDisplayController 455 | NSObject 456 | 457 | IBFrameworkSource 458 | UIKit.framework/Headers/UISearchDisplayController.h 459 | 460 | 461 | 462 | UITableViewController 463 | UIViewController 464 | 465 | IBFrameworkSource 466 | UIKit.framework/Headers/UITableViewController.h 467 | 468 | 469 | 470 | UIView 471 | 472 | IBFrameworkSource 473 | UIKit.framework/Headers/UITextField.h 474 | 475 | 476 | 477 | UIView 478 | UIResponder 479 | 480 | IBFrameworkSource 481 | UIKit.framework/Headers/UIView.h 482 | 483 | 484 | 485 | UIViewController 486 | 487 | 488 | 489 | UIViewController 490 | 491 | IBFrameworkSource 492 | UIKit.framework/Headers/UIPopoverController.h 493 | 494 | 495 | 496 | UIViewController 497 | 498 | IBFrameworkSource 499 | UIKit.framework/Headers/UISplitViewController.h 500 | 501 | 502 | 503 | UIViewController 504 | 505 | IBFrameworkSource 506 | UIKit.framework/Headers/UITabBarController.h 507 | 508 | 509 | 510 | UIViewController 511 | UIResponder 512 | 513 | IBFrameworkSource 514 | UIKit.framework/Headers/UIViewController.h 515 | 516 | 517 | 518 | UIWindow 519 | UIView 520 | 521 | IBFrameworkSource 522 | UIKit.framework/Headers/UIWindow.h 523 | 524 | 525 | 526 | 527 | 0 528 | IBCocoaTouchFramework 529 | 530 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 531 | 532 | 533 | 534 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 535 | 536 | 537 | YES 538 | JSBridgeTest.xcodeproj 539 | 3 540 | 112 541 | 542 | 543 | -------------------------------------------------------------------------------- /JSBridgeTest/html/jquery-1.4.4.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery JavaScript Library v1.4.4 3 | * http://jquery.com/ 4 | * 5 | * Copyright 2010, John Resig 6 | * Dual licensed under the MIT or GPL Version 2 licenses. 7 | * http://jquery.org/license 8 | * 9 | * Includes Sizzle.js 10 | * http://sizzlejs.com/ 11 | * Copyright 2010, The Dojo Foundation 12 | * Released under the MIT, BSD, and GPL Licenses. 13 | * 14 | * Date: Thu Nov 11 19:04:53 2010 -0500 15 | */ 16 | (function(E,B){function ka(a,b,d){if(d===B&&a.nodeType===1){d=a.getAttribute("data-"+b);if(typeof d==="string"){try{d=d==="true"?true:d==="false"?false:d==="null"?null:!c.isNaN(d)?parseFloat(d):Ja.test(d)?c.parseJSON(d):d}catch(e){}c.data(a,b,d)}else d=B}return d}function U(){return false}function ca(){return true}function la(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function Ka(a){var b,d,e,f,h,l,k,o,x,r,A,C=[];f=[];h=c.data(this,this.nodeType?"events":"__events__");if(typeof h==="function")h= 17 | h.events;if(!(a.liveFired===this||!h||!h.live||a.button&&a.type==="click")){if(a.namespace)A=RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)");a.liveFired=this;var J=h.live.slice(0);for(k=0;kd)break;a.currentTarget=f.elem;a.data=f.handleObj.data;a.handleObj=f.handleObj;A=f.handleObj.origHandler.apply(f.elem,arguments);if(A===false||a.isPropagationStopped()){d=f.level;if(A===false)b=false;if(a.isImmediatePropagationStopped())break}}return b}}function Y(a,b){return(a&&a!=="*"?a+".":"")+b.replace(La, 19 | "`").replace(Ma,"&")}function ma(a,b,d){if(c.isFunction(b))return c.grep(a,function(f,h){return!!b.call(f,h,f)===d});else if(b.nodeType)return c.grep(a,function(f){return f===b===d});else if(typeof b==="string"){var e=c.grep(a,function(f){return f.nodeType===1});if(Na.test(b))return c.filter(b,e,!d);else b=c.filter(b,e)}return c.grep(a,function(f){return c.inArray(f,b)>=0===d})}function na(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var e=c.data(a[d++]),f=c.data(this, 20 | e);if(e=e&&e.events){delete f.handle;f.events={};for(var h in e)for(var l in e[h])c.event.add(this,h,e[h][l],e[h][l].data)}}})}function Oa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function oa(a,b,d){var e=b==="width"?a.offsetWidth:a.offsetHeight;if(d==="border")return e;c.each(b==="width"?Pa:Qa,function(){d||(e-=parseFloat(c.css(a,"padding"+this))||0);if(d==="margin")e+=parseFloat(c.css(a, 21 | "margin"+this))||0;else e-=parseFloat(c.css(a,"border"+this+"Width"))||0});return e}function da(a,b,d,e){if(c.isArray(b)&&b.length)c.each(b,function(f,h){d||Ra.test(a)?e(a,h):da(a+"["+(typeof h==="object"||c.isArray(h)?f:"")+"]",h,d,e)});else if(!d&&b!=null&&typeof b==="object")c.isEmptyObject(b)?e(a,""):c.each(b,function(f,h){da(a+"["+f+"]",h,d,e)});else e(a,b)}function S(a,b){var d={};c.each(pa.concat.apply([],pa.slice(0,b)),function(){d[this]=a});return d}function qa(a){if(!ea[a]){var b=c("<"+ 22 | a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d==="")d="block";ea[a]=d}return ea[a]}function fa(a){return c.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var t=E.document,c=function(){function a(){if(!b.isReady){try{t.documentElement.doScroll("left")}catch(j){setTimeout(a,1);return}b.ready()}}var b=function(j,s){return new b.fn.init(j,s)},d=E.jQuery,e=E.$,f,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,l=/\S/,k=/^\s+/,o=/\s+$/,x=/\W/,r=/\d/,A=/^<(\w+)\s*\/?>(?:<\/\1>)?$/, 23 | C=/^[\],:{}\s]*$/,J=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,w=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,I=/(?:^|:|,)(?:\s*\[)+/g,L=/(webkit)[ \/]([\w.]+)/,g=/(opera)(?:.*version)?[ \/]([\w.]+)/,i=/(msie) ([\w.]+)/,n=/(mozilla)(?:.*? rv:([\w.]+))?/,m=navigator.userAgent,p=false,q=[],u,y=Object.prototype.toString,F=Object.prototype.hasOwnProperty,M=Array.prototype.push,N=Array.prototype.slice,O=String.prototype.trim,D=Array.prototype.indexOf,R={};b.fn=b.prototype={init:function(j, 24 | s){var v,z,H;if(!j)return this;if(j.nodeType){this.context=this[0]=j;this.length=1;return this}if(j==="body"&&!s&&t.body){this.context=t;this[0]=t.body;this.selector="body";this.length=1;return this}if(typeof j==="string")if((v=h.exec(j))&&(v[1]||!s))if(v[1]){H=s?s.ownerDocument||s:t;if(z=A.exec(j))if(b.isPlainObject(s)){j=[t.createElement(z[1])];b.fn.attr.call(j,s,true)}else j=[H.createElement(z[1])];else{z=b.buildFragment([v[1]],[H]);j=(z.cacheable?z.fragment.cloneNode(true):z.fragment).childNodes}return b.merge(this, 25 | j)}else{if((z=t.getElementById(v[2]))&&z.parentNode){if(z.id!==v[2])return f.find(j);this.length=1;this[0]=z}this.context=t;this.selector=j;return this}else if(!s&&!x.test(j)){this.selector=j;this.context=t;j=t.getElementsByTagName(j);return b.merge(this,j)}else return!s||s.jquery?(s||f).find(j):b(s).find(j);else if(b.isFunction(j))return f.ready(j);if(j.selector!==B){this.selector=j.selector;this.context=j.context}return b.makeArray(j,this)},selector:"",jquery:"1.4.4",length:0,size:function(){return this.length}, 26 | toArray:function(){return N.call(this,0)},get:function(j){return j==null?this.toArray():j<0?this.slice(j)[0]:this[j]},pushStack:function(j,s,v){var z=b();b.isArray(j)?M.apply(z,j):b.merge(z,j);z.prevObject=this;z.context=this.context;if(s==="find")z.selector=this.selector+(this.selector?" ":"")+v;else if(s)z.selector=this.selector+"."+s+"("+v+")";return z},each:function(j,s){return b.each(this,j,s)},ready:function(j){b.bindReady();if(b.isReady)j.call(t,b);else q&&q.push(j);return this},eq:function(j){return j=== 27 | -1?this.slice(j):this.slice(j,+j+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(N.apply(this,arguments),"slice",N.call(arguments).join(","))},map:function(j){return this.pushStack(b.map(this,function(s,v){return j.call(s,v,s)}))},end:function(){return this.prevObject||b(null)},push:M,sort:[].sort,splice:[].splice};b.fn.init.prototype=b.fn;b.extend=b.fn.extend=function(){var j,s,v,z,H,G=arguments[0]||{},K=1,Q=arguments.length,ga=false; 28 | if(typeof G==="boolean"){ga=G;G=arguments[1]||{};K=2}if(typeof G!=="object"&&!b.isFunction(G))G={};if(Q===K){G=this;--K}for(;K0))if(q){var s=0,v=q;for(q=null;j=v[s++];)j.call(t,b);b.fn.trigger&&b(t).trigger("ready").unbind("ready")}}},bindReady:function(){if(!p){p=true;if(t.readyState==="complete")return setTimeout(b.ready,1);if(t.addEventListener){t.addEventListener("DOMContentLoaded",u,false);E.addEventListener("load",b.ready,false)}else if(t.attachEvent){t.attachEvent("onreadystatechange",u);E.attachEvent("onload", 30 | b.ready);var j=false;try{j=E.frameElement==null}catch(s){}t.documentElement.doScroll&&j&&a()}}},isFunction:function(j){return b.type(j)==="function"},isArray:Array.isArray||function(j){return b.type(j)==="array"},isWindow:function(j){return j&&typeof j==="object"&&"setInterval"in j},isNaN:function(j){return j==null||!r.test(j)||isNaN(j)},type:function(j){return j==null?String(j):R[y.call(j)]||"object"},isPlainObject:function(j){if(!j||b.type(j)!=="object"||j.nodeType||b.isWindow(j))return false;if(j.constructor&& 31 | !F.call(j,"constructor")&&!F.call(j.constructor.prototype,"isPrototypeOf"))return false;for(var s in j);return s===B||F.call(j,s)},isEmptyObject:function(j){for(var s in j)return false;return true},error:function(j){throw j;},parseJSON:function(j){if(typeof j!=="string"||!j)return null;j=b.trim(j);if(C.test(j.replace(J,"@").replace(w,"]").replace(I,"")))return E.JSON&&E.JSON.parse?E.JSON.parse(j):(new Function("return "+j))();else b.error("Invalid JSON: "+j)},noop:function(){},globalEval:function(j){if(j&& 32 | l.test(j)){var s=t.getElementsByTagName("head")[0]||t.documentElement,v=t.createElement("script");v.type="text/javascript";if(b.support.scriptEval)v.appendChild(t.createTextNode(j));else v.text=j;s.insertBefore(v,s.firstChild);s.removeChild(v)}},nodeName:function(j,s){return j.nodeName&&j.nodeName.toUpperCase()===s.toUpperCase()},each:function(j,s,v){var z,H=0,G=j.length,K=G===B||b.isFunction(j);if(v)if(K)for(z in j){if(s.apply(j[z],v)===false)break}else for(;H
a";var f=d.getElementsByTagName("*"),h=d.getElementsByTagName("a")[0],l=t.createElement("select"), 38 | k=l.appendChild(t.createElement("option"));if(!(!f||!f.length||!h)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(h.getAttribute("style")),hrefNormalized:h.getAttribute("href")==="/a",opacity:/^0.55$/.test(h.style.opacity),cssFloat:!!h.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:k.selected,deleteExpando:true,optDisabled:false,checkClone:false, 39 | scriptEval:false,noCloneEvent:true,boxModel:null,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableHiddenOffsets:true};l.disabled=true;c.support.optDisabled=!k.disabled;b.type="text/javascript";try{b.appendChild(t.createTextNode("window."+e+"=1;"))}catch(o){}a.insertBefore(b,a.firstChild);if(E[e]){c.support.scriptEval=true;delete E[e]}try{delete b.test}catch(x){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function r(){c.support.noCloneEvent= 40 | false;d.detachEvent("onclick",r)});d.cloneNode(true).fireEvent("onclick")}d=t.createElement("div");d.innerHTML="";a=t.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var r=t.createElement("div");r.style.width=r.style.paddingLeft="1px";t.body.appendChild(r);c.boxModel=c.support.boxModel=r.offsetWidth===2;if("zoom"in r.style){r.style.display="inline";r.style.zoom= 41 | 1;c.support.inlineBlockNeedsLayout=r.offsetWidth===2;r.style.display="";r.innerHTML="
";c.support.shrinkWrapBlocks=r.offsetWidth!==2}r.innerHTML="
t
";var A=r.getElementsByTagName("td");c.support.reliableHiddenOffsets=A[0].offsetHeight===0;A[0].style.display="";A[1].style.display="none";c.support.reliableHiddenOffsets=c.support.reliableHiddenOffsets&&A[0].offsetHeight===0;r.innerHTML="";t.body.removeChild(r).style.display= 42 | "none"});a=function(r){var A=t.createElement("div");r="on"+r;var C=r in A;if(!C){A.setAttribute(r,"return;");C=typeof A[r]==="function"}return C};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=f=h=null}})();var ra={},Ja=/^(?:\{.*\}|\[.*\])$/;c.extend({cache:{},uuid:0,expando:"jQuery"+c.now(),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},data:function(a,b,d){if(c.acceptData(a)){a=a==E?ra:a;var e=a.nodeType,f=e?a[c.expando]:null,h= 43 | c.cache;if(!(e&&!f&&typeof b==="string"&&d===B)){if(e)f||(a[c.expando]=f=++c.uuid);else h=a;if(typeof b==="object")if(e)h[f]=c.extend(h[f],b);else c.extend(h,b);else if(e&&!h[f])h[f]={};a=e?h[f]:h;if(d!==B)a[b]=d;return typeof b==="string"?a[b]:a}}},removeData:function(a,b){if(c.acceptData(a)){a=a==E?ra:a;var d=a.nodeType,e=d?a[c.expando]:a,f=c.cache,h=d?f[e]:e;if(b){if(h){delete h[b];d&&c.isEmptyObject(h)&&c.removeData(a)}}else if(d&&c.support.deleteExpando)delete a[c.expando];else if(a.removeAttribute)a.removeAttribute(c.expando); 44 | else if(d)delete f[e];else for(var l in a)delete a[l]}},acceptData:function(a){if(a.nodeName){var b=c.noData[a.nodeName.toLowerCase()];if(b)return!(b===true||a.getAttribute("classid")!==b)}return true}});c.fn.extend({data:function(a,b){var d=null;if(typeof a==="undefined"){if(this.length){var e=this[0].attributes,f;d=c.data(this[0]);for(var h=0,l=e.length;h-1)return true;return false},val:function(a){if(!arguments.length){var b=this[0];if(b){if(c.nodeName(b,"option")){var d=b.attributes.value;return!d||d.specified?b.value:b.text}if(c.nodeName(b,"select")){var e=b.selectedIndex;d=[];var f=b.options;b=b.type==="select-one"; 52 | if(e<0)return null;var h=b?e:0;for(e=b?e+1:f.length;h=0;else if(c.nodeName(this,"select")){var A=c.makeArray(r);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),A)>=0});if(!A.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true}, 54 | attr:function(a,b,d,e){if(!a||a.nodeType===3||a.nodeType===8)return B;if(e&&b in c.attrFn)return c(a)[b](d);e=a.nodeType!==1||!c.isXMLDoc(a);var f=d!==B;b=e&&c.props[b]||b;var h=Ta.test(b);if((b in a||a[b]!==B)&&e&&!h){if(f){b==="type"&&Ua.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");if(d===null)a.nodeType===1&&a.removeAttribute(b);else a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&& 55 | b.specified?b.value:Va.test(a.nodeName)||Wa.test(a.nodeName)&&a.href?0:B;return a[b]}if(!c.support.style&&e&&b==="style"){if(f)a.style.cssText=""+d;return a.style.cssText}f&&a.setAttribute(b,""+d);if(!a.attributes[b]&&a.hasAttribute&&!a.hasAttribute(b))return B;a=!c.support.hrefNormalized&&e&&h?a.getAttribute(b,2):a.getAttribute(b);return a===null?B:a}});var X=/\.(.*)$/,ia=/^(?:textarea|input|select)$/i,La=/\./g,Ma=/ /g,Xa=/[^\w\s.|`]/g,Ya=function(a){return a.replace(Xa,"\\$&")},ua={focusin:0,focusout:0}; 56 | c.event={add:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(c.isWindow(a)&&a!==E&&!a.frameElement)a=E;if(d===false)d=U;else if(!d)return;var f,h;if(d.handler){f=d;d=f.handler}if(!d.guid)d.guid=c.guid++;if(h=c.data(a)){var l=a.nodeType?"events":"__events__",k=h[l],o=h.handle;if(typeof k==="function"){o=k.handle;k=k.events}else if(!k){a.nodeType||(h[l]=h=function(){});h.events=k={}}if(!o)h.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem, 57 | arguments):B};o.elem=a;b=b.split(" ");for(var x=0,r;l=b[x++];){h=f?c.extend({},f):{handler:d,data:e};if(l.indexOf(".")>-1){r=l.split(".");l=r.shift();h.namespace=r.slice(0).sort().join(".")}else{r=[];h.namespace=""}h.type=l;if(!h.guid)h.guid=d.guid;var A=k[l],C=c.event.special[l]||{};if(!A){A=k[l]=[];if(!C.setup||C.setup.call(a,e,r,o)===false)if(a.addEventListener)a.addEventListener(l,o,false);else a.attachEvent&&a.attachEvent("on"+l,o)}if(C.add){C.add.call(a,h);if(!h.handler.guid)h.handler.guid= 58 | d.guid}A.push(h);c.event.global[l]=true}a=null}}},global:{},remove:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(d===false)d=U;var f,h,l=0,k,o,x,r,A,C,J=a.nodeType?"events":"__events__",w=c.data(a),I=w&&w[J];if(w&&I){if(typeof I==="function"){w=I;I=I.events}if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(f in I)c.event.remove(a,f+b)}else{for(b=b.split(" ");f=b[l++];){r=f;k=f.indexOf(".")<0;o=[];if(!k){o=f.split(".");f=o.shift();x=RegExp("(^|\\.)"+ 59 | c.map(o.slice(0).sort(),Ya).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(A=I[f])if(d){r=c.event.special[f]||{};for(h=e||0;h=0){a.type=f=f.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[f]&&c.each(c.cache,function(){this.events&&this.events[f]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType=== 61 | 8)return B;a.result=B;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(e=d.nodeType?c.data(d,"handle"):(c.data(d,"__events__")||{}).handle)&&e.apply(d,b);e=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+f]&&d["on"+f].apply(d,b)===false){a.result=false;a.preventDefault()}}catch(h){}if(!a.isPropagationStopped()&&e)c.event.trigger(a,b,e,true);else if(!a.isDefaultPrevented()){var l;e=a.target;var k=f.replace(X,""),o=c.nodeName(e,"a")&&k=== 62 | "click",x=c.event.special[k]||{};if((!x._default||x._default.call(d,a)===false)&&!o&&!(e&&e.nodeName&&c.noData[e.nodeName.toLowerCase()])){try{if(e[k]){if(l=e["on"+k])e["on"+k]=null;c.event.triggered=true;e[k]()}}catch(r){}if(l)e["on"+k]=l;c.event.triggered=false}}},handle:function(a){var b,d,e,f;d=[];var h=c.makeArray(arguments);a=h[0]=c.event.fix(a||E.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;if(!b){e=a.type.split(".");a.type=e.shift();d=e.slice(0).sort();e=RegExp("(^|\\.)"+ 63 | d.join("\\.(?:.*\\.)?")+"(\\.|$)")}a.namespace=a.namespace||d.join(".");f=c.data(this,this.nodeType?"events":"__events__");if(typeof f==="function")f=f.events;d=(f||{})[a.type];if(f&&d){d=d.slice(0);f=0;for(var l=d.length;f-1?c.map(a.options,function(e){return e.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},Z=function(a,b){var d=a.target,e,f;if(!(!ia.test(d.nodeName)||d.readOnly)){e=c.data(d,"_change_data");f=xa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",f);if(!(e===B||f===e))if(e!=null||f){a.type="change";a.liveFired= 71 | B;return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:Z,beforedeactivate:Z,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return Z.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return Z.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,"_change_data",xa(a))}},setup:function(){if(this.type=== 72 | "file")return false;for(var a in V)c.event.add(this,a+".specialChange",V[a]);return ia.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return ia.test(this.nodeName)}};V=c.event.special.change.filters;V.focus=V.beforeactivate}t.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.trigger(e,null,e.target)}c.event.special[b]={setup:function(){ua[b]++===0&&t.addEventListener(a,d,true)},teardown:function(){--ua[b]=== 73 | 0&&t.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,e,f){if(typeof d==="object"){for(var h in d)this[b](h,e,d[h],f);return this}if(c.isFunction(e)||e===false){f=e;e=B}var l=b==="one"?c.proxy(f,function(o){c(this).unbind(o,l);return f.apply(this,arguments)}):f;if(d==="unload"&&b!=="one")this.one(d,e,f);else{h=0;for(var k=this.length;h0?this.bind(b,d,e):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});E.attachEvent&&!E.addEventListener&&c(E).bind("unload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}}); 78 | (function(){function a(g,i,n,m,p,q){p=0;for(var u=m.length;p0){F=y;break}}y=y[g]}m[p]=F}}}var d=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,h=false,l=true;[0,0].sort(function(){l=false;return 0});var k=function(g,i,n,m){n=n||[];var p=i=i||t;if(i.nodeType!==1&&i.nodeType!==9)return[];if(!g||typeof g!=="string")return n;var q,u,y,F,M,N=true,O=k.isXML(i),D=[],R=g;do{d.exec("");if(q=d.exec(R)){R=q[3];D.push(q[1]);if(q[2]){F=q[3]; 80 | break}}}while(q);if(D.length>1&&x.exec(g))if(D.length===2&&o.relative[D[0]])u=L(D[0]+D[1],i);else for(u=o.relative[D[0]]?[i]:k(D.shift(),i);D.length;){g=D.shift();if(o.relative[g])g+=D.shift();u=L(g,u)}else{if(!m&&D.length>1&&i.nodeType===9&&!O&&o.match.ID.test(D[0])&&!o.match.ID.test(D[D.length-1])){q=k.find(D.shift(),i,O);i=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]}if(i){q=m?{expr:D.pop(),set:C(m)}:k.find(D.pop(),D.length===1&&(D[0]==="~"||D[0]==="+")&&i.parentNode?i.parentNode:i,O);u=q.expr?k.filter(q.expr, 81 | q.set):q.set;if(D.length>0)y=C(u);else N=false;for(;D.length;){q=M=D.pop();if(o.relative[M])q=D.pop();else M="";if(q==null)q=i;o.relative[M](y,q,O)}}else y=[]}y||(y=u);y||k.error(M||g);if(f.call(y)==="[object Array]")if(N)if(i&&i.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&k.contains(i,y[g])))n.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&n.push(u[g]);else n.push.apply(n,y);else C(y,n);if(F){k(F,p,n,m);k.uniqueSort(n)}return n};k.uniqueSort=function(g){if(w){h= 82 | l;g.sort(w);if(h)for(var i=1;i0};k.find=function(g,i,n){var m;if(!g)return[];for(var p=0,q=o.order.length;p":function(g,i){var n,m=typeof i==="string",p=0,q=g.length;if(m&&!/\W/.test(i))for(i=i.toLowerCase();p=0))n||m.push(u);else if(n)i[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var i=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=i[1]+(i[2]||1)-0;g[3]=i[3]-0}g[0]=e++;return g},ATTR:function(g,i,n, 89 | m,p,q){i=g[1].replace(/\\/g,"");if(!q&&o.attrMap[i])g[1]=o.attrMap[i];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,i,n,m,p){if(g[1]==="not")if((d.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,i);else{g=k.filter(g[3],i,n,true^p);n||m.push.apply(m,g);return false}else if(o.match.POS.test(g[0])||o.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled=== 90 | true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,i,n){return!!k(n[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"=== 91 | g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,i){return i===0},last:function(g,i,n,m){return i===m.length-1},even:function(g,i){return i%2===0},odd:function(g,i){return i%2===1},lt:function(g,i,n){return in[3]-0},nth:function(g,i,n){return n[3]- 92 | 0===i},eq:function(g,i,n){return n[3]-0===i}},filter:{PSEUDO:function(g,i,n,m){var p=i[1],q=o.filters[p];if(q)return q(g,n,i,m);else if(p==="contains")return(g.textContent||g.innerText||k.getText([g])||"").indexOf(i[3])>=0;else if(p==="not"){i=i[3];n=0;for(m=i.length;n=0}},ID:function(g,i){return g.nodeType===1&&g.getAttribute("id")===i},TAG:function(g,i){return i==="*"&&g.nodeType===1||g.nodeName.toLowerCase()=== 94 | i},CLASS:function(g,i){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(i)>-1},ATTR:function(g,i){var n=i[1];n=o.attrHandle[n]?o.attrHandle[n](g):g[n]!=null?g[n]:g.getAttribute(n);var m=n+"",p=i[2],q=i[4];return n==null?p==="!=":p==="="?m===q:p==="*="?m.indexOf(q)>=0:p==="~="?(" "+m+" ").indexOf(q)>=0:!q?m&&n!==false:p==="!="?m!==q:p==="^="?m.indexOf(q)===0:p==="$="?m.substr(m.length-q.length)===q:p==="|="?m===q||m.substr(0,q.length+1)===q+"-":false},POS:function(g,i,n,m){var p=o.setFilters[i[2]]; 95 | if(p)return p(g,n,i,m)}}},x=o.match.POS,r=function(g,i){return"\\"+(i-0+1)},A;for(A in o.match){o.match[A]=RegExp(o.match[A].source+/(?![^\[]*\])(?![^\(]*\))/.source);o.leftMatch[A]=RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[A].source.replace(/\\(\d+)/g,r))}var C=function(g,i){g=Array.prototype.slice.call(g,0);if(i){i.push.apply(i,g);return i}return g};try{Array.prototype.slice.call(t.documentElement.childNodes,0)}catch(J){C=function(g,i){var n=0,m=i||[];if(f.call(g)==="[object Array]")Array.prototype.push.apply(m, 96 | g);else if(typeof g.length==="number")for(var p=g.length;n";n.insertBefore(g,n.firstChild);if(t.getElementById(i)){o.find.ID=function(m,p,q){if(typeof p.getElementById!=="undefined"&&!q)return(p=p.getElementById(m[1]))?p.id===m[1]||typeof p.getAttributeNode!=="undefined"&&p.getAttributeNode("id").nodeValue===m[1]?[p]:B:[]};o.filter.ID=function(m,p){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===p}}n.removeChild(g); 99 | n=g=null})();(function(){var g=t.createElement("div");g.appendChild(t.createComment(""));if(g.getElementsByTagName("*").length>0)o.find.TAG=function(i,n){var m=n.getElementsByTagName(i[1]);if(i[1]==="*"){for(var p=[],q=0;m[q];q++)m[q].nodeType===1&&p.push(m[q]);m=p}return m};g.innerHTML="";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")o.attrHandle.href=function(i){return i.getAttribute("href",2)};g=null})();t.querySelectorAll&& 100 | function(){var g=k,i=t.createElement("div");i.innerHTML="

";if(!(i.querySelectorAll&&i.querySelectorAll(".TEST").length===0)){k=function(m,p,q,u){p=p||t;m=m.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!u&&!k.isXML(p))if(p.nodeType===9)try{return C(p.querySelectorAll(m),q)}catch(y){}else if(p.nodeType===1&&p.nodeName.toLowerCase()!=="object"){var F=p.getAttribute("id"),M=F||"__sizzle__";F||p.setAttribute("id",M);try{return C(p.querySelectorAll("#"+M+" "+m),q)}catch(N){}finally{F|| 101 | p.removeAttribute("id")}}return g(m,p,q,u)};for(var n in g)k[n]=g[n];i=null}}();(function(){var g=t.documentElement,i=g.matchesSelector||g.mozMatchesSelector||g.webkitMatchesSelector||g.msMatchesSelector,n=false;try{i.call(t.documentElement,"[test!='']:sizzle")}catch(m){n=true}if(i)k.matchesSelector=function(p,q){q=q.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(p))try{if(n||!o.match.PSEUDO.test(q)&&!/!=/.test(q))return i.call(p,q)}catch(u){}return k(q,null,null,[p]).length>0}})();(function(){var g= 102 | t.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){o.order.splice(1,0,"CLASS");o.find.CLASS=function(i,n,m){if(typeof n.getElementsByClassName!=="undefined"&&!m)return n.getElementsByClassName(i[1])};g=null}}})();k.contains=t.documentElement.contains?function(g,i){return g!==i&&(g.contains?g.contains(i):true)}:t.documentElement.compareDocumentPosition? 103 | function(g,i){return!!(g.compareDocumentPosition(i)&16)}:function(){return false};k.isXML=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false};var L=function(g,i){for(var n,m=[],p="",q=i.nodeType?[i]:i;n=o.match.PSEUDO.exec(g);){p+=n[0];g=g.replace(o.match.PSEUDO,"")}g=o.relative[g]?g+"*":g;n=0;for(var u=q.length;n0)for(var h=d;h0},closest:function(a,b){var d=[],e,f,h=this[0];if(c.isArray(a)){var l,k={},o=1;if(h&&a.length){e=0;for(f=a.length;e-1:c(h).is(e))d.push({selector:l,elem:h,level:o})}h= 106 | h.parentNode;o++}}return d}l=cb.test(a)?c(a,b||this.context):null;e=0;for(f=this.length;e-1:c.find.matchesSelector(h,a)){d.push(h);break}else{h=h.parentNode;if(!h||!h.ownerDocument||h===b)break}d=d.length>1?c.unique(d):d;return this.pushStack(d,"closest",a)},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var d=typeof a==="string"?c(a,b||this.context): 107 | c.makeArray(a),e=c.merge(this.get(),d);return this.pushStack(!d[0]||!d[0].parentNode||d[0].parentNode.nodeType===11||!e[0]||!e[0].parentNode||e[0].parentNode.nodeType===11?e:c.unique(e))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a, 108 | 2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a, 109 | b){c.fn[a]=function(d,e){var f=c.map(this,b,d);Za.test(a)||(e=d);if(e&&typeof e==="string")f=c.filter(e,f);f=this.length>1?c.unique(f):f;if((this.length>1||ab.test(e))&&$a.test(a))f=f.reverse();return this.pushStack(f,a,bb.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return b.length===1?c.find.matchesSelector(b[0],a)?[b[0]]:[]:c.find.matches(a,b)},dir:function(a,b,d){var e=[];for(a=a[b];a&&a.nodeType!==9&&(d===B||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&& 110 | e.push(a);a=a[b]}return e},nth:function(a,b,d){b=b||1;for(var e=0;a;a=a[d])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var za=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,Aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Ba=/<([\w:]+)/,db=/\s]+\/)>/g,P={option:[1, 111 | ""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};P.optgroup=P.option;P.tbody=P.tfoot=P.colgroup=P.caption=P.thead;P.th=P.td;if(!c.support.htmlSerialize)P._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= 112 | c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==B)return this.empty().append((this[0]&&this[0].ownerDocument||t).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, 113 | wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, 114 | prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, 115 | this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,e;(e=this[d])!=null;d++)if(!a||c.filter(a,[e]).length){if(!b&&e.nodeType===1){c.cleanData(e.getElementsByTagName("*"));c.cleanData([e])}e.parentNode&&e.parentNode.removeChild(e)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); 116 | return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,e=this.ownerDocument;if(!d){d=e.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(za,"").replace(fb,'="$1">').replace($,"")],e)[0]}else return this.cloneNode(true)});if(a===true){na(this,b);na(this.find("*"),b.find("*"))}return b},html:function(a){if(a===B)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(za,""):null; 117 | else if(typeof a==="string"&&!Ca.test(a)&&(c.support.leadingWhitespace||!$.test(a))&&!P[(Ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Aa,"<$1>");try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?h.cloneNode(true):h)}k.length&&c.each(k,Oa)}return this}});c.buildFragment=function(a,b,d){var e,f,h;b=b&&b[0]?b[0].ownerDocument||b[0]:t;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===t&&!Ca.test(a[0])&&(c.support.checkClone||!Da.test(a[0]))){f=true;if(h=c.fragments[a[0]])if(h!==1)e=h}if(!e){e=b.createDocumentFragment();c.clean(a,b,e,d)}if(f)c.fragments[a[0]]=h?e:1;return{fragment:e,cacheable:f}};c.fragments={};c.each({appendTo:"append", 121 | prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var e=[];d=c(d);var f=this.length===1&&this[0].parentNode;if(f&&f.nodeType===11&&f.childNodes.length===1&&d.length===1){d[b](this[0]);return this}else{f=0;for(var h=d.length;f0?this.clone(true):this).get();c(d[f])[b](l);e=e.concat(l)}return this.pushStack(e,a,d.selector)}}});c.extend({clean:function(a,b,d,e){b=b||t;if(typeof b.createElement==="undefined")b=b.ownerDocument|| 122 | b[0]&&b[0].ownerDocument||t;for(var f=[],h=0,l;(l=a[h])!=null;h++){if(typeof l==="number")l+="";if(l){if(typeof l==="string"&&!eb.test(l))l=b.createTextNode(l);else if(typeof l==="string"){l=l.replace(Aa,"<$1>");var k=(Ba.exec(l)||["",""])[1].toLowerCase(),o=P[k]||P._default,x=o[0],r=b.createElement("div");for(r.innerHTML=o[1]+l+o[2];x--;)r=r.lastChild;if(!c.support.tbody){x=db.test(l);k=k==="table"&&!x?r.firstChild&&r.firstChild.childNodes:o[1]===""&&!x?r.childNodes:[];for(o=k.length- 123 | 1;o>=0;--o)c.nodeName(k[o],"tbody")&&!k[o].childNodes.length&&k[o].parentNode.removeChild(k[o])}!c.support.leadingWhitespace&&$.test(l)&&r.insertBefore(b.createTextNode($.exec(l)[0]),r.firstChild);l=r.childNodes}if(l.nodeType)f.push(l);else f=c.merge(f,l)}}if(d)for(h=0;f[h];h++)if(e&&c.nodeName(f[h],"script")&&(!f[h].type||f[h].type.toLowerCase()==="text/javascript"))e.push(f[h].parentNode?f[h].parentNode.removeChild(f[h]):f[h]);else{f[h].nodeType===1&&f.splice.apply(f,[h+1,0].concat(c.makeArray(f[h].getElementsByTagName("script")))); 124 | d.appendChild(f[h])}return f},cleanData:function(a){for(var b,d,e=c.cache,f=c.event.special,h=c.support.deleteExpando,l=0,k;(k=a[l])!=null;l++)if(!(k.nodeName&&c.noData[k.nodeName.toLowerCase()]))if(d=k[c.expando]){if((b=e[d])&&b.events)for(var o in b.events)f[o]?c.event.remove(k,o):c.removeEvent(k,o,b.handle);if(h)delete k[c.expando];else k.removeAttribute&&k.removeAttribute(c.expando);delete e[d]}}});var Ea=/alpha\([^)]*\)/i,gb=/opacity=([^)]*)/,hb=/-([a-z])/ig,ib=/([A-Z])/g,Fa=/^-?\d+(?:px)?$/i, 125 | jb=/^-?\d/,kb={position:"absolute",visibility:"hidden",display:"block"},Pa=["Left","Right"],Qa=["Top","Bottom"],W,Ga,aa,lb=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){if(arguments.length===2&&b===B)return this;return c.access(this,a,b,true,function(d,e,f){return f!==B?c.style(d,e,f):c.css(d,e)})};c.extend({cssHooks:{opacity:{get:function(a,b){if(b){var d=W(a,"opacity","opacity");return d===""?"1":d}else return a.style.opacity}}},cssNumber:{zIndex:true,fontWeight:true,opacity:true, 126 | zoom:true,lineHeight:true},cssProps:{"float":c.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,d,e){if(!(!a||a.nodeType===3||a.nodeType===8||!a.style)){var f,h=c.camelCase(b),l=a.style,k=c.cssHooks[h];b=c.cssProps[h]||h;if(d!==B){if(!(typeof d==="number"&&isNaN(d)||d==null)){if(typeof d==="number"&&!c.cssNumber[h])d+="px";if(!k||!("set"in k)||(d=k.set(a,d))!==B)try{l[b]=d}catch(o){}}}else{if(k&&"get"in k&&(f=k.get(a,false,e))!==B)return f;return l[b]}}},css:function(a,b,d){var e,f=c.camelCase(b), 127 | h=c.cssHooks[f];b=c.cssProps[f]||f;if(h&&"get"in h&&(e=h.get(a,true,d))!==B)return e;else if(W)return W(a,b,f)},swap:function(a,b,d){var e={},f;for(f in b){e[f]=a.style[f];a.style[f]=b[f]}d.call(a);for(f in b)a.style[f]=e[f]},camelCase:function(a){return a.replace(hb,lb)}});c.curCSS=c.css;c.each(["height","width"],function(a,b){c.cssHooks[b]={get:function(d,e,f){var h;if(e){if(d.offsetWidth!==0)h=oa(d,b,f);else c.swap(d,kb,function(){h=oa(d,b,f)});if(h<=0){h=W(d,b,b);if(h==="0px"&&aa)h=aa(d,b,b); 128 | if(h!=null)return h===""||h==="auto"?"0px":h}if(h<0||h==null){h=d.style[b];return h===""||h==="auto"?"0px":h}return typeof h==="string"?h:h+"px"}},set:function(d,e){if(Fa.test(e)){e=parseFloat(e);if(e>=0)return e+"px"}else return e}}});if(!c.support.opacity)c.cssHooks.opacity={get:function(a,b){return gb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var d=a.style;d.zoom=1;var e=c.isNaN(b)?"":"alpha(opacity="+b*100+")",f= 129 | d.filter||"";d.filter=Ea.test(f)?f.replace(Ea,e):d.filter+" "+e}};if(t.defaultView&&t.defaultView.getComputedStyle)Ga=function(a,b,d){var e;d=d.replace(ib,"-$1").toLowerCase();if(!(b=a.ownerDocument.defaultView))return B;if(b=b.getComputedStyle(a,null)){e=b.getPropertyValue(d);if(e===""&&!c.contains(a.ownerDocument.documentElement,a))e=c.style(a,d)}return e};if(t.documentElement.currentStyle)aa=function(a,b){var d,e,f=a.currentStyle&&a.currentStyle[b],h=a.style;if(!Fa.test(f)&&jb.test(f)){d=h.left; 130 | e=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;h.left=b==="fontSize"?"1em":f||0;f=h.pixelLeft+"px";h.left=d;a.runtimeStyle.left=e}return f===""?"auto":f};W=Ga||aa;if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetHeight;return a.offsetWidth===0&&b===0||!c.support.reliableHiddenOffsets&&(a.style.display||c.css(a,"display"))==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var mb=c.now(),nb=/)<[^<]*)*<\/script>/gi, 131 | ob=/^(?:select|textarea)/i,pb=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,qb=/^(?:GET|HEAD)$/,Ra=/\[\]$/,T=/\=\?(&|$)/,ja=/\?/,rb=/([?&])_=[^&]*/,sb=/^(\w+:)?\/\/([^\/?#]+)/,tb=/%20/g,ub=/#.*$/,Ha=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!=="string"&&Ha)return Ha.apply(this,arguments);else if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var f=a.slice(e,a.length);a=a.slice(0,e)}e="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b=== 132 | "object"){b=c.param(b,c.ajaxSettings.traditional);e="POST"}var h=this;c.ajax({url:a,type:e,dataType:"html",data:b,complete:function(l,k){if(k==="success"||k==="notmodified")h.html(f?c("
").append(l.responseText.replace(nb,"")).find(f):l.responseText);d&&h.each(d,[l.responseText,k,l])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&& 133 | !this.disabled&&(this.checked||ob.test(this.nodeName)||pb.test(this.type))}).map(function(a,b){var d=c(this).val();return d==null?null:c.isArray(d)?c.map(d,function(e){return{name:b.name,value:e}}):{name:b.name,value:d}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:e})}, 134 | getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:e})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return new E.XMLHttpRequest},accepts:{xml:"application/xml, text/xml",html:"text/html", 135 | script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},ajax:function(a){var b=c.extend(true,{},c.ajaxSettings,a),d,e,f,h=b.type.toUpperCase(),l=qb.test(h);b.url=b.url.replace(ub,"");b.context=a&&a.context!=null?a.context:b;if(b.data&&b.processData&&typeof b.data!=="string")b.data=c.param(b.data,b.traditional);if(b.dataType==="jsonp"){if(h==="GET")T.test(b.url)||(b.url+=(ja.test(b.url)?"&":"?")+(b.jsonp||"callback")+"=?");else if(!b.data|| 136 | !T.test(b.data))b.data=(b.data?b.data+"&":"")+(b.jsonp||"callback")+"=?";b.dataType="json"}if(b.dataType==="json"&&(b.data&&T.test(b.data)||T.test(b.url))){d=b.jsonpCallback||"jsonp"+mb++;if(b.data)b.data=(b.data+"").replace(T,"="+d+"$1");b.url=b.url.replace(T,"="+d+"$1");b.dataType="script";var k=E[d];E[d]=function(m){if(c.isFunction(k))k(m);else{E[d]=B;try{delete E[d]}catch(p){}}f=m;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);r&&r.removeChild(A)}}if(b.dataType==="script"&&b.cache===null)b.cache= 137 | false;if(b.cache===false&&l){var o=c.now(),x=b.url.replace(rb,"$1_="+o);b.url=x+(x===b.url?(ja.test(b.url)?"&":"?")+"_="+o:"")}if(b.data&&l)b.url+=(ja.test(b.url)?"&":"?")+b.data;b.global&&c.active++===0&&c.event.trigger("ajaxStart");o=(o=sb.exec(b.url))&&(o[1]&&o[1].toLowerCase()!==location.protocol||o[2].toLowerCase()!==location.host);if(b.dataType==="script"&&h==="GET"&&o){var r=t.getElementsByTagName("head")[0]||t.documentElement,A=t.createElement("script");if(b.scriptCharset)A.charset=b.scriptCharset; 138 | A.src=b.url;if(!d){var C=false;A.onload=A.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);A.onload=A.onreadystatechange=null;r&&A.parentNode&&r.removeChild(A)}}}r.insertBefore(A,r.firstChild);return B}var J=false,w=b.xhr();if(w){b.username?w.open(h,b.url,b.async,b.username,b.password):w.open(h,b.url,b.async);try{if(b.data!=null&&!l||a&&a.contentType)w.setRequestHeader("Content-Type", 139 | b.contentType);if(b.ifModified){c.lastModified[b.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[b.url]);c.etag[b.url]&&w.setRequestHeader("If-None-Match",c.etag[b.url])}o||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",b.dataType&&b.accepts[b.dataType]?b.accepts[b.dataType]+", */*; q=0.01":b.accepts._default)}catch(I){}if(b.beforeSend&&b.beforeSend.call(b.context,w,b)===false){b.global&&c.active--===1&&c.event.trigger("ajaxStop");w.abort();return false}b.global&& 140 | c.triggerGlobal(b,"ajaxSend",[w,b]);var L=w.onreadystatechange=function(m){if(!w||w.readyState===0||m==="abort"){J||c.handleComplete(b,w,e,f);J=true;if(w)w.onreadystatechange=c.noop}else if(!J&&w&&(w.readyState===4||m==="timeout")){J=true;w.onreadystatechange=c.noop;e=m==="timeout"?"timeout":!c.httpSuccess(w)?"error":b.ifModified&&c.httpNotModified(w,b.url)?"notmodified":"success";var p;if(e==="success")try{f=c.httpData(w,b.dataType,b)}catch(q){e="parsererror";p=q}if(e==="success"||e==="notmodified")d|| 141 | c.handleSuccess(b,w,e,f);else c.handleError(b,w,e,p);d||c.handleComplete(b,w,e,f);m==="timeout"&&w.abort();if(b.async)w=null}};try{var g=w.abort;w.abort=function(){w&&Function.prototype.call.call(g,w);L("abort")}}catch(i){}b.async&&b.timeout>0&&setTimeout(function(){w&&!J&&L("timeout")},b.timeout);try{w.send(l||b.data==null?null:b.data)}catch(n){c.handleError(b,w,null,n);c.handleComplete(b,w,e,f)}b.async||L();return w}},param:function(a,b){var d=[],e=function(h,l){l=c.isFunction(l)?l():l;d[d.length]= 142 | encodeURIComponent(h)+"="+encodeURIComponent(l)};if(b===B)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){e(this.name,this.value)});else for(var f in a)da(f,a[f],b,e);return d.join("&").replace(tb,"+")}});c.extend({active:0,lastModified:{},etag:{},handleError:function(a,b,d,e){a.error&&a.error.call(a.context,b,d,e);a.global&&c.triggerGlobal(a,"ajaxError",[b,a,e])},handleSuccess:function(a,b,d,e){a.success&&a.success.call(a.context,e,d,b);a.global&&c.triggerGlobal(a,"ajaxSuccess", 143 | [b,a])},handleComplete:function(a,b,d){a.complete&&a.complete.call(a.context,b,d);a.global&&c.triggerGlobal(a,"ajaxComplete",[b,a]);a.global&&c.active--===1&&c.event.trigger("ajaxStop")},triggerGlobal:function(a,b,d){(a.context&&a.context.url==null?c(a.context):c.event).trigger(b,d)},httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"), 144 | e=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(e)c.etag[b]=e;return a.status===304},httpData:function(a,b,d){var e=a.getResponseHeader("content-type")||"",f=b==="xml"||!b&&e.indexOf("xml")>=0;a=f?a.responseXML:a.responseText;f&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&e.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&e.indexOf("javascript")>=0)c.globalEval(a);return a}}); 145 | if(E.ActiveXObject)c.ajaxSettings.xhr=function(){if(E.location.protocol!=="file:")try{return new E.XMLHttpRequest}catch(a){}try{return new E.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}};c.support.ajax=!!c.ajaxSettings.xhr();var ea={},vb=/^(?:toggle|show|hide)$/,wb=/^([+\-]=)?([\d+.\-]+)(.*)$/,ba,pa=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b,d){if(a||a===0)return this.animate(S("show", 146 | 3),a,b,d);else{d=0;for(var e=this.length;d=0;e--)if(d[e].elem===this){b&&d[e](true);d.splice(e,1)}});b||this.dequeue();return this}});c.each({slideDown:S("show",1),slideUp:S("hide",1),slideToggle:S("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){c.fn[a]=function(d,e,f){return this.animate(b, 151 | d,e,f)}});c.extend({speed:function(a,b,d){var e=a&&typeof a==="object"?c.extend({},a):{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};e.duration=c.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in c.fx.speeds?c.fx.speeds[e.duration]:c.fx.speeds._default;e.old=e.complete;e.complete=function(){e.queue!==false&&c(this).dequeue();c.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,d,e){return d+e*a},swing:function(a,b,d,e){return(-Math.cos(a* 152 | Math.PI)/2+0.5)*e+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a=parseFloat(c.css(this.elem,this.prop));return a&&a>-1E4?a:0},custom:function(a,b,d){function e(l){return f.step(l)} 153 | var f=this,h=c.fx;this.startTime=c.now();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;e.elem=this.elem;if(e()&&c.timers.push(e)&&!ba)ba=setInterval(h.tick,h.interval)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true; 154 | this.custom(this.cur(),0)},step:function(a){var b=c.now(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var e in this.options.curAnim)if(this.options.curAnim[e]!==true)d=false;if(d){if(this.options.overflow!=null&&!c.support.shrinkWrapBlocks){var f=this.elem,h=this.options;c.each(["","X","Y"],function(k,o){f.style["overflow"+o]=h.overflow[k]})}this.options.hide&&c(this.elem).hide();if(this.options.hide|| 155 | this.options.show)for(var l in this.options.curAnim)c.style(this.elem,l,this.options.orig[l]);this.options.complete.call(this.elem)}return false}else{a=b-this.startTime;this.state=a/this.options.duration;b=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||b](this.state,a,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a= 156 | c.timers,b=0;b-1;e={};var x={};if(o)x=f.position();l=o?x.top:parseInt(l,10)||0;k=o?x.left:parseInt(k,10)||0;if(c.isFunction(b))b=b.call(a,d,h);if(b.top!=null)e.top=b.top-h.top+l;if(b.left!=null)e.left=b.left-h.left+k;"using"in b?b.using.call(a, 164 | e):f.css(e)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),e=Ia.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.css(a,"marginTop"))||0;d.left-=parseFloat(c.css(a,"marginLeft"))||0;e.top+=parseFloat(c.css(b[0],"borderTopWidth"))||0;e.left+=parseFloat(c.css(b[0],"borderLeftWidth"))||0;return{top:d.top-e.top,left:d.left-e.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||t.body;a&&!Ia.test(a.nodeName)&& 165 | c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(e){var f=this[0],h;if(!f)return null;if(e!==B)return this.each(function(){if(h=fa(this))h.scrollTo(!a?e:c(h).scrollLeft(),a?e:c(h).scrollTop());else this[d]=e});else return(h=fa(f))?"pageXOffset"in h?h[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&h.document.documentElement[d]||h.document.body[d]:f[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase(); 166 | c.fn["inner"+b]=function(){return this[0]?parseFloat(c.css(this[0],d,"padding")):null};c.fn["outer"+b]=function(e){return this[0]?parseFloat(c.css(this[0],d,e?"margin":"border")):null};c.fn[d]=function(e){var f=this[0];if(!f)return e==null?null:this;if(c.isFunction(e))return this.each(function(l){var k=c(this);k[d](e.call(this,l,k[d]()))});if(c.isWindow(f))return f.document.compatMode==="CSS1Compat"&&f.document.documentElement["client"+b]||f.document.body["client"+b];else if(f.nodeType===9)return Math.max(f.documentElement["client"+ 167 | b],f.body["scroll"+b],f.documentElement["scroll"+b],f.body["offset"+b],f.documentElement["offset"+b]);else if(e===B){f=c.css(f,d);var h=parseFloat(f);return c.isNaN(h)?f:h}else return this.css(d,typeof e==="string"?e:e+"px")}})})(window); 168 | --------------------------------------------------------------------------------