import AppKit import WebKit @MainActor enum RedditWebViewManager { private static let processPool = WKProcessPool() static func makeConfiguration(includeLoginBridge: Bool = true) -> WKWebViewConfiguration { let configuration = WKWebViewConfiguration() configuration.processPool = processPool configuration.websiteDataStore = .default() configuration.defaultWebpagePreferences.allowsContentJavaScript = true configuration.preferences.isElementFullscreenEnabled = true let isDarkMode = AppearanceManager.shared.isDarkMode let themeScript = WKUserScript( source: RedditThemeStyle.earlyInjectionScript(isDarkMode: isDarkMode), injectionTime: .atDocumentStart, forMainFrameOnly: true ) configuration.userContentController.addUserScript(themeScript) let boundaryScript = WKUserScript( source: RedditPostBoundaryStyle.injectionScript, injectionTime: .atDocumentEnd, forMainFrameOnly: true ) configuration.userContentController.addUserScript(boundaryScript) let chromeScript = WKUserScript( source: RedditHomeChromeStyle.injectionScript, injectionTime: .atDocumentStart, forMainFrameOnly: true ) configuration.userContentController.addUserScript(chromeScript) let authChromeScript = WKUserScript( source: RedditAuthChromeStyle.injectionScript, injectionTime: .atDocumentStart, forMainFrameOnly: false ) configuration.userContentController.addUserScript(authChromeScript) let shareBridgeScript = WKUserScript( source: RedditShareBridgeStyle.injectionScript, injectionTime: .atDocumentStart, forMainFrameOnly: true ) configuration.userContentController.addUserScript(shareBridgeScript) configuration.userContentController.add( RedditShareScriptBridge.shared, name: RedditShareBridgeStyle.messageHandlerName ) if includeLoginBridge { let loginBridgeScript = WKUserScript( source: RedditLoginBridgeStyle.injectionScript, injectionTime: .atDocumentStart, forMainFrameOnly: true ) configuration.userContentController.addUserScript(loginBridgeScript) configuration.userContentController.add( RedditLoginScriptBridge.shared, name: RedditLoginBridgeStyle.messageHandlerName ) } return configuration } static func makeWebView() -> WKWebView { let webView = WKWebView(frame: .zero, configuration: makeConfiguration()) webView.allowsBackForwardNavigationGestures = true webView.allowsMagnification = true // Use the default WKWebView user agent instead of spoofing Safari. let isDarkMode = AppearanceManager.shared.isDarkMode applyTheme(to: webView, isDarkMode: isDarkMode) return webView } static func applyTheme(to webView: WKWebView, isDarkMode: Bool) { applyAppearance(to: webView, isDarkMode: isDarkMode) applyUnderPageBackground(to: webView, isDarkMode: isDarkMode) webView.evaluateJavaScript( RedditThemeStyle.syncScript(isDarkMode: isDarkMode), completionHandler: nil ) } static func applyAppearance(to webView: WKWebView, isDarkMode: Bool) { let appearanceName: NSAppearance.Name = isDarkMode ? .darkAqua : .aqua webView.appearance = NSAppearance(named: appearanceName) } static func applyUnderPageBackground(to webView: WKWebView, isDarkMode: Bool) { webView.underPageBackgroundColor = AppearanceManager.webUnderPageBackgroundColor(isDarkMode: isDarkMode) } }