|
- import Cocoa
- import FlutterMacOS
- import WebKit
-
- private var viewId: Int64 = 0
-
- public class WebviewUniversalPlugin: 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 = WebviewUniversalPlugin(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 "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) {
- wc.destroy()
- let wc = webviews.removeValue(forKey: viewId)
- wc?.window?.windowController = nil
- wc?.window = nil
- }
- }
|