The Webview Univeral Flutter package for Appeto SDK.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

251 lignes
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. }