@@ -37,18 +37,26 @@ @interface GAScriptEngine ()
3737 */
3838- (void )loadScriptRuntime ;
3939
40+ - (void )makeLotsaCalls ;
41+
42+ - (void )callReceiversForSelector : (SEL )theSelector withArguments : (NSArray *)arguments ;
43+
4044@end
4145
4246#pragma mark -
4347
4448@implementation GAScriptEngine
4549
50+ @synthesize receivers = m_receivers;
51+
4652- (id )initWithWebView : (UIWebView *)webView
4753{
4854 if ((self = [super init ]))
4955 {
5056 m_webView = [webView retain ];
5157 m_webView.delegate = self;
58+
59+ m_receivers = [[NSMutableArray alloc ] initWithCapacity: 4 ];
5260 }
5361
5462 return self;
@@ -57,6 +65,7 @@ - (id)initWithWebView:(UIWebView *)webView
5765- (void )dealloc
5866{
5967 [m_webView release ];
68+ [m_receivers release ];
6069
6170 [super dealloc ];
6271}
@@ -97,6 +106,51 @@ - (void)loadScriptRuntime
97106 [m_webView stringByEvaluatingJavaScriptFromString: scriptData];
98107}
99108
109+ - (void )makeLotsaCalls
110+ {
111+ id calls = [self scriptObjectWithReference: @" GAJavaScript.calls" ];
112+ NSNumber * numCalls = [calls valueForKey: @" length" ];
113+ calls = [calls callFunction: @" splice"
114+ withArguments: [NSArray arrayWithObjects: [NSNumber numberWithInt: 0 ], numCalls, nil ]];
115+
116+ for (NSInteger i = 0 ; i < [calls count ]; ++i)
117+ {
118+ id call = [calls objectAtIndex: i];
119+
120+ NSString * selName = [call valueForKey: @" sel" ];
121+ NSArray * arguments = [call valueForKey: @" args" ];
122+ SEL theSelector = NSSelectorFromString (selName);
123+
124+ [self callReceiversForSelector: theSelector withArguments: arguments];
125+ }
126+ }
127+
128+ - (void )callReceiversForSelector : (SEL )theSelector withArguments : (NSArray *)arguments
129+ {
130+ // The first argument is the selector name, so ignore it
131+ //
132+ arguments = [arguments subarrayWithRange: NSMakeRange (1 , [arguments count ] - 1 )];
133+
134+ for (id receiver in self.receivers )
135+ {
136+ if (![receiver respondsToSelector: theSelector])
137+ continue ;
138+
139+ NSMethodSignature * methodSig = [receiver methodSignatureForSelector: theSelector];
140+ NSInvocation * inv = [NSInvocation invocationWithMethodSignature: methodSig];
141+ NSInteger argIndex = 2 ;
142+
143+ for (id arg in arguments)
144+ [inv setArgument: &arg atIndex: argIndex++];
145+
146+ [inv setSelector: theSelector];
147+ [inv invokeWithTarget: receiver];
148+
149+ // Ignore return values...
150+ break ;
151+ }
152+ }
153+
100154#pragma mark UIWebViewDelegate
101155
102156- (void )webViewDidFinishLoad : (UIWebView *)webView
@@ -108,6 +162,19 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView
108162- (BOOL )webView : (UIWebView *)webView shouldStartLoadWithRequest : (NSURLRequest *)request
109163 navigationType : (UIWebViewNavigationType)navigationType
110164{
165+ NSURL * theUrl = [request URL ];
166+
167+ if ([[theUrl scheme ] isEqualToString: @" ga-js" ])
168+ {
169+ if ([[theUrl resourceSpecifier ] isEqualToString: @" makeLotsaCalls" ])
170+ {
171+ [self makeLotsaCalls ];
172+ }
173+
174+ return NO ;
175+ }
176+
177+ // TODO: Only YES for the inital HTML page
111178 return YES ;
112179}
113180
0 commit comments