mangayomi-mirror/packages/desktop_webview_window/macos/Classes/DesktopWebviewWindowPlugin.swift
kodjomoustapha 88fa089727 +
2024-02-07 23:50:22 +01:00

328 lines
13 KiB
Swift

import Cocoa
import FlutterMacOS
import WebKit
private var viewId: Int64 = 0
public class DesktopWebviewWindowPlugin: NSObject, FlutterPlugin {
private let methodChannel: FlutterMethodChannel
private var webviews: [Int64: WebviewWindowController] = [:]
public init(methodChannel: FlutterMethodChannel) {
self.methodChannel = methodChannel
super.init()
}
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "webview_window", binaryMessenger: registrar.messenger)
let instance = DesktopWebviewWindowPlugin(methodChannel: channel)
registrar.addMethodCallDelegate(instance, channel: channel)
ClientMessageChannelPlugin.register(with: registrar)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "create":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
let width = argument["windowWidth"] as? Int ?? 1280
let height = argument["windowHeight"] as? Int ?? 720
let title = argument["title"] as? String ?? ""
let titleBarHeight = argument["titleBarHeight"] as? Int ?? 50
let titleBarTopPadding = argument["titleBarTopPadding"] as? Int ?? 0
let controller = WebviewWindowController(
viewId: viewId, methodChannel: methodChannel,
width: width, height: height, title: title,
titleBarHeight: titleBarHeight, titleBarTopPadding: titleBarTopPadding
)
controller.webviewPlugin = self
webviews[viewId] = controller
controller.showWindow(nil)
result(viewId)
viewId += 1
break
case "getCookies":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
guard let url = argument["url"] as? String else {
result(FlutterError(code: "0", message: "param url not found", details: nil))
return
}
var cookieList: [[String: Any?]] = []
if let urlHost = URL(string: url)?.host {
WKWebsiteDataStore.default().httpCookieStore.getAllCookies { (cookies) in
for cookie in cookies {
if urlHost.hasSuffix(cookie.domain) || ".\(urlHost)".hasSuffix(cookie.domain) {
var sameSite: String? = nil
if #available(macOS 10.15, *) {
if let sameSiteValue = cookie.sameSitePolicy?.rawValue {
sameSite = sameSiteValue.prefix(1).capitalized + sameSiteValue.dropFirst()
}
}
var expiresDateTimestamp: Int64 = -1
if let expiresDate = cookie.expiresDate?.timeIntervalSince1970 {
// convert to milliseconds
expiresDateTimestamp = Int64(expiresDate * 1000)
}
cookieList.append([
"name": cookie.name,
"value": cookie.value,
"expiresDate": expiresDateTimestamp != -1 ? expiresDateTimestamp : nil,
"isSessionOnly": cookie.isSessionOnly,
"domain": cookie.domain,
"sameSite": sameSite,
"isSecure": cookie.isSecure,
"isHttpOnly": cookie.isHTTPOnly,
"path": cookie.path,
])
}
}
result(cookieList)
}
return
}
result(cookieList)
break
case "launch":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
guard let viewId = argument["viewId"] as? Int64 else {
result(FlutterError(code: "0", message: "param viewId not found", details: nil))
return
}
guard let url = argument["url"] as? String else {
result(FlutterError(code: "0", message: "param url not found", details: nil))
return
}
guard let parsedUrl = URL(string: url) else {
result(FlutterError(code: "0", message: "failed to parse \(url)", details: nil))
return
}
guard let wc = webviews[viewId] else {
result(FlutterError(code: "0", message: "can not find webview for id: \(viewId)", details: nil))
return
}
wc.webViewController.load(url: parsedUrl)
result(nil)
break
case "registerJavaScripInterface":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
guard let viewId = argument["viewId"] as? Int64 else {
result(FlutterError(code: "0", message: "param viewId not found", details: nil))
return
}
guard let name = argument["name"] as? String else {
result(FlutterError(code: "0", message: "param name not found", details: nil))
return
}
guard let wc = webviews[viewId] else {
result(FlutterError(code: "0", message: "can not find webview for id: \(viewId)", details: nil))
return
}
wc.webViewController.addJavascriptInterface(name: name)
result(nil)
break
case "unregisterJavaScripInterface":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
guard let viewId = argument["viewId"] as? Int64 else {
result(FlutterError(code: "0", message: "param viewId not found", details: nil))
return
}
guard let name = argument["name"] as? String else {
result(FlutterError(code: "0", message: "param name not found", details: nil))
return
}
guard let wc = webviews[viewId] else {
result(FlutterError(code: "0", message: "can not find webview for id: \(viewId)", details: nil))
return
}
wc.webViewController.addJavascriptInterface(name: name)
result(nil)
break
case "clearAll":
WKWebsiteDataStore.default().removeData(
ofTypes: [WKWebsiteDataTypeCookies, WKWebsiteDataTypeLocalStorage],
modifiedSince: .distantPast,
completionHandler: {
result(nil)
})
break
case "setBrightness":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
guard let viewId = argument["viewId"] as? Int64 else {
result(FlutterError(code: "0", message: "param viewId not found", details: nil))
return
}
guard let wc = webviews[viewId] else {
result(FlutterError(code: "0", message: "can not find webview for id: \(viewId)", details: nil))
return
}
let brightness = argument["brightness"] as? Int ?? -1
wc.setAppearance(brightness: brightness)
result(nil)
break
case "addScriptToExecuteOnDocumentCreated":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
guard let viewId = argument["viewId"] as? Int64 else {
result(FlutterError(code: "0", message: "param viewId not found", details: nil))
return
}
guard let wc = webviews[viewId] else {
result(FlutterError(code: "0", message: "can not find webview for id: \(viewId)", details: nil))
return
}
guard let javaScript = argument["javaScript"] as? String else {
result(FlutterError(code: "0", message: "param javaScript not found", details: nil))
return
}
wc.webViewController.addScriptToExecuteOnDocumentCreated(javaScript: javaScript)
result(nil)
break
case "setApplicationNameForUserAgent":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
guard let viewId = argument["viewId"] as? Int64 else {
result(FlutterError(code: "0", message: "param viewId not found", details: nil))
return
}
guard let wc = webviews[viewId] else {
result(FlutterError(code: "0", message: "can not find webview for id: \(viewId)", details: nil))
return
}
guard let applicationName = argument["applicationName"] as? String else {
result(FlutterError(code: "0", message: "param applicationName not found", details: nil))
return
}
wc.webViewController.setApplicationNameForUserAgent(applicationName: applicationName)
result(nil)
break
case "back":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
guard let viewId = argument["viewId"] as? Int64 else {
result(FlutterError(code: "0", message: "param viewId not found", details: nil))
return
}
guard let wc = webviews[viewId] else {
result(FlutterError(code: "0", message: "can not find webview for id: \(viewId)", details: nil))
return
}
wc.webViewController.goBack()
break
case "forward":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
guard let viewId = argument["viewId"] as? Int64 else {
result(FlutterError(code: "0", message: "param viewId not found", details: nil))
return
}
guard let wc = webviews[viewId] else {
result(FlutterError(code: "0", message: "can not find webview for id: \(viewId)", details: nil))
return
}
wc.webViewController.goForward()
break
case "reload":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
guard let viewId = argument["viewId"] as? Int64 else {
result(FlutterError(code: "0", message: "param viewId not found", details: nil))
return
}
guard let wc = webviews[viewId] else {
result(FlutterError(code: "0", message: "can not find webview for id: \(viewId)", details: nil))
return
}
wc.webViewController.reload()
break
case "stop":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
guard let viewId = argument["viewId"] as? Int64 else {
result(FlutterError(code: "0", message: "param viewId not found", details: nil))
return
}
guard let wc = webviews[viewId] else {
result(FlutterError(code: "0", message: "can not find webview for id: \(viewId)", details: nil))
return
}
wc.webViewController.stopLoading()
break
case "close":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
guard let viewId = argument["viewId"] as? Int64 else {
result(FlutterError(code: "0", message: "param viewId not found", details: nil))
return
}
guard let wc = webviews[viewId] else {
result(FlutterError(code: "0", message: "can not find webview for id: \(viewId)", details: nil))
return
}
wc.close()
break
case "evaluateJavaScript":
guard let argument = call.arguments as? [String: Any?] else {
result(FlutterError(code: "0", message: "arg is not map", details: nil))
return
}
guard let viewId = argument["viewId"] as? Int64 else {
result(FlutterError(code: "0", message: "param viewId not found", details: nil))
return
}
guard let wc = webviews[viewId] else {
result(FlutterError(code: "0", message: "can not find webview for id: \(viewId)", details: nil))
return
}
guard let js = argument["javaScriptString"] as? String else {
result(FlutterError(code: "0", message: "param javaScriptString not found", details: nil))
return
}
wc.webViewController.evaluateJavaScript(javaScriptString: js, completer: result)
break
default:
result(FlutterMethodNotImplemented)
}
}
func onWebviewWindowClose(viewId: Int64, wc: WebviewWindowController) {
webviews.removeValue(forKey: viewId)
}
}