From b3773ad01b8df39de8a96a25e59467cd7ecd8d29 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Thu, 29 Jul 2021 16:48:42 -0500 Subject: [PATCH] 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. --- iOS/Article/WebViewController.swift | 36 ++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/iOS/Article/WebViewController.swift b/iOS/Article/WebViewController.swift index c5b776126..fe6188903 100644 --- a/iOS/Article/WebViewController.swift +++ b/iOS/Article/WebViewController.swift @@ -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