diff --git a/Reader/Screens/Read/ReadViewController.swift b/Reader/Screens/Read/ReadViewController.swift index e5a1edd..3945e18 100644 --- a/Reader/Screens/Read/ReadViewController.swift +++ b/Reader/Screens/Read/ReadViewController.swift @@ -8,6 +8,7 @@ import UIKit import WebKit import HTMLEntities +import SafariServices class ReadViewController: UIViewController { @@ -50,6 +51,7 @@ class ReadViewController: UIViewController { let webView = WKWebView() webView.translatesAutoresizingMaskIntoConstraints = false webView.navigationDelegate = self + webView.uiDelegate = self if let content = itemContentHTML() { // todo: using the bundle url is the only way to get the stylesheet to load, but feels wrong // will break, e.g., images with relative urls @@ -119,7 +121,40 @@ extension ReadViewController: WKNavigationDelegate { let url = navigationAction.request.url! if url == Bundle.main.bundleURL { return .allow + } else { + present(SFSafariViewController(url: url), animated: true) + return .cancel + } + } +} + +extension ReadViewController: WKUIDelegate { + func webView(_ webView: WKWebView, contextMenuConfigurationFor elementInfo: WKContextMenuElementInfo) async -> UIContextMenuConfiguration? { + guard let url = elementInfo.linkURL, + ["http", "https"].contains(url.scheme?.lowercased()) else { + return nil + } + return UIContextMenuConfiguration(identifier: nil) { + SFSafariViewController(url: url) + } actionProvider: { _ in + return UIMenu(children: [ + UIAction(title: "Open in Safari", image: UIImage(systemName: "safari"), handler: { [weak self] _ in + self?.present(SFSafariViewController(url: url), animated: true) + }), + UIAction(title: "Share", image: UIImage(systemName: "square.and.arrow.up"), handler: { [weak self] _ in + self?.present(UIActivityViewController(activityItems: [url], applicationActivities: nil), animated: true) + }), + ]) + } + + } + + func webView(_ webView: WKWebView, contextMenuForElement elementInfo: WKContextMenuElementInfo, willCommitWithAnimator animator: UIContextMenuInteractionCommitAnimating) { + if let vc = animator.previewViewController as? SFSafariViewController { + animator.preferredCommitStyle = .pop + animator.addCompletion { + self.present(vc, animated: true) + } } - return .cancel } }