Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

251 строка
10 KiB

  1. //
  2. // Created by yangbin on 2021/11/15.
  3. //
  4. #include <windows.h>
  5. #include "web_view_window_plugin.h"
  6. #include <map>
  7. namespace {
  8. int64_t next_window_id_ = 0;
  9. bool IsWebViewRuntimeAvailable() {
  10. LPWSTR version_info;
  11. GetAvailableCoreWebView2BrowserVersionString(nullptr, &version_info);
  12. return version_info != nullptr;
  13. }
  14. } // namespace
  15. // static
  16. void WebviewWindowPlugin::RegisterWithRegistrar(
  17. flutter::PluginRegistrarWindows *registrar) {
  18. auto channel =
  19. std::make_shared<flutter::MethodChannel<flutter::EncodableValue>>(
  20. registrar->messenger(), "webview_window",
  21. &flutter::StandardMethodCodec::GetInstance());
  22. auto plugin = std::make_unique<WebviewWindowPlugin>(channel);
  23. channel->SetMethodCallHandler(
  24. [plugin_pointer = plugin.get()](const auto &call, auto result) {
  25. plugin_pointer->HandleMethodCall(call, std::move(result));
  26. });
  27. registrar->AddPlugin(std::move(plugin));
  28. }
  29. WebviewWindowPlugin::WebviewWindowPlugin(MethodChannelPtr method_channel)
  30. : method_channel_(std::move(method_channel)),
  31. windows_() {}
  32. WebviewWindowPlugin::~WebviewWindowPlugin() = default;
  33. void WebviewWindowPlugin::HandleMethodCall(
  34. const flutter::MethodCall<flutter::EncodableValue> &method_call,
  35. std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
  36. if (method_call.method_name() == "create") {
  37. if (!IsWebViewRuntimeAvailable()) {
  38. result->Error("0", "WebView runtime not available");
  39. return;
  40. }
  41. auto *arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  42. auto width = arguments->at(flutter::EncodableValue("windowWidth")).LongValue();
  43. auto height = arguments->at(flutter::EncodableValue("windowHeight")).LongValue();
  44. auto title = std::get<std::string>(arguments->at(flutter::EncodableValue("title")));
  45. auto titleBarHeight = arguments->at(flutter::EncodableValue("titleBarHeight")).LongValue();
  46. auto userDataFolder = std::get<std::string>(arguments->at(flutter::EncodableValue("userDataFolderWindows")));
  47. auto window_id = next_window_id_;
  48. auto window = std::make_unique<WebviewWindow>(
  49. method_channel_, window_id, int(titleBarHeight),
  50. [this, window_id]() {
  51. windows_.erase(window_id);
  52. });
  53. std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result2(std::move(result));
  54. window->CreateAndShow(
  55. utf8_to_wide(title), int(height), int(width), utf8_to_wide(userDataFolder),
  56. [this, window_id, result(result2)](bool succeed) mutable {
  57. if (!succeed) {
  58. result->Error("0", "failed to show window");
  59. windows_.erase(window_id);
  60. return;
  61. }
  62. result->Success(flutter::EncodableValue(window_id));
  63. });
  64. next_window_id_++;
  65. windows_[window_id] = std::move(window);
  66. } else if (method_call.method_name() == "launch") {
  67. auto *arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  68. auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue();
  69. auto url = std::get<std::string>(arguments->at(flutter::EncodableValue("url")));
  70. if (!windows_.count(window_id)) {
  71. result->Error("0", "can not find webview window for id");
  72. return;
  73. }
  74. if (!windows_[window_id]->GetWebView()) {
  75. result->Error("0", "webview window not ready");
  76. return;
  77. }
  78. windows_[window_id]->GetWebView()->Navigate(utf8_to_wide(url));
  79. result->Success();
  80. } else if (method_call.method_name() == "addScriptToExecuteOnDocumentCreated") {
  81. auto *arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  82. auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue();
  83. auto javaScript = std::get<std::string>(arguments->at(flutter::EncodableValue("javaScript")));
  84. if (!windows_.count(window_id)) {
  85. result->Error("0", "can not find webview window for id");
  86. return;
  87. }
  88. if (!windows_[window_id]->GetWebView()) {
  89. result->Error("0", "webview window not ready");
  90. return;
  91. }
  92. windows_[window_id]->GetWebView()->AddScriptToExecuteOnDocumentCreated(utf8_to_wide(javaScript));
  93. result->Success();
  94. } else if (method_call.method_name() == "clearAll") {
  95. std::map<int64_t, std::unique_ptr<WebviewWindow>> local;
  96. std::swap(local, windows_);
  97. local.clear();
  98. result->Success();
  99. } else if (method_call.method_name() == "setApplicationNameForUserAgent") {
  100. auto *arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  101. auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue();
  102. auto applicationName = std::get<std::string>(arguments->at(flutter::EncodableValue("applicationName")));
  103. if (!windows_.count(window_id)) {
  104. result->Error("0", "can not find webview window for id");
  105. return;
  106. }
  107. if (!windows_[window_id]->GetWebView()) {
  108. result->Error("0", "webview window not ready");
  109. return;
  110. }
  111. windows_[window_id]->GetWebView()->SetApplicationNameForUserAgent(utf8_to_wide(applicationName));
  112. result->Success();
  113. } else if (method_call.method_name() == "isWebviewAvailable") {
  114. result->Success(flutter::EncodableValue(IsWebViewRuntimeAvailable()));
  115. } else if (method_call.method_name() == "back") {
  116. auto *arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  117. auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue();
  118. if (!windows_.count(window_id)) {
  119. result->Error("0", "can not find webview window for id");
  120. return;
  121. }
  122. if (!windows_[window_id]->GetWebView()) {
  123. result->Error("0", "webview window not ready");
  124. return;
  125. }
  126. windows_[window_id]->GetWebView()->GoBack();
  127. result->Success();
  128. } else if (method_call.method_name() == "forward") {
  129. auto *arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  130. auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue();
  131. if (!windows_.count(window_id)) {
  132. result->Error("0", "can not find webview window for id");
  133. return;
  134. }
  135. if (!windows_[window_id]->GetWebView()) {
  136. result->Error("0", "webview window not ready");
  137. return;
  138. }
  139. windows_[window_id]->GetWebView()->GoForward();
  140. result->Success();
  141. } else if (method_call.method_name() == "reload") {
  142. auto *arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  143. auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue();
  144. if (!windows_.count(window_id)) {
  145. result->Error("0", "can not find webview window for id");
  146. return;
  147. }
  148. if (!windows_[window_id]->GetWebView()) {
  149. result->Error("0", "webview window not ready");
  150. return;
  151. }
  152. windows_[window_id]->GetWebView()->Reload();
  153. result->Success();
  154. } else if (method_call.method_name() == "stop") {
  155. auto *arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  156. auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue();
  157. if (!windows_.count(window_id)) {
  158. result->Error("0", "can not find webview window for id");
  159. return;
  160. }
  161. if (!windows_[window_id]->GetWebView()) {
  162. result->Error("0", "webview window not ready");
  163. return;
  164. }
  165. windows_[window_id]->GetWebView()->Stop();
  166. result->Success();
  167. } else if (method_call.method_name() == "close") {
  168. auto *arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  169. auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue();
  170. if (!windows_.count(window_id)) {
  171. result->Error("0", "can not find webview window for id");
  172. return;
  173. }
  174. windows_.erase(window_id);
  175. result->Success();
  176. } else if (method_call.method_name() == "evaluateJavaScript") {
  177. auto *arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  178. auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue();
  179. auto javascript = std::get<std::string>(arguments->at(flutter::EncodableValue("javaScriptString")));
  180. if (!windows_.count(window_id)) {
  181. result->Error("0", "can not find webview window for id");
  182. return;
  183. }
  184. if (!windows_[window_id]->GetWebView()) {
  185. result->Error("0", "webview window not ready");
  186. return;
  187. }
  188. windows_[window_id]->GetWebView()->ExecuteJavaScript(utf8_to_wide(javascript), std::move(result));
  189. } else if (method_call.method_name() == "postWebMessageAsString") {
  190. auto* arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  191. auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue();
  192. auto webmessage = std::get<std::string>(arguments->at(flutter::EncodableValue("webMessage")));
  193. if (!windows_.count(window_id)) {
  194. result->Error("0", "can not find webview window for id");
  195. return;
  196. }
  197. if (!windows_[window_id]->GetWebView()) {
  198. result->Error("0", "webview window not ready");
  199. return;
  200. }
  201. windows_[window_id]->GetWebView()->PostWebMessageAsString(utf8_to_wide(webmessage), std::move(result));
  202. } else if (method_call.method_name() == "postWebMessageAsJson") {
  203. auto* arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  204. auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue();
  205. auto webmessage = std::get<std::string>(arguments->at(flutter::EncodableValue("webMessage")));
  206. if (!windows_.count(window_id)) {
  207. result->Error("0", "can not find webview window for id");
  208. return;
  209. }
  210. if (!windows_[window_id]->GetWebView()) {
  211. result->Error("0", "webview window not ready");
  212. return;
  213. }
  214. windows_[window_id]->GetWebView()->PostWebMessageAsJson(utf8_to_wide(webmessage), std::move(result));
  215. } else if (method_call.method_name() == "openDevToolsWindow") {
  216. auto* arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
  217. auto window_id = arguments->at(flutter::EncodableValue("viewId")).LongValue();
  218. if (!windows_.count(window_id)) {
  219. result->Error("0", "can not find webview window for id");
  220. return;
  221. }
  222. if (!windows_[window_id]->GetWebView()) {
  223. result->Error("0", "webview window not ready");
  224. return;
  225. }
  226. windows_[window_id]->GetWebView()->openDevToolsWindow();
  227. result->Success();
  228. } else {
  229. result->NotImplemented();
  230. }
  231. }