Re: Intercepting JavaScript calls in WebViews
Re: Intercepting JavaScript calls in WebViews
- Subject: Re: Intercepting JavaScript calls in WebViews
- From: Patrick Machielse <email@hidden>
- Date: Mon, 05 Jan 2004 12:32:11 +0100
op 05-01-2004 02:09 schreef Mark op email@hidden:
>
On Dec 14, 2003, at 14:55, Patrick Machielse wrote:
>
>
> I'm working on a project using a WebView. The html that is displayed
>
> contains JavaSctipt links like:
>
>
>
> <a href="javascript:function(parameter);">click me</a>
>
>
>
> When the user clicks on a link, I must intercept the JavaScript
>
> function call (which is implemented as an empty function in the html)
>
> and do something intelligent with the function parameter.
>
I have the same requirement and would be interested if you discover the
>
right way to capture javascript calls. When working in the Windows (Internet
>
Explorer) world there can be a call to
>
windows.external.myExternalFunction(any_number_of_parameters) which I have
>
used successfully. I am currently searching for a similar mechanism for a
>
development project I have for MAC.
I didn't find a good solution. My project is 'in the fridge' at the moment,
but I finally used the following technique:
In the main controller:
- (void)awakeFromNib
{
[NSURLProtocol registerClass:[MyURLProtocol class]];
// register for html loading completion
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self
selector:@selector ( modifySource: )
name:WebViewProgressFinishedNotification
object:nil];
}
- (void)modifySource:(NSNotification *)notification
{
NSString *source = [[[[webView mainFrame] dataSource] representation]
documentSource];
if ( [source rangeOfString:@"function("].location != NSNotFound ) {
// replace all occurences of @"javascript:function(parameter)"
// with @"myScheme://parameter"
// and load source in webView
}
}
Here the controller gets notified after the html was loaded, replaces the
javascript with a custom URL scheme and reloads the modified html if needed.
Then make MyURLProtocol like so:
@implementation MyURLProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
NSString *scheme = [[request URL] scheme];
if ( [scheme isEqualToString:@"myScheme"] )
return YES;
else
return NO;
}
- (void)startLoading
{
NSString *parameter = [[[self request] URL] path];
// do your custom action...
}
// add other required methods...
@end
This is quite 'easy' and does what it is supposed to, but won't work if the
user clicks on a 'javascript' link before loading of the page is complete
and the controler hasn't replaced the js calls yet.
I also tried replacing the js code while the html is retreived, but then you
have to register a URLProtocol for the html scheme. The problem here is that
you want to build on "NSHTMLProtocol", but you can't since it is private.
There may be a way around this, but I didn't investigate any further.
If you find a better way, I'm very interested...
Groeten,
Patrick
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.