Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cocoa/WebKit, having "window.open()" JavaScript links opening in an instance of Safari

I am building a really basic Cocoa application using WebKit, to display a Flash/Silverlight application within it. Very basic, no intentions for it to be a browser itself.

So far I have been able to get it to open basic html links (<a href="..." />) in a new instance of Safari using

[[NSWorkspace sharedWorkspace] openURL:[request URL]];

Now my difficulty is opening a link in a new instance of Safari when window.open() is used in JavaScript. I "think" (and by this, I have been hacking away at the code and am unsure if i actually did or not) I got this kind of working by setting the WebView's policyDelegate and implementing its

-webView:decidePolicyForNavigationAction:request:frame:decisionListener:

delegate method. However this led to some erratic behavior.

So the simple question, what do I need to do so that when window.open() is called, the link is opened in a new instance of Safari.

Thanks

Big point, I am normally a .NET developer, and have only been working with Cocoa/WebKit for a few days.

like image 525
FireWire Avatar asked Nov 06 '08 21:11

FireWire


2 Answers

I made from progress last night and pinned down part of my problem.

I am already using webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener: and I have gotten it to work with anchor tags, however the method never seems to get called when JavaScript is invoked.

However when window.open() is called webView:createWebViewWithRequest:request is called, I have tried to force the window to open in Safari here, however request is always null. So I can never read the URL out.

I have done some searching around, and this seems to be a known "misfeature" however I have not been able to find a way to work around it.

From what I understand createWebViewWithRequest gives you the ability to create the new webview, the the requested url is then sent to the new webView to be loaded. This is the best explanation I have been able to find so far.

So while many people have pointed out this problem, I have yet to see any solution which fits my needs. I will try to delve a little deeper into the decidePolicyForNewWindowAction again.

Thanks!

like image 194
FireWire Avatar answered Oct 06 '22 01:10

FireWire


Well, I'm handling it by creating a dummy webView, setting it's frameLoad delegate to a custom class that handles

- (void)webView:decidePolicyForNavigationAction:actionInformation :request:frame:decisionListener:

and opens a new window there.

code :

- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request {
    //this is a hack because request URL is null here due to a bug in webkit        
    return [newWindowHandler webView];
}

and NewWindowHandler :

@implementation NewWindowHandler

-(NewWindowHandler*)initWithWebView:(WebView*)newWebView {
    webView = newWebView;

    [webView setUIDelegate:self];
    [webView setPolicyDelegate:self];  
    [webView setResourceLoadDelegate:self];

    return self;
}

- (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener {
    [[NSWorkspace sharedWorkspace] openURL:[actionInformation objectForKey:WebActionOriginalURLKey]];
}

-(WebView*)webView {
    return webView;
}
like image 31
Yoni Shalom Avatar answered Oct 05 '22 23:10

Yoni Shalom