// // ConditionsWebView.swift // SimpleX (iOS) // // Created by Stanislav Dmitrenko on 26.11.2024. // Copyright © 2024 SimpleX Chat. All rights reserved. // // Spec: spec/architecture.md import SwiftUI import WebKit struct ConditionsWebView: UIViewRepresentable { @State var html: String var openLink: (URL) -> Void = openExternalLink @EnvironmentObject var theme: AppTheme @State var pageLoaded = false func makeUIView(context: Context) -> WKWebView { let config = WKWebViewConfiguration() config.defaultWebpagePreferences.allowsContentJavaScript = false config.websiteDataStore = .nonPersistent() let view = WKWebView(frame: .zero, configuration: config) view.backgroundColor = .clear view.isOpaque = false view.navigationDelegate = context.coordinator DispatchQueue.main.asyncAfter(deadline: .now() + 1) { // just to make sure that even if updateUIView will not be called for any reason, the page // will be rendered anyway if !pageLoaded { loadPage(view) } } return view } func updateUIView(_ view: WKWebView, context: Context) { loadPage(view) } private func loadPage(_ webView: WKWebView) { let nonce = UUID().uuidString let styles = """ """ let csp = "" let head = "
\(csp)\(styles)" webView.loadHTMLString(head + html, baseURL: nil) DispatchQueue.main.async { pageLoaded = true } } func makeCoordinator() -> Cordinator { Cordinator(openLink: openLink) } class Cordinator: NSObject, WKNavigationDelegate { let openLink: (URL) -> Void init(openLink: @escaping (URL) -> Void) { self.openLink = openLink } func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { guard let url = navigationAction.request.url else { return decisionHandler(.allow) } switch navigationAction.navigationType { case .linkActivated: decisionHandler(.cancel) openLink(url) default: decisionHandler(url.scheme == "about" ? .allow : .cancel) } } } }