Cocoa/WebKit,具有"window.open()"JavaScript链接在Safari实例中打开

Fir*_*ire 7 macos cocoa webkit objective-c

我正在使用WebKit构建一个非常基本的Cocoa应用程序,以在其中显示Flash/Silverlight应用程序.非常基本,没有意图成为浏览器本身.

到目前为止,我已经能够<a href="..." />在一个新的Safari实例中使用它来打开基本的html链接()

[[NSWorkspace sharedWorkspace] openURL:[request URL]];
Run Code Online (Sandbox Code Playgroud)

现在我的困难是window.open()在JavaScript中使用Safari的新实例中打开一个链接.我"思考"(并且由此,我一直在破解代码并且不确定我是否真的这样做了)我通过设置WebView policyDelegate并实现它来实现这种工作

-webView:decidePolicyForNavigationAction:request:frame:decisionListener:
Run Code Online (Sandbox Code Playgroud)

委托方法.然而,这导致了一些不稳定的行为.

所以简单的问题是,我需要做什么,以便在window.open()调用时,在新的Safari实例中打开链接.

谢谢

重点,我通常是.NET开发人员,并且只与Cocoa/WebKit合作了几天.

Fir*_*ire 9

我昨晚取得了进展,并将我的部分问题归结为一部分.

我已经在使用了webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:,我已经使用它来使用锚标记,但是当调用JavaScript时,似乎永远不会调用该方法.

但是当window.open()调用webView:createWebViewWithRequest:request被调用时,我试图强制窗口在Safari中打开,但请求始终为null.所以我永远无法读出网址.

我已经做了一些搜索,这似乎是一个已知的" 错误 ",但我还没有找到办法解决它.

根据我的理解createWebViewWithRequest,您可以创建新的webview,然后将请求的URL发送到要加载的新webView. 这是迄今为止我能找到的最佳解释.

因此,虽然很多人都指出了这个问题,但我还没有看到任何符合我需求的解决方案.我将尝试再深入研究decidePolicyForNewWindowAction一下.

谢谢!


Yon*_*lom 6

好吧,我正在通过创建一个虚拟webView来处理它,将它的frameLoad委托设置为一个处理的自定义类

- (void)webView:decidePolicyForNavigationAction:actionInformation :request:frame:decisionListener:
Run Code Online (Sandbox Code Playgroud)

并在那里打开一个新窗口.

代码:

- (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];
}
Run Code Online (Sandbox Code Playgroud)

和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;
}
Run Code Online (Sandbox Code Playgroud)


Lou*_*arg 2

您没有提到您看到了什么样的不稳定行为。一种快速的可能性是,在实现委托方法时,您忘记告诉 WebView 您通过调用传递给委托的WebPolicyDecisionListener的忽略方法来忽略单击,这可能会使事情陷入奇怪的状态。

如果这不是问题,那么您对所显示的内容有多少控制权?策略委托为您提供了简单的机制来过滤所有资源负载(正如您所发现的),并且所有新窗口都通过webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:打开。所有 window.open 调用都应该通过它,触发新窗口的任何其他调用也是如此。

如果您想保留应用程序中打开的其他窗口,您将需要做更多的工作。传递给委托的参数之一是包含有关事件信息的字典。在该字典中,WebActionElementKey 将有一个包含许多详细信息的字典,包括链接的原始 dom 内容。如果你想在那里查看,你可以抓取实际的 DOM 元素,并检查 href 的文本,看看它是否以 window.open 开头。这是一个有点重的重量,但如果你想要细粒度的控制,它会给你它。