// // Created by yangbin on 2021/11/15. // #include #include "web_view_window_plugin.h" #include namespace { int64_t next_window_id_ = 0; bool IsWebViewRuntimeAvailable() { LPWSTR version_info; GetAvailableCoreWebView2BrowserVersionString(nullptr, &version_info); return version_info != nullptr; } } // namespace // static void WebviewWindowPlugin::RegisterWithRegistrar( flutter::PluginRegistrarWindows *registrar) { auto channel = std::make_shared>( registrar->messenger(), "webview_window", &flutter::StandardMethodCodec::GetInstance()); auto plugin = std::make_unique(channel); channel->SetMethodCallHandler( [plugin_pointer = plugin.get()](const auto &call, auto result) { plugin_pointer->HandleMethodCall(call, std::move(result)); }); registrar->AddPlugin(std::move(plugin)); } WebviewWindowPlugin::WebviewWindowPlugin(MethodChannelPtr method_channel) : method_channel_(std::move(method_channel)), windows_() {} WebviewWindowPlugin::~WebviewWindowPlugin() = default; void WebviewWindowPlugin::HandleMethodCall( const flutter::MethodCall &method_call, std::unique_ptr> result) { if (method_call.method_name() == "create") { if (!IsWebViewRuntimeAvailable()) { result->Error("0", "WebView runtime not available"); return; } auto *arguments = std::get_if(method_call.arguments()); auto width = arguments->at(flutter::EncodableValue("windowWidth")).LongValue(); auto height = arguments->at(flutter::EncodableValue("windowHeight")).LongValue(); auto title = std::get(arguments->at(flutter::EncodableValue("title"))); auto titleBarHeight = arguments->at(flutter::EncodableValue("titleBarHeight")).LongValue(); auto userDataFolder = std::get(arguments->at(flutter::EncodableValue("userDataFolderWindows"))); auto window_id = next_window_id_; auto window = std::make_unique( method_channel_, window_id, int(titleBarHeight), [this, window_id]() { windows_.erase(window_id); }); std::shared_ptr> result2(std::move(result)); window->CreateAndShow( utf8_to_wide(title), int(height), int(width), utf8_to_wide(userDataFolder), [this, window_id, result(result2)](bool succeed) mutable { if (!succeed) { result->Error("0", "failed to show window"); windows_.erase(window_id); return; } result->Success(flutter::EncodableValue(window_id)); }); next_window_id_++; windows_[window_id] = std::move(window); } else if (method_call.method_name() == "launch") { auto *arguments = std::get_if(method_call.arguments()); auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue(); auto url = std::get(arguments->at(flutter::EncodableValue("url"))); if (!windows_.count(window_id)) { result->Error("0", "can not find webview window for id"); return; } if (!windows_[window_id]->GetWebView()) { result->Error("0", "webview window not ready"); return; } windows_[window_id]->GetWebView()->Navigate(utf8_to_wide(url)); result->Success(); } else if (method_call.method_name() == "addScriptToExecuteOnDocumentCreated") { auto *arguments = std::get_if(method_call.arguments()); auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue(); auto javaScript = std::get(arguments->at(flutter::EncodableValue("javaScript"))); if (!windows_.count(window_id)) { result->Error("0", "can not find webview window for id"); return; } if (!windows_[window_id]->GetWebView()) { result->Error("0", "webview window not ready"); return; } windows_[window_id]->GetWebView()->AddScriptToExecuteOnDocumentCreated(utf8_to_wide(javaScript)); result->Success(); } else if (method_call.method_name() == "clearAll") { std::map> local; std::swap(local, windows_); local.clear(); result->Success(); } else if (method_call.method_name() == "setApplicationNameForUserAgent") { auto *arguments = std::get_if(method_call.arguments()); auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue(); auto applicationName = std::get(arguments->at(flutter::EncodableValue("applicationName"))); if (!windows_.count(window_id)) { result->Error("0", "can not find webview window for id"); return; } if (!windows_[window_id]->GetWebView()) { result->Error("0", "webview window not ready"); return; } windows_[window_id]->GetWebView()->SetApplicationNameForUserAgent(utf8_to_wide(applicationName)); result->Success(); } else if (method_call.method_name() == "isWebviewAvailable") { result->Success(flutter::EncodableValue(IsWebViewRuntimeAvailable())); } else if (method_call.method_name() == "back") { auto *arguments = std::get_if(method_call.arguments()); auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue(); if (!windows_.count(window_id)) { result->Error("0", "can not find webview window for id"); return; } if (!windows_[window_id]->GetWebView()) { result->Error("0", "webview window not ready"); return; } windows_[window_id]->GetWebView()->GoBack(); result->Success(); } else if (method_call.method_name() == "forward") { auto *arguments = std::get_if(method_call.arguments()); auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue(); if (!windows_.count(window_id)) { result->Error("0", "can not find webview window for id"); return; } if (!windows_[window_id]->GetWebView()) { result->Error("0", "webview window not ready"); return; } windows_[window_id]->GetWebView()->GoForward(); result->Success(); } else if (method_call.method_name() == "reload") { auto *arguments = std::get_if(method_call.arguments()); auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue(); if (!windows_.count(window_id)) { result->Error("0", "can not find webview window for id"); return; } if (!windows_[window_id]->GetWebView()) { result->Error("0", "webview window not ready"); return; } windows_[window_id]->GetWebView()->Reload(); result->Success(); } else if (method_call.method_name() == "stop") { auto *arguments = std::get_if(method_call.arguments()); auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue(); if (!windows_.count(window_id)) { result->Error("0", "can not find webview window for id"); return; } if (!windows_[window_id]->GetWebView()) { result->Error("0", "webview window not ready"); return; } windows_[window_id]->GetWebView()->Stop(); result->Success(); } else if (method_call.method_name() == "close") { auto *arguments = std::get_if(method_call.arguments()); auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue(); if (!windows_.count(window_id)) { result->Error("0", "can not find webview window for id"); return; } windows_.erase(window_id); result->Success(); } else if (method_call.method_name() == "evaluateJavaScript") { auto *arguments = std::get_if(method_call.arguments()); auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue(); auto javascript = std::get(arguments->at(flutter::EncodableValue("javaScriptString"))); if (!windows_.count(window_id)) { result->Error("0", "can not find webview window for id"); return; } if (!windows_[window_id]->GetWebView()) { result->Error("0", "webview window not ready"); return; } windows_[window_id]->GetWebView()->ExecuteJavaScript(utf8_to_wide(javascript), std::move(result)); } else if (method_call.method_name() == "postWebMessageAsString") { auto* arguments = std::get_if(method_call.arguments()); auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue(); auto webmessage = std::get(arguments->at(flutter::EncodableValue("webMessage"))); if (!windows_.count(window_id)) { result->Error("0", "can not find webview window for id"); return; } if (!windows_[window_id]->GetWebView()) { result->Error("0", "webview window not ready"); return; } windows_[window_id]->GetWebView()->PostWebMessageAsString(utf8_to_wide(webmessage), std::move(result)); } else if (method_call.method_name() == "postWebMessageAsJson") { auto* arguments = std::get_if(method_call.arguments()); auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue(); auto webmessage = std::get(arguments->at(flutter::EncodableValue("webMessage"))); if (!windows_.count(window_id)) { result->Error("0", "can not find webview window for id"); return; } if (!windows_[window_id]->GetWebView()) { result->Error("0", "webview window not ready"); return; } windows_[window_id]->GetWebView()->PostWebMessageAsJson(utf8_to_wide(webmessage), std::move(result)); } else if (method_call.method_name() == "openDevToolsWindow") { auto* arguments = std::get_if(method_call.arguments()); auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue(); if (!windows_.count(window_id)) { result->Error("0", "can not find webview window for id"); return; } if (!windows_[window_id]->GetWebView()) { result->Error("0", "webview window not ready"); return; } windows_[window_id]->GetWebView()->openDevToolsWindow(); result->Success(); } else { result->NotImplemented(); } }