mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-01-11 22:40:36 +00:00
328 lines
13 KiB
Swift
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)
|
|
}
|
|
}
|