Implement the WKUIDelegate method that is reached when JavaScript in a web view invokes window.open(). This ensures that attempts to open links from code, such as from the YouTube embedded video player, work as expected. Fixes #3088.

This commit is contained in:
Maurice Parker 2021-07-29 16:48:42 -05:00
parent d3f932919f
commit b3773ad01b
1 changed files with 25 additions and 11 deletions

View File

@ -344,16 +344,7 @@ extension WebViewController: WKNavigationDelegate {
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
if components?.scheme == "http" || components?.scheme == "https" {
decisionHandler(.cancel)
// If the resource cannot be opened with an installed app, present the web view.
UIApplication.shared.open(url, options: [.universalLinksOnly: true]) { didOpen in
assert(Thread.isMainThread)
guard didOpen == false else {
return
}
let vc = SFSafariViewController(url: url)
self.present(vc, animated: true)
}
openURL(url)
} else if components?.scheme == "mailto" {
decisionHandler(.cancel)
@ -392,12 +383,23 @@ extension WebViewController: WKNavigationDelegate {
// MARK: WKUIDelegate
extension WebViewController: WKUIDelegate {
func webView(_ webView: WKWebView, contextMenuForElement elementInfo: WKContextMenuElementInfo, willCommitWithAnimator animator: UIContextMenuInteractionCommitAnimating) {
// We need to have at least an unimplemented WKUIDelegate assigned to the WKWebView. This makes the
// link preview launch Safari when the link preview is tapped. In theory, you shoud be able to get
// the link from the elementInfo above and transition to SFSafariViewController instead of launching
// Safari. As the time of this writing, the link in elementInfo is always nil. ¯\_()_/¯
}
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
guard let url = navigationAction.request.url else {
return nil
}
openURL(url)
return nil
}
}
// MARK: WKScriptMessageHandler
@ -745,7 +747,19 @@ private extension WebViewController {
self?.showActivityDialog()
}
}
// If the resource cannot be opened with an installed app, present the web view.
func openURL(_ url: URL) {
UIApplication.shared.open(url, options: [.universalLinksOnly: true]) { didOpen in
assert(Thread.isMainThread)
guard didOpen == false else {
return
}
let vc = SFSafariViewController(url: url)
self.present(vc, animated: true)
}
}
}
// MARK: Find in Article