On windows, when the \"Shell.Explorer\" ActiveX control is embedded in an application it is possible to register an \"external\" handler - on object that implements IDispatc
This is very easy to do with the WebScriptObject API in combination with the JavaScriptCore framework.
You need to implement the various WebScripting protocol methods. Here is a basic example:
@interface WebController : NSObject
{
IBOutlet WebView* webView;
}
@end
@implementation WebController
//this returns a nice name for the method in the JavaScript environment
+(NSString*)webScriptNameForSelector:(SEL)sel
{
if(sel == @selector(logJavaScriptString:))
return @"log";
return nil;
}
//this allows JavaScript to call the -logJavaScriptString: method
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)sel
{
if(sel == @selector(logJavaScriptString:))
return NO;
return YES;
}
//called when the nib objects are available, so do initial setup
- (void)awakeFromNib
{
//set this class as the web view's frame load delegate
//we will then be notified when the scripting environment
//becomes available in the page
[webView setFrameLoadDelegate:self];
//load a file called 'page.html' from the app bundle into the WebView
NSString* pagePath = [[NSBundle mainBundle] pathForResource:@"page" ofType:@"html"];
NSURL* pageURL = [NSURL fileURLWithPath:pagePath];
[[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:pageURL]];
}
//this is a simple log command
- (void)logJavaScriptString:(NSString*) logText
{
NSLog(@"JavaScript: %@",logText);
}
//this is called as soon as the script environment is ready in the webview
- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)windowScriptObject forFrame:(WebFrame *)frame
{
//add the controller to the script environment
//the "Cocoa" object will now be available to JavaScript
[windowScriptObject setValue:self forKey:@"Cocoa"];
}
@end
After implementing this code in your controller, you can now call Cocoa.log('foo');
from the JavaScript environment and the logJavaScriptString:
method will be called.