diff --git a/flutter_inappwebview/example/lib/in_app_browser_example.screen.dart b/flutter_inappwebview/example/lib/in_app_browser_example.screen.dart index 6d307cb8..15f2bd7b 100755 --- a/flutter_inappwebview/example/lib/in_app_browser_example.screen.dart +++ b/flutter_inappwebview/example/lib/in_app_browser_example.screen.dart @@ -30,7 +30,6 @@ class MyInAppBrowser extends InAppBrowser { @override Future onLoadStop(url) async { pullToRefreshController?.endRefreshing(); - print(await webViewController?.getUrl()); } @override diff --git a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.cpp b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.cpp index 5e4070cb..74eb2287 100644 --- a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.cpp +++ b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.cpp @@ -7,21 +7,20 @@ namespace flutter_inappwebview_plugin { - // static - void FlutterInappwebviewWindowsPlugin::RegisterWithRegistrar( - flutter::PluginRegistrarWindows* registrar) { - auto plugin = std::make_unique(registrar); - registrar->AddPlugin(std::move(plugin)); - } + // static + void FlutterInappwebviewWindowsPlugin::RegisterWithRegistrar( + flutter::PluginRegistrarWindows* registrar) + { + auto plugin = std::make_unique(registrar); + registrar->AddPlugin(std::move(plugin)); + } - FlutterInappwebviewWindowsPlugin::FlutterInappwebviewWindowsPlugin(flutter::PluginRegistrarWindows* registrar) - : registrar(registrar) - { - inAppBrowserManager = std::make_unique(this); - } + FlutterInappwebviewWindowsPlugin::FlutterInappwebviewWindowsPlugin(flutter::PluginRegistrarWindows* registrar) + : registrar(registrar) + { + inAppBrowserManager = std::make_unique(this); + } - FlutterInappwebviewWindowsPlugin::~FlutterInappwebviewWindowsPlugin() - { - - } + FlutterInappwebviewWindowsPlugin::~FlutterInappwebviewWindowsPlugin() + {} } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.h b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.h index 534ecabb..ffa0a576 100644 --- a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.h +++ b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.h @@ -6,22 +6,22 @@ namespace flutter_inappwebview_plugin { - class InAppBrowserManager; + class InAppBrowserManager; - class FlutterInappwebviewWindowsPlugin : public flutter::Plugin { - public: - flutter::PluginRegistrarWindows* registrar; - std::unique_ptr inAppBrowserManager; + class FlutterInappwebviewWindowsPlugin : public flutter::Plugin { + public: + flutter::PluginRegistrarWindows* registrar; + std::unique_ptr inAppBrowserManager; - static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar); + static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar); - FlutterInappwebviewWindowsPlugin(flutter::PluginRegistrarWindows* registrar); + FlutterInappwebviewWindowsPlugin(flutter::PluginRegistrarWindows* registrar); - virtual ~FlutterInappwebviewWindowsPlugin(); + virtual ~FlutterInappwebviewWindowsPlugin(); - // Disallow copy and assign. - FlutterInappwebviewWindowsPlugin(const FlutterInappwebviewWindowsPlugin&) = delete; - FlutterInappwebviewWindowsPlugin& operator=(const FlutterInappwebviewWindowsPlugin&) = delete; - }; + // Disallow copy and assign. + FlutterInappwebviewWindowsPlugin(const FlutterInappwebviewWindowsPlugin&) = delete; + FlutterInappwebviewWindowsPlugin& operator=(const FlutterInappwebviewWindowsPlugin&) = delete; + }; } #endif // FLUTTER_PLUGIN_FLUTTER_INAPPWEBVIEW_PLUGIN_PLUGIN_H_ diff --git a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin_c_api.cpp b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin_c_api.cpp index f49d1a29..9fc6f673 100644 --- a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin_c_api.cpp +++ b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin_c_api.cpp @@ -5,8 +5,9 @@ #include "flutter_inappwebview_windows_plugin.h" void FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar( - FlutterDesktopPluginRegistrarRef registrar) { - flutter_inappwebview_plugin::FlutterInappwebviewWindowsPlugin::RegisterWithRegistrar( - flutter::PluginRegistrarManager::GetInstance() - ->GetRegistrar(registrar)); + FlutterDesktopPluginRegistrarRef registrar) +{ + flutter_inappwebview_plugin::FlutterInappwebviewWindowsPlugin::RegisterWithRegistrar( + flutter::PluginRegistrarManager::GetInstance() + ->GetRegistrar(registrar)); } diff --git a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.cpp b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.cpp index 0a158848..afa81412 100644 --- a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.cpp +++ b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.cpp @@ -1,221 +1,226 @@ #include -#include "in_app_browser.h" + #include "../utils/util.h" +#include "in_app_browser.h" #include "in_app_browser_manager.h" namespace flutter_inappwebview_plugin { - InAppBrowser::InAppBrowser(FlutterInappwebviewWindowsPlugin* plugin, const InAppBrowserCreationParams& params) - : plugin(plugin), - m_hInstance(GetModuleHandle(nullptr)), - id(params.id), - initialUrlRequest(params.urlRequest), - channelDelegate(std::make_unique(id, plugin->registrar->messenger())) - { - WNDCLASS wndClass = {}; - wndClass.lpszClassName = InAppBrowser::CLASS_NAME; - wndClass.hInstance = m_hInstance; - wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); - wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); - wndClass.lpfnWndProc = InAppBrowser::WndProc; + InAppBrowser::InAppBrowser(FlutterInappwebviewWindowsPlugin* plugin, const InAppBrowserCreationParams& params) + : plugin(plugin), + m_hInstance(GetModuleHandle(nullptr)), + id(params.id), + initialUrlRequest(params.urlRequest), + channelDelegate(std::make_unique(id, plugin->registrar->messenger())) + { + WNDCLASS wndClass = {}; + wndClass.lpszClassName = InAppBrowser::CLASS_NAME; + wndClass.hInstance = m_hInstance; + wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndClass.lpfnWndProc = InAppBrowser::WndProc; - RegisterClass(&wndClass); + RegisterClass(&wndClass); - m_hWnd = CreateWindowEx( - 0, // Optional window styles. - InAppBrowser::CLASS_NAME, // Window class - L"", // Window text - WS_OVERLAPPEDWINDOW, // Window style + m_hWnd = CreateWindowEx( + 0, // Optional window styles. + InAppBrowser::CLASS_NAME, // Window class + L"", // Window text + WS_OVERLAPPEDWINDOW, // Window style - // Size and position - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + // Size and position + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - NULL, // Parent window - NULL, // Menu - m_hInstance,// Instance handle - this // Additional application data - ); + NULL, // Parent window + NULL, // Menu + m_hInstance,// Instance handle + this // Additional application data + ); - ShowWindow(m_hWnd, SW_SHOW); + ShowWindow(m_hWnd, SW_SHOW); - webView = std::make_unique(plugin, id, m_hWnd, InAppBrowser::METHOD_CHANNEL_NAME_PREFIX + id, [this]() -> void { - if (channelDelegate) { - channelDelegate->onBrowserCreated(); - } + webView = std::make_unique(plugin, id, m_hWnd, InAppBrowser::METHOD_CHANNEL_NAME_PREFIX + id, [this]() -> void + { + if (channelDelegate) { + channelDelegate->onBrowserCreated(); + } - if (initialUrlRequest.has_value()) { - webView->loadUrl(initialUrlRequest.value()); - } - }); + if (initialUrlRequest.has_value()) { + webView->loadUrl(initialUrlRequest.value()); + } + }); - // <-- WebView2 sample code starts here --> - // Step 3 - Create a single WebView within the parent window - // Locate the browser and set up the environment for WebView - //CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr, - // Callback( - // [hWnd = m_hWnd, inAppBrowser = this](HRESULT result, ICoreWebView2Environment* env) -> HRESULT { + // <-- WebView2 sample code starts here --> + // Step 3 - Create a single WebView within the parent window + // Locate the browser and set up the environment for WebView + //CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr, + // Callback( + // [hWnd = m_hWnd, inAppBrowser = this](HRESULT result, ICoreWebView2Environment* env) -> HRESULT { - // // Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd - // env->CreateCoreWebView2Controller(hWnd, Callback( - // [hWnd, inAppBrowser](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT { - // if (controller != nullptr) { - // inAppBrowser->webviewController = controller; - // inAppBrowser->webviewController->get_CoreWebView2(&inAppBrowser->webview); - // } + // // Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd + // env->CreateCoreWebView2Controller(hWnd, Callback( + // [hWnd, inAppBrowser](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT { + // if (controller != nullptr) { + // inAppBrowser->webviewController = controller; + // inAppBrowser->webviewController->get_CoreWebView2(&inAppBrowser->webview); + // } - // // Add a few settings for the webview - // // The demo step is redundant since the values are the default settings - // wil::com_ptr settings; - // inAppBrowser->webview->get_Settings(&settings); - // settings->put_IsScriptEnabled(TRUE); - // settings->put_AreDefaultScriptDialogsEnabled(TRUE); - // settings->put_IsWebMessageEnabled(TRUE); + // // Add a few settings for the webview + // // The demo step is redundant since the values are the default settings + // wil::com_ptr settings; + // inAppBrowser->webview->get_Settings(&settings); + // settings->put_IsScriptEnabled(TRUE); + // settings->put_AreDefaultScriptDialogsEnabled(TRUE); + // settings->put_IsWebMessageEnabled(TRUE); - // // Resize WebView to fit the bounds of the parent window - // RECT bounds; - // GetClientRect(hWnd, &bounds); - // inAppBrowser->webviewController->put_Bounds(bounds); + // // Resize WebView to fit the bounds of the parent window + // RECT bounds; + // GetClientRect(hWnd, &bounds); + // inAppBrowser->webviewController->put_Bounds(bounds); - // auto url = inAppBrowser->initialUrlRequest.value().url.value(); - // std::wstring stemp = ansi_to_wide(url); + // auto url = inAppBrowser->initialUrlRequest.value().url.value(); + // std::wstring stemp = ansi_to_wide(url); - // // Schedule an async task to navigate to Bing - // inAppBrowser->webview->Navigate(stemp.c_str()); + // // Schedule an async task to navigate to Bing + // inAppBrowser->webview->Navigate(stemp.c_str()); - // // - // // Step 4 - Navigation events - // // register an ICoreWebView2NavigationStartingEventHandler to cancel any non-https navigation - // EventRegistrationToken token; - // inAppBrowser->webview->add_NavigationStarting(Callback( - // [](ICoreWebView2* webview, ICoreWebView2NavigationStartingEventArgs* args) -> HRESULT { - // wil::unique_cotaskmem_string uri; - // args->get_Uri(&uri); - // std::wstring source(uri.get()); - // if (source.substr(0, 5) != L"https") { - // args->put_Cancel(true); - // } - // return S_OK; - // }).Get(), &token); - // // + // // + // // Step 4 - Navigation events + // // register an ICoreWebView2NavigationStartingEventHandler to cancel any non-https navigation + // EventRegistrationToken token; + // inAppBrowser->webview->add_NavigationStarting(Callback( + // [](ICoreWebView2* webview, ICoreWebView2NavigationStartingEventArgs* args) -> HRESULT { + // wil::unique_cotaskmem_string uri; + // args->get_Uri(&uri); + // std::wstring source(uri.get()); + // if (source.substr(0, 5) != L"https") { + // args->put_Cancel(true); + // } + // return S_OK; + // }).Get(), &token); + // // - // // - // // Step 5 - Scripting - // // Schedule an async task to add initialization script that freezes the Object object - // inAppBrowser->webview->AddScriptToExecuteOnDocumentCreated(L"Object.freeze(Object);", nullptr); - // // Schedule an async task to get the document URL - // inAppBrowser->webview->ExecuteScript(L"window.document.URL;", Callback( - // [](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT { - // LPCWSTR URL = resultObjectAsJson; - // OutputDebugStringW(URL); - // //doSomethingWithURL(URL); - // return S_OK; - // }).Get()); - // // + // // + // // Step 5 - Scripting + // // Schedule an async task to add initialization script that freezes the Object object + // inAppBrowser->webview->AddScriptToExecuteOnDocumentCreated(L"Object.freeze(Object);", nullptr); + // // Schedule an async task to get the document URL + // inAppBrowser->webview->ExecuteScript(L"window.document.URL;", Callback( + // [](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT { + // LPCWSTR URL = resultObjectAsJson; + // OutputDebugStringW(URL); + // //doSomethingWithURL(URL); + // return S_OK; + // }).Get()); + // // - // // - // // Step 6 - Communication between host and web content - // // Set an event handler for the host to return received message back to the web content - // inAppBrowser->webview->add_WebMessageReceived(Callback( - // [](ICoreWebView2* webview, ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT { - // wil::unique_cotaskmem_string message; - // args->TryGetWebMessageAsString(&message); - // // processMessage(&message); - // webview->PostWebMessageAsString(message.get()); - // return S_OK; - // }).Get(), &token); + // // + // // Step 6 - Communication between host and web content + // // Set an event handler for the host to return received message back to the web content + // inAppBrowser->webview->add_WebMessageReceived(Callback( + // [](ICoreWebView2* webview, ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT { + // wil::unique_cotaskmem_string message; + // args->TryGetWebMessageAsString(&message); + // // processMessage(&message); + // webview->PostWebMessageAsString(message.get()); + // return S_OK; + // }).Get(), &token); - // // Schedule an async task to add initialization script that - // // 1) Add an listener to print message from the host - // // 2) Post document URL to the host - // inAppBrowser->webview->AddScriptToExecuteOnDocumentCreated( - // L"window.chrome.webview.addEventListener(\'message\', event => alert(event.data));" \ + // // Schedule an async task to add initialization script that + // // 1) Add an listener to print message from the host + // // 2) Post document URL to the host + // inAppBrowser->webview->AddScriptToExecuteOnDocumentCreated( + // L"window.chrome.webview.addEventListener(\'message\', event => alert(event.data));" \ // L"window.chrome.webview.postMessage(window.document.URL);", - // nullptr); - // // + // nullptr); + // // - // return S_OK; - // }).Get()); - // return S_OK; - // }).Get()); - } + // return S_OK; + // }).Get()); + // return S_OK; + // }).Get()); + } - LRESULT CALLBACK InAppBrowser::WndProc( - HWND window, - UINT message, - WPARAM wparam, - LPARAM lparam - ) noexcept { - if (message == WM_NCCREATE) { - auto window_struct = reinterpret_cast(lparam); - SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast(window_struct->lpCreateParams)); - } - else if (InAppBrowser* that = GetThisFromHandle(window)) { - return that->MessageHandler(window, message, wparam, lparam); - } + LRESULT CALLBACK InAppBrowser::WndProc( + HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam + ) noexcept + { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast(window_struct->lpCreateParams)); + } + else if (InAppBrowser* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } - return DefWindowProc(window, message, wparam, lparam); - } + return DefWindowProc(window, message, wparam, lparam); + } - LRESULT InAppBrowser::MessageHandler( - HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam - ) noexcept { - switch (message) { - case WM_DESTROY: { - // might receive multiple WM_DESTROY messages. - if (!destroyed_) { - destroyed_ = true; + LRESULT InAppBrowser::MessageHandler( + HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam + ) noexcept + { + switch (message) { + case WM_DESTROY: { + // might receive multiple WM_DESTROY messages. + if (!destroyed_) { + destroyed_ = true; - webView.reset(); + webView.reset(); - if (channelDelegate) { - channelDelegate->onExit(); - } + if (channelDelegate) { + channelDelegate->onExit(); + } - if (plugin && plugin->inAppBrowserManager) { - plugin->inAppBrowserManager->browsers.erase(id); - } - } - return 0; - } - case WM_DPICHANGED: { - auto newRectSize = reinterpret_cast(lparam); - LONG newWidth = newRectSize->right - newRectSize->left; - LONG newHeight = newRectSize->bottom - newRectSize->top; + if (plugin && plugin->inAppBrowserManager) { + plugin->inAppBrowserManager->browsers.erase(id); + } + } + return 0; + } + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; - SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, - newHeight, SWP_NOZORDER | SWP_NOACTIVATE); - return 0; - } - case WM_SIZE: { - RECT bounds; - GetClientRect(hwnd, &bounds); - if (webView) { - webView->webViewController->put_Bounds(bounds); - } - return 0; - } - case WM_ACTIVATE: { - return 0; - } - } + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + return 0; + } + case WM_SIZE: { + RECT bounds; + GetClientRect(hwnd, &bounds); + if (webView) { + webView->webViewController->put_Bounds(bounds); + } + return 0; + } + case WM_ACTIVATE: { + return 0; + } + } - return DefWindowProc(hwnd, message, wparam, lparam); - } + return DefWindowProc(hwnd, message, wparam, lparam); + } - InAppBrowser* InAppBrowser::GetThisFromHandle(HWND const window) noexcept { - return reinterpret_cast( - GetWindowLongPtr(window, GWLP_USERDATA)); - } + InAppBrowser* InAppBrowser::GetThisFromHandle(HWND const window) noexcept + { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); + } - InAppBrowser::~InAppBrowser() - { - debugLog("dealloc InAppBrowser"); - webView.reset(); - SetWindowLongPtr(m_hWnd, GWLP_USERDATA, 0); - plugin = nullptr; - } + InAppBrowser::~InAppBrowser() + { + debugLog("dealloc InAppBrowser"); + webView.reset(); + SetWindowLongPtr(m_hWnd, GWLP_USERDATA, 0); + plugin = nullptr; + } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.h b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.h index a3adb62d..900fecde 100644 --- a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.h +++ b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.h @@ -1,11 +1,11 @@ #ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_H_ #define FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_H_ -#include -#include #include - +#include #include +#include + #include "../flutter_inappwebview_windows_plugin.h" #include "../in_app_webview/in_app_webview.h" #include "../types/url_request.h" @@ -13,40 +13,40 @@ namespace flutter_inappwebview_plugin { - struct InAppBrowserCreationParams - { - std::string id; - std::optional urlRequest; - }; + struct InAppBrowserCreationParams + { + std::string id; + std::optional urlRequest; + }; - class InAppBrowser { - public: - static inline const std::string METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappbrowser_"; - static inline const wchar_t* CLASS_NAME = L"InAppBrowser"; + class InAppBrowser { + public: + static inline const std::string METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappbrowser_"; + static inline const wchar_t* CLASS_NAME = L"InAppBrowser"; - static LRESULT CALLBACK WndProc(HWND window, - UINT message, - WPARAM wparam, - LPARAM lparam) noexcept; + static LRESULT CALLBACK WndProc(HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) noexcept; - FlutterInappwebviewWindowsPlugin* plugin; - std::string id; - std::optional initialUrlRequest; - std::unique_ptr webView; - std::unique_ptr channelDelegate; + FlutterInappwebviewWindowsPlugin* plugin; + std::string id; + std::optional initialUrlRequest; + std::unique_ptr webView; + std::unique_ptr channelDelegate; - InAppBrowser(FlutterInappwebviewWindowsPlugin* plugin, const InAppBrowserCreationParams& params); - ~InAppBrowser(); + InAppBrowser(FlutterInappwebviewWindowsPlugin* plugin, const InAppBrowserCreationParams& params); + ~InAppBrowser(); - private: - HINSTANCE m_hInstance; - HWND m_hWnd; - bool destroyed_ = false; - static InAppBrowser* GetThisFromHandle(HWND window) noexcept; - LRESULT MessageHandler(HWND window, - UINT message, - WPARAM wparam, - LPARAM lparam) noexcept; - }; + private: + HINSTANCE m_hInstance; + HWND m_hWnd; + bool destroyed_ = false; + static InAppBrowser* GetThisFromHandle(HWND window) noexcept; + LRESULT MessageHandler(HWND window, + UINT message, + WPARAM wparam, + LPARAM lparam) noexcept; + }; } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.cpp b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.cpp index 9a253806..d3bc5961 100644 --- a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.cpp +++ b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.cpp @@ -1,40 +1,37 @@ +#include "../utils/util.h" #include "in_app_browser.h" #include "in_app_browser_channel_delegate.h" -#include "../utils/util.h" - namespace flutter_inappwebview_plugin { - InAppBrowserChannelDelegate::InAppBrowserChannelDelegate(const std::string& id, flutter::BinaryMessenger* messenger) - : ChannelDelegate(messenger, InAppBrowser::METHOD_CHANNEL_NAME_PREFIX + id) - { + InAppBrowserChannelDelegate::InAppBrowserChannelDelegate(const std::string& id, flutter::BinaryMessenger* messenger) + : ChannelDelegate(messenger, InAppBrowser::METHOD_CHANNEL_NAME_PREFIX + id) + {} - } + void InAppBrowserChannelDelegate::HandleMethodCall(const flutter::MethodCall& method_call, + std::unique_ptr> result) + { + result->NotImplemented(); + } - void InAppBrowserChannelDelegate::HandleMethodCall(const flutter::MethodCall& method_call, - std::unique_ptr> result) - { - result->NotImplemented(); + void InAppBrowserChannelDelegate::onBrowserCreated() const + { + if (!channel) { + return; } + channel->InvokeMethod("onBrowserCreated", nullptr); + } - void InAppBrowserChannelDelegate::onBrowserCreated() const - { - if (!channel) { - return; - } - channel->InvokeMethod("onBrowserCreated", nullptr); + void InAppBrowserChannelDelegate::onExit() const + { + if (!channel) { + return; } + channel->InvokeMethod("onExit", nullptr); + } - void InAppBrowserChannelDelegate::onExit() const - { - if (!channel) { - return; - } - channel->InvokeMethod("onExit", nullptr); - } - - InAppBrowserChannelDelegate::~InAppBrowserChannelDelegate() - { - debugLog("dealloc InAppBrowserChannelDelegate"); - } + InAppBrowserChannelDelegate::~InAppBrowserChannelDelegate() + { + debugLog("dealloc InAppBrowserChannelDelegate"); + } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.h b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.h index 488f69f1..d0032cff 100644 --- a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.h +++ b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.h @@ -8,19 +8,19 @@ namespace flutter_inappwebview_plugin { - class InAppBrowserChannelDelegate : public ChannelDelegate - { - public: - InAppBrowserChannelDelegate(const std::string& id, flutter::BinaryMessenger* messenger); - ~InAppBrowserChannelDelegate(); + class InAppBrowserChannelDelegate : public ChannelDelegate + { + public: + InAppBrowserChannelDelegate(const std::string& id, flutter::BinaryMessenger* messenger); + ~InAppBrowserChannelDelegate(); - void HandleMethodCall( - const flutter::MethodCall& method_call, - std::unique_ptr> result); + void HandleMethodCall( + const flutter::MethodCall& method_call, + std::unique_ptr> result); - void onBrowserCreated() const; - void onExit() const; - }; + void onBrowserCreated() const; + void onExit() const; + }; } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_CHANNEL_DELEGATE_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.cpp b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.cpp index a421aaee..1e08d7ba 100644 --- a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.cpp +++ b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.cpp @@ -1,53 +1,47 @@ -#include #include #include -#include - -#include "in_app_browser_manager.h" #include "../types/url_request.h" - #include "../utils/flutter.h" +#include "in_app_browser_manager.h" namespace flutter_inappwebview_plugin { - InAppBrowserManager::InAppBrowserManager(FlutterInappwebviewWindowsPlugin* plugin) - : plugin(plugin), ChannelDelegate(plugin->registrar->messenger(), InAppBrowserManager::METHOD_CHANNEL_NAME) - { + InAppBrowserManager::InAppBrowserManager(FlutterInappwebviewWindowsPlugin* plugin) + : plugin(plugin), ChannelDelegate(plugin->registrar->messenger(), InAppBrowserManager::METHOD_CHANNEL_NAME) + {} - } + void InAppBrowserManager::HandleMethodCall(const flutter::MethodCall& method_call, + std::unique_ptr> result) + { + if (method_call.method_name().compare("open") == 0) { + auto* arguments = std::get_if(method_call.arguments()); + open(arguments); + result->Success(flutter::EncodableValue(true)); + } + else { + result->NotImplemented(); + } + } - void InAppBrowserManager::HandleMethodCall(const flutter::MethodCall& method_call, - std::unique_ptr> result) - { - if (method_call.method_name().compare("open") == 0) { - auto* arguments = std::get_if(method_call.arguments()); - open(arguments); - result->Success(flutter::EncodableValue(true)); - } - else { - result->NotImplemented(); - } - } + void InAppBrowserManager::open(const flutter::EncodableMap* arguments) + { + auto id = get_fl_map_value(*arguments, "id"); + auto urlRequestMap = get_optional_fl_map_value(*arguments, "urlRequest"); + std::optional urlRequest = urlRequestMap.has_value() ? std::make_optional(urlRequestMap.value()) : std::optional{}; - void InAppBrowserManager::open(const flutter::EncodableMap* arguments) - { - auto id = get_fl_map_value(*arguments, "id"); - auto urlRequestMap = get_optional_fl_map_value(*arguments, "urlRequest"); - std::optional urlRequest = urlRequestMap.has_value() ? std::make_optional(urlRequestMap.value()) : std::optional{}; + InAppBrowserCreationParams params = { + id, + urlRequest + }; + auto inAppBrowser = std::make_unique(plugin, params); + browsers.insert({ id, std::move(inAppBrowser) }); + } - InAppBrowserCreationParams params = { - id, - urlRequest - }; - auto inAppBrowser = std::make_unique(plugin, params); - browsers.insert({ id, std::move(inAppBrowser) }); - } - - InAppBrowserManager::~InAppBrowserManager() - { - debugLog("dealloc InAppBrowserManager"); - browsers.clear(); - plugin = nullptr; - } + InAppBrowserManager::~InAppBrowserManager() + { + debugLog("dealloc InAppBrowserManager"); + browsers.clear(); + plugin = nullptr; + } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.h b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.h index b0093c51..91f813e2 100644 --- a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.h +++ b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.h @@ -1,35 +1,33 @@ #ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_MANAGER_H_ #define FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_MANAGER_H_ -#include -#include #include #include +#include +#include #include "../flutter_inappwebview_windows_plugin.h" - -#include "in_app_browser.h" - #include "../types/channel_delegate.h" +#include "in_app_browser.h" namespace flutter_inappwebview_plugin { - class InAppBrowserManager : public ChannelDelegate - { - public: - static inline const std::string METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappbrowser"; + class InAppBrowserManager : public ChannelDelegate + { + public: + static inline const std::string METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappbrowser"; - FlutterInappwebviewWindowsPlugin* plugin; - std::map> browsers; + FlutterInappwebviewWindowsPlugin* plugin; + std::map> browsers; - InAppBrowserManager(FlutterInappwebviewWindowsPlugin* plugin); - ~InAppBrowserManager(); + InAppBrowserManager(FlutterInappwebviewWindowsPlugin* plugin); + ~InAppBrowserManager(); - void HandleMethodCall( - const flutter::MethodCall& method_call, - std::unique_ptr> result); + void HandleMethodCall( + const flutter::MethodCall& method_call, + std::unique_ptr> result); - void open(const flutter::EncodableMap* arguments); - }; + void open(const flutter::EncodableMap* arguments); + }; } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_MANAGER_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.cpp b/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.cpp index 51187943..2902c704 100644 --- a/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.cpp +++ b/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.cpp @@ -1,258 +1,266 @@ #pragma comment(lib, "Shlwapi.lib") -#include "in_app_webview.h" +#include #include #include -#include + +#include "../types/web_resource_error.h" +#include "../types/web_resource_request.h" #include "../utils/strconv.h" #include "../utils/util.h" -#include "../types/web_resource_request.h" -#include "../types/web_resource_error.h" +#include "in_app_webview.h" namespace flutter_inappwebview_plugin { - using namespace Microsoft::WRL; + using namespace Microsoft::WRL; - InAppWebView::InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant& id, const HWND parentWindow, const std::function completionHandler) - : plugin(plugin), id(id), channelDelegate(std::make_unique(this, plugin->registrar->messenger())) - { - createWebView(parentWindow, completionHandler); - } + InAppWebView::InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant& id, const HWND parentWindow, const std::function completionHandler) + : plugin(plugin), id(id), channelDelegate(std::make_unique(this, plugin->registrar->messenger())) + { + createWebView(parentWindow, completionHandler); + } - InAppWebView::InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant& id, const HWND parentWindow, const std::string& channelName, const std::function completionHandler) - : plugin(plugin), id(id), channelDelegate(std::make_unique(this, plugin->registrar->messenger(), channelName)) - { - createWebView(parentWindow, completionHandler); - } + InAppWebView::InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant& id, const HWND parentWindow, const std::string& channelName, const std::function completionHandler) + : plugin(plugin), id(id), channelDelegate(std::make_unique(this, plugin->registrar->messenger(), channelName)) + { + createWebView(parentWindow, completionHandler); + } - void InAppWebView::createWebView(const HWND parentWindow, const std::function completionHandler) - { - CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr, - Callback( - [parentWindow, completionHandler, this](HRESULT result, ICoreWebView2Environment* env) -> HRESULT { - webViewEnv = env; - // Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window HWND - env->CreateCoreWebView2Controller(parentWindow, Callback( - [parentWindow, completionHandler, this](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT { - if (controller != nullptr) { - webViewController = controller; - webViewController->get_CoreWebView2(webView.put()); - } + void InAppWebView::createWebView(const HWND parentWindow, const std::function completionHandler) + { + CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr, + Callback( + [parentWindow, completionHandler, this](HRESULT result, ICoreWebView2Environment* env) -> HRESULT + { + webViewEnv = env; + // Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window HWND + env->CreateCoreWebView2Controller(parentWindow, Callback( + [parentWindow, completionHandler, this](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT + { + if (controller != nullptr) { + webViewController = controller; + webViewController->get_CoreWebView2(webView.put()); + } - // Resize WebView to fit the bounds of the parent window - RECT bounds; - GetClientRect(parentWindow, &bounds); - webViewController->put_Bounds(bounds); + // Resize WebView to fit the bounds of the parent window + RECT bounds; + GetClientRect(parentWindow, &bounds); + webViewController->put_Bounds(bounds); - registerEventHandlers(); + registerEventHandlers(); - completionHandler(); + completionHandler(); - return S_OK; - }).Get()); - return S_OK; - }).Get()); - } + return S_OK; + }).Get()); + return S_OK; + }).Get()); + } - void InAppWebView::registerEventHandlers() - { - if (!webView) { - return; - } + void InAppWebView::registerEventHandlers() + { + if (!webView) { + return; + } - webView->add_NavigationStarting( - Callback( - [this](ICoreWebView2* sender, ICoreWebView2NavigationStartingEventArgs* args) { - if (!channelDelegate) { - args->put_Cancel(false); - return S_OK; - } - - wil::unique_cotaskmem_string uri = nullptr; - std::optional url = SUCCEEDED(args->get_Uri(&uri)) ? wide_to_utf8(uri.get()) : std::optional{}; + webView->add_NavigationStarting( + Callback( + [this](ICoreWebView2* sender, ICoreWebView2NavigationStartingEventArgs* args) + { + if (!channelDelegate) { + args->put_Cancel(false); + return S_OK; + } - wil::unique_cotaskmem_string requestMethod = nullptr; - wil::com_ptr requestHeaders = nullptr; - std::optional> headers = std::optional>{}; - if (SUCCEEDED(args->get_RequestHeaders(&requestHeaders))) { - headers = std::make_optional>({}); - wil::com_ptr iterator; - requestHeaders->GetIterator(&iterator); - BOOL hasCurrent = FALSE; - while (SUCCEEDED(iterator->get_HasCurrentHeader(&hasCurrent)) && hasCurrent) - { - wil::unique_cotaskmem_string name; - wil::unique_cotaskmem_string value; + wil::unique_cotaskmem_string uri = nullptr; + std::optional url = SUCCEEDED(args->get_Uri(&uri)) ? wide_to_utf8(uri.get()) : std::optional{}; - if (SUCCEEDED(iterator->GetCurrentHeader(&name, &value))) { - headers->insert({ wide_to_utf8(name.get()), wide_to_utf8(value.get()) }); - } + wil::unique_cotaskmem_string requestMethod = nullptr; + wil::com_ptr requestHeaders = nullptr; + std::optional> headers = std::optional>{}; + if (SUCCEEDED(args->get_RequestHeaders(&requestHeaders))) { + headers = std::make_optional>({}); + wil::com_ptr iterator; + requestHeaders->GetIterator(&iterator); + BOOL hasCurrent = FALSE; + while (SUCCEEDED(iterator->get_HasCurrentHeader(&hasCurrent)) && hasCurrent) { + wil::unique_cotaskmem_string name; + wil::unique_cotaskmem_string value; - BOOL hasNext = FALSE; - iterator->MoveNext(&hasNext); - } + if (SUCCEEDED(iterator->GetCurrentHeader(&name, &value))) { + headers->insert({ wide_to_utf8(name.get()), wide_to_utf8(value.get()) }); + } - requestHeaders->GetHeader(L"Flutter-InAppWebView-Request-Method", &requestMethod); - requestHeaders->RemoveHeader(L"Flutter-InAppWebView-Request-Method"); - } + BOOL hasNext = FALSE; + iterator->MoveNext(&hasNext); + } - std::optional method = requestMethod ? wide_to_utf8(requestMethod.get()) : std::optional{}; + requestHeaders->GetHeader(L"Flutter-InAppWebView-Request-Method", &requestMethod); + requestHeaders->RemoveHeader(L"Flutter-InAppWebView-Request-Method"); + } - auto urlRequest = std::make_shared(url, method, headers, std::nullopt); - auto navigationAction = std::make_shared( - urlRequest, - true - ); + std::optional method = requestMethod ? wide_to_utf8(requestMethod.get()) : std::optional{}; - UINT64 navigationId; - if (SUCCEEDED(args->get_NavigationId(&navigationId))) { - navigationActions.insert({navigationId, navigationAction}); - } + auto urlRequest = std::make_shared(url, method, headers, std::nullopt); + auto navigationAction = std::make_shared( + urlRequest, + true + ); - if (callShouldOverrideUrlLoading && requestMethod == nullptr) { - // for some reason, we can't cancel and load an URL with other HTTP methods than GET, - // so ignore the shouldOverrideUrlLoading event. - - auto callback = std::make_unique(); - callback->nonNullSuccess = [this, urlRequest](const NavigationActionPolicy actionPolicy) { - callShouldOverrideUrlLoading = false; - if (actionPolicy == allow) { - loadUrl(*urlRequest); - } - return false; - }; - auto defaultBehaviour = [this, urlRequest](const std::optional actionPolicy) { - callShouldOverrideUrlLoading = false; - loadUrl(*urlRequest); - }; - callback->defaultBehaviour = defaultBehaviour; - callback->error = [defaultBehaviour](const std::string& error_code, const std::string& error_message, const flutter::EncodableValue* error_details) { - debugLog(error_code + ", " + error_message); - defaultBehaviour(std::nullopt); - }; - channelDelegate->shouldOverrideUrlLoading(std::move(navigationAction), std::move(callback)); - args->put_Cancel(true); - } - else { - callShouldOverrideUrlLoading = true; - channelDelegate->onLoadStart(url); - args->put_Cancel(false); - } + UINT64 navigationId; + if (SUCCEEDED(args->get_NavigationId(&navigationId))) { + navigationActions.insert({ navigationId, navigationAction }); + } - return S_OK; - } - ).Get(), nullptr); + if (callShouldOverrideUrlLoading && requestMethod == nullptr) { + // for some reason, we can't cancel and load an URL with other HTTP methods than GET, + // so ignore the shouldOverrideUrlLoading event. - webView->add_NavigationCompleted( - Callback( - [this](ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args) { - std::shared_ptr navigationAction; - UINT64 navigationId; - if (SUCCEEDED(args->get_NavigationId(&navigationId))) { - navigationAction = map_at_or_null(navigationActions, navigationId); - if (navigationAction) { - navigationActions.erase(navigationId); - } - } + auto callback = std::make_unique(); + callback->nonNullSuccess = [this, urlRequest](const NavigationActionPolicy actionPolicy) + { + callShouldOverrideUrlLoading = false; + if (actionPolicy == allow) { + loadUrl(*urlRequest); + } + return false; + }; + auto defaultBehaviour = [this, urlRequest](const std::optional actionPolicy) + { + callShouldOverrideUrlLoading = false; + loadUrl(*urlRequest); + }; + callback->defaultBehaviour = defaultBehaviour; + callback->error = [defaultBehaviour](const std::string& error_code, const std::string& error_message, const flutter::EncodableValue* error_details) + { + debugLog(error_code + ", " + error_message); + defaultBehaviour(std::nullopt); + }; + channelDelegate->shouldOverrideUrlLoading(std::move(navigationAction), std::move(callback)); + args->put_Cancel(true); + } + else { + callShouldOverrideUrlLoading = true; + channelDelegate->onLoadStart(url); + args->put_Cancel(false); + } - COREWEBVIEW2_WEB_ERROR_STATUS webErrorType = COREWEBVIEW2_WEB_ERROR_STATUS_UNKNOWN; - args->get_WebErrorStatus(&webErrorType); + return S_OK; + } + ).Get(), nullptr); - BOOL isSuccess; - args->get_IsSuccess(&isSuccess); + webView->add_NavigationCompleted( + Callback( + [this](ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args) + { + std::shared_ptr navigationAction; + UINT64 navigationId; + if (SUCCEEDED(args->get_NavigationId(&navigationId))) { + navigationAction = map_at_or_null(navigationActions, navigationId); + if (navigationAction) { + navigationActions.erase(navigationId); + } + } - if (channelDelegate) { - LPWSTR uri = nullptr; - std::optional url = SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(std::wstring(uri)) : std::optional{}; - if (isSuccess) { - channelDelegate->onLoadStop(url); - } - else if (!InAppWebView::isSslError(webErrorType) && navigationAction) { - auto webResourceRequest = std::make_unique(url, navigationAction->request->method, navigationAction->request->headers, navigationAction->isForMainFrame); - int httpStatusCode = 0; - wil::com_ptr args2; - if (SUCCEEDED(args->QueryInterface(IID_PPV_ARGS(&args2))) && SUCCEEDED(args2->get_HttpStatusCode(&httpStatusCode)) && httpStatusCode >= 400) { - auto webResourceResponse = std::make_unique(httpStatusCode); - channelDelegate->onReceivedHttpError(std::move(webResourceRequest), std::move(webResourceResponse)); - } - else if (httpStatusCode < 400) { - auto webResourceError = std::make_unique(WebErrorStatusDescription[webErrorType], webErrorType); - channelDelegate->onReceivedError(std::move(webResourceRequest), std::move(webResourceError)); - } - } - } + COREWEBVIEW2_WEB_ERROR_STATUS webErrorType = COREWEBVIEW2_WEB_ERROR_STATUS_UNKNOWN; + args->get_WebErrorStatus(&webErrorType); - return S_OK; - } - ).Get(), nullptr); - } + BOOL isSuccess; + args->get_IsSuccess(&isSuccess); - std::optional InAppWebView::getUrl() const - { - LPWSTR uri = nullptr; - return SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(uri) : std::optional{}; - } + if (channelDelegate) { + LPWSTR uri = nullptr; + std::optional url = SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(std::wstring(uri)) : std::optional{}; + if (isSuccess) { + channelDelegate->onLoadStop(url); + } + else if (!InAppWebView::isSslError(webErrorType) && navigationAction) { + auto webResourceRequest = std::make_unique(url, navigationAction->request->method, navigationAction->request->headers, navigationAction->isForMainFrame); + int httpStatusCode = 0; + wil::com_ptr args2; + if (SUCCEEDED(args->QueryInterface(IID_PPV_ARGS(&args2))) && SUCCEEDED(args2->get_HttpStatusCode(&httpStatusCode)) && httpStatusCode >= 400) { + auto webResourceResponse = std::make_unique(httpStatusCode); + channelDelegate->onReceivedHttpError(std::move(webResourceRequest), std::move(webResourceResponse)); + } + else if (httpStatusCode < 400) { + auto webResourceError = std::make_unique(WebErrorStatusDescription[webErrorType], webErrorType); + channelDelegate->onReceivedError(std::move(webResourceRequest), std::move(webResourceError)); + } + } + } - void InAppWebView::loadUrl(const URLRequest& urlRequest) const - { - if (!webView || !urlRequest.url.has_value()) { - return; - } + return S_OK; + } + ).Get(), nullptr); + } - std::wstring url = ansi_to_wide(urlRequest.url.value()); + std::optional InAppWebView::getUrl() const + { + LPWSTR uri = nullptr; + return SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(uri) : std::optional{}; + } - wil::com_ptr webViewEnv2; - wil::com_ptr webView2; - if (SUCCEEDED(webViewEnv->QueryInterface(IID_PPV_ARGS(&webViewEnv2))) && SUCCEEDED(webView->QueryInterface(IID_PPV_ARGS(&webView2)))) { - wil::com_ptr webResourceRequest; - std::wstring method = urlRequest.method.has_value() ? ansi_to_wide(urlRequest.method.value()) : L"GET"; - - wil::com_ptr postDataStream = nullptr; - if (urlRequest.body.has_value()) { - auto postData = std::string(urlRequest.body->begin(), urlRequest.body->end()); - postDataStream = SHCreateMemStream( - reinterpret_cast(postData.data()), static_cast(postData.length())); - } - webViewEnv2->CreateWebResourceRequest( - url.c_str(), - method.c_str(), - postDataStream.get(), - L"", - &webResourceRequest - ); - wil::com_ptr requestHeaders; - if (SUCCEEDED(webResourceRequest->get_Headers(&requestHeaders))) { - if (method.compare(L"GET") != 0) { - requestHeaders->SetHeader(L"Flutter-InAppWebView-Request-Method", method.c_str()); - } - if (urlRequest.headers.has_value()) { - auto& headers = urlRequest.headers.value(); - for (auto const& [key, val] : headers) { - requestHeaders->SetHeader(ansi_to_wide(key).c_str(), ansi_to_wide(val).c_str()); - } - } - } - webView2->NavigateWithWebResourceRequest(webResourceRequest.get()); - } - else { - webView->Navigate(url.c_str()); - } - } + void InAppWebView::loadUrl(const URLRequest& urlRequest) const + { + if (!webView || !urlRequest.url.has_value()) { + return; + } - bool InAppWebView::isSslError(const COREWEBVIEW2_WEB_ERROR_STATUS& webErrorStatus) { - return webErrorStatus >= COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_COMMON_NAME_IS_INCORRECT && webErrorStatus <= COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_IS_INVALID; - } + std::wstring url = ansi_to_wide(urlRequest.url.value()); - InAppWebView::~InAppWebView() - { - debugLog("dealloc InAppWebView"); - if (webView) { - webView->Stop(); - } - if (webViewController) { - webViewController->Close(); - } - navigationActions.clear(); - plugin = nullptr; - } + wil::com_ptr webViewEnv2; + wil::com_ptr webView2; + if (SUCCEEDED(webViewEnv->QueryInterface(IID_PPV_ARGS(&webViewEnv2))) && SUCCEEDED(webView->QueryInterface(IID_PPV_ARGS(&webView2)))) { + wil::com_ptr webResourceRequest; + std::wstring method = urlRequest.method.has_value() ? ansi_to_wide(urlRequest.method.value()) : L"GET"; + + wil::com_ptr postDataStream = nullptr; + if (urlRequest.body.has_value()) { + auto postData = std::string(urlRequest.body->begin(), urlRequest.body->end()); + postDataStream = SHCreateMemStream( + reinterpret_cast(postData.data()), static_cast(postData.length())); + } + webViewEnv2->CreateWebResourceRequest( + url.c_str(), + method.c_str(), + postDataStream.get(), + L"", + &webResourceRequest + ); + wil::com_ptr requestHeaders; + if (SUCCEEDED(webResourceRequest->get_Headers(&requestHeaders))) { + if (method.compare(L"GET") != 0) { + requestHeaders->SetHeader(L"Flutter-InAppWebView-Request-Method", method.c_str()); + } + if (urlRequest.headers.has_value()) { + auto& headers = urlRequest.headers.value(); + for (auto const& [key, val] : headers) { + requestHeaders->SetHeader(ansi_to_wide(key).c_str(), ansi_to_wide(val).c_str()); + } + } + } + webView2->NavigateWithWebResourceRequest(webResourceRequest.get()); + } + else { + webView->Navigate(url.c_str()); + } + } + + bool InAppWebView::isSslError(const COREWEBVIEW2_WEB_ERROR_STATUS& webErrorStatus) + { + return webErrorStatus >= COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_COMMON_NAME_IS_INCORRECT && webErrorStatus <= COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_IS_INVALID; + } + + InAppWebView::~InAppWebView() + { + debugLog("dealloc InAppWebView"); + if (webView) { + webView->Stop(); + } + if (webViewController) { + webViewController->Close(); + } + navigationActions.clear(); + plugin = nullptr; + } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.h b/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.h index 145b2512..2043a469 100644 --- a/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.h +++ b/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.h @@ -2,43 +2,43 @@ #define FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_WEBVIEW_H_ #include - #include #include -#include "../types/url_request.h" -#include "../types/navigation_action.h" -#include "webview_channel_delegate.h" + #include "../flutter_inappwebview_windows_plugin.h" +#include "../types/navigation_action.h" +#include "../types/url_request.h" +#include "webview_channel_delegate.h" namespace flutter_inappwebview_plugin { - using namespace Microsoft::WRL; + using namespace Microsoft::WRL; - class InAppWebView - { - public: - static inline const std::string METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_"; + class InAppWebView + { + public: + static inline const std::string METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_"; - const FlutterInappwebviewWindowsPlugin* plugin; - const std::variant id; - wil::com_ptr webViewEnv; - wil::com_ptr webViewController; - wil::com_ptr webView; - const std::unique_ptr channelDelegate; - std::map> navigationActions = {}; + const FlutterInappwebviewWindowsPlugin* plugin; + const std::variant id; + wil::com_ptr webViewEnv; + wil::com_ptr webViewController; + wil::com_ptr webView; + const std::unique_ptr channelDelegate; + std::map> navigationActions = {}; - InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant& id, const HWND parentWindow, const std::function completionHandler); - InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant& id, const HWND parentWindow, const std::string& channelName, const std::function completionHandler); - ~InAppWebView(); + InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant& id, const HWND parentWindow, const std::function completionHandler); + InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant& id, const HWND parentWindow, const std::string& channelName, const std::function completionHandler); + ~InAppWebView(); - std::optional getUrl() const; - void loadUrl(const URLRequest& urlRequest) const; + std::optional getUrl() const; + void loadUrl(const URLRequest& urlRequest) const; - static bool isSslError(const COREWEBVIEW2_WEB_ERROR_STATUS& webErrorStatus); - private: - bool callShouldOverrideUrlLoading = true; - void createWebView(const HWND parentWindow, const std::function completionHandler); - void InAppWebView::registerEventHandlers(); - }; + static bool isSslError(const COREWEBVIEW2_WEB_ERROR_STATUS& webErrorStatus); + private: + bool callShouldOverrideUrlLoading = true; + void createWebView(const HWND parentWindow, const std::function completionHandler); + void InAppWebView::registerEventHandlers(); + }; } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_WEBVIEW_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.cpp b/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.cpp index 2e6f0d9f..cb6d4f24 100644 --- a/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.cpp +++ b/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.cpp @@ -1,119 +1,116 @@ +#include "../types/base_callback_result.h" +#include "../utils/flutter.h" +#include "../utils/strconv.h" #include "in_app_webview.h" #include "webview_channel_delegate.h" -#include "../utils/flutter.h" -#include "../utils/strconv.h" -#include "../types/base_callback_result.h" - namespace flutter_inappwebview_plugin { - WebViewChannelDelegate::WebViewChannelDelegate(InAppWebView* webView, flutter::BinaryMessenger* messenger) - : webView(webView), ChannelDelegate(messenger, InAppWebView::METHOD_CHANNEL_NAME_PREFIX + variant_to_string(webView->id)) - { + WebViewChannelDelegate::WebViewChannelDelegate(InAppWebView* webView, flutter::BinaryMessenger* messenger) + : webView(webView), ChannelDelegate(messenger, InAppWebView::METHOD_CHANNEL_NAME_PREFIX + variant_to_string(webView->id)) + {} + WebViewChannelDelegate::WebViewChannelDelegate(InAppWebView* webView, flutter::BinaryMessenger* messenger, const std::string& name) + : webView(webView), ChannelDelegate(messenger, name) + {} + + WebViewChannelDelegate::ShouldOverrideUrlLoadingCallback::ShouldOverrideUrlLoadingCallback() + { + decodeResult = [](const flutter::EncodableValue* value) + { + if (value->IsNull()) { + return cancel; + } + auto navigationPolicy = std::get(*value); + return static_cast(navigationPolicy); + }; + } + + void WebViewChannelDelegate::HandleMethodCall(const flutter::MethodCall& method_call, + std::unique_ptr> result) + { + if (!webView) { + result->Success(); + return; } - WebViewChannelDelegate::WebViewChannelDelegate(InAppWebView* webView, flutter::BinaryMessenger* messenger, const std::string& name) - : webView(webView), ChannelDelegate(messenger, name) - { - - } - - WebViewChannelDelegate::ShouldOverrideUrlLoadingCallback::ShouldOverrideUrlLoadingCallback() { - decodeResult = [](const flutter::EncodableValue* value) { - if (value->IsNull()) { - return cancel; - } - auto navigationPolicy = std::get(*value); - return static_cast(navigationPolicy); - }; - } - - void WebViewChannelDelegate::HandleMethodCall(const flutter::MethodCall& method_call, - std::unique_ptr> result) - { - if (!webView) { - result->Success(); - return; - } - - if (method_call.method_name().compare("getUrl") == 0) { - result->Success(make_fl_value(webView->getUrl())); - } - else if (method_call.method_name().compare("loadUrl") == 0) { - auto& arguments = std::get(*method_call.arguments()); - auto urlRequest = std::make_unique(get_fl_map_value(arguments, "urlRequest")); - webView->loadUrl(*urlRequest); - result->Success(make_fl_value(true)); - } - else { - result->NotImplemented(); - } - } - - void WebViewChannelDelegate::onLoadStart(const std::optional& url) const - { - if (!channel) { - return; - } - - auto arguments = std::make_unique(flutter::EncodableMap { - {flutter::EncodableValue("url"), make_fl_value(url)}, - }); - channel->InvokeMethod("onLoadStart", std::move(arguments)); - } - - void WebViewChannelDelegate::onLoadStop(const std::optional& url) const - { - if (!channel) { - return; - } - - auto arguments = std::make_unique(flutter::EncodableMap{ - {flutter::EncodableValue("url"), make_fl_value(url)}, - }); - channel->InvokeMethod("onLoadStop", std::move(arguments)); - } - - void WebViewChannelDelegate::shouldOverrideUrlLoading(std::shared_ptr navigationAction, std::unique_ptr callback) const - { - if (!channel) { - return; - } - - auto arguments = std::make_unique(navigationAction->toEncodableMap()); - channel->InvokeMethod("shouldOverrideUrlLoading", std::move(arguments), std::move(callback)); - } - - void WebViewChannelDelegate::onReceivedError(std::shared_ptr request, std::shared_ptr error) const - { - if (!channel) { - return; - } - - auto arguments = std::make_unique(flutter::EncodableMap{ - {flutter::EncodableValue("request"), request->toEncodableMap()}, - {flutter::EncodableValue("error"), error->toEncodableMap()}, - }); - channel->InvokeMethod("onReceivedError", std::move(arguments)); - } - - void WebViewChannelDelegate::onReceivedHttpError(std::shared_ptr request, std::shared_ptr errorResponse) const - { - if (!channel) { - return; - } - - auto arguments = std::make_unique(flutter::EncodableMap{ - {flutter::EncodableValue("request"), request->toEncodableMap()}, - {flutter::EncodableValue("errorResponse"), errorResponse->toEncodableMap()}, - }); - channel->InvokeMethod("onReceivedHttpError", std::move(arguments)); - } - - WebViewChannelDelegate::~WebViewChannelDelegate() - { - debugLog("dealloc WebViewChannelDelegate"); - webView = nullptr; + if (method_call.method_name().compare("getUrl") == 0) { + result->Success(make_fl_value(webView->getUrl())); } + else if (method_call.method_name().compare("loadUrl") == 0) { + auto& arguments = std::get(*method_call.arguments()); + auto urlRequest = std::make_unique(get_fl_map_value(arguments, "urlRequest")); + webView->loadUrl(*urlRequest); + result->Success(make_fl_value(true)); + } + else { + result->NotImplemented(); + } + } + + void WebViewChannelDelegate::onLoadStart(const std::optional& url) const + { + if (!channel) { + return; + } + + auto arguments = std::make_unique(flutter::EncodableMap{ + {flutter::EncodableValue("url"), make_fl_value(url)}, + }); + channel->InvokeMethod("onLoadStart", std::move(arguments)); + } + + void WebViewChannelDelegate::onLoadStop(const std::optional& url) const + { + if (!channel) { + return; + } + + auto arguments = std::make_unique(flutter::EncodableMap{ + {flutter::EncodableValue("url"), make_fl_value(url)}, + }); + channel->InvokeMethod("onLoadStop", std::move(arguments)); + } + + void WebViewChannelDelegate::shouldOverrideUrlLoading(std::shared_ptr navigationAction, std::unique_ptr callback) const + { + if (!channel) { + return; + } + + auto arguments = std::make_unique(navigationAction->toEncodableMap()); + channel->InvokeMethod("shouldOverrideUrlLoading", std::move(arguments), std::move(callback)); + } + + void WebViewChannelDelegate::onReceivedError(std::shared_ptr request, std::shared_ptr error) const + { + if (!channel) { + return; + } + + auto arguments = std::make_unique(flutter::EncodableMap{ + {flutter::EncodableValue("request"), request->toEncodableMap()}, + {flutter::EncodableValue("error"), error->toEncodableMap()}, + }); + channel->InvokeMethod("onReceivedError", std::move(arguments)); + } + + void WebViewChannelDelegate::onReceivedHttpError(std::shared_ptr request, std::shared_ptr errorResponse) const + { + if (!channel) { + return; + } + + auto arguments = std::make_unique(flutter::EncodableMap{ + {flutter::EncodableValue("request"), request->toEncodableMap()}, + {flutter::EncodableValue("errorResponse"), errorResponse->toEncodableMap()}, + }); + channel->InvokeMethod("onReceivedHttpError", std::move(arguments)); + } + + WebViewChannelDelegate::~WebViewChannelDelegate() + { + debugLog("dealloc WebViewChannelDelegate"); + webView = nullptr; + } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.h b/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.h index 768c5191..7f950d66 100644 --- a/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.h +++ b/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.h @@ -4,44 +4,44 @@ #include #include -#include "../types/channel_delegate.h" #include "../types/base_callback_result.h" +#include "../types/channel_delegate.h" #include "../types/navigation_action.h" -#include "../types/web_resource_request.h" #include "../types/web_resource_error.h" +#include "../types/web_resource_request.h" #include "../types/web_resource_response.h" namespace flutter_inappwebview_plugin { - class InAppWebView; + class InAppWebView; - enum NavigationActionPolicy {cancel = 0, allow = 1}; + enum NavigationActionPolicy { cancel = 0, allow = 1 }; - class WebViewChannelDelegate : public ChannelDelegate - { + class WebViewChannelDelegate : public ChannelDelegate + { + public: + InAppWebView* webView; + + class ShouldOverrideUrlLoadingCallback : public BaseCallbackResult { public: - InAppWebView* webView; - - class ShouldOverrideUrlLoadingCallback : public BaseCallbackResult { - public: - ShouldOverrideUrlLoadingCallback(); - ~ShouldOverrideUrlLoadingCallback() = default; - }; - - WebViewChannelDelegate(InAppWebView* webView, flutter::BinaryMessenger* messenger); - WebViewChannelDelegate(InAppWebView* webView, flutter::BinaryMessenger* messenger, const std::string& name); - ~WebViewChannelDelegate(); - - void HandleMethodCall( - const flutter::MethodCall& method_call, - std::unique_ptr> result); - - void onLoadStart(const std::optional& url) const; - void onLoadStop(const std::optional& url) const; - void shouldOverrideUrlLoading(std::shared_ptr navigationAction, std::unique_ptr callback) const; - void WebViewChannelDelegate::onReceivedError(std::shared_ptr request, std::shared_ptr error) const; - void WebViewChannelDelegate::onReceivedHttpError(std::shared_ptr request, std::shared_ptr error) const; + ShouldOverrideUrlLoadingCallback(); + ~ShouldOverrideUrlLoadingCallback() = default; }; + + WebViewChannelDelegate(InAppWebView* webView, flutter::BinaryMessenger* messenger); + WebViewChannelDelegate(InAppWebView* webView, flutter::BinaryMessenger* messenger, const std::string& name); + ~WebViewChannelDelegate(); + + void HandleMethodCall( + const flutter::MethodCall& method_call, + std::unique_ptr> result); + + void onLoadStart(const std::optional& url) const; + void onLoadStop(const std::optional& url) const; + void shouldOverrideUrlLoading(std::shared_ptr navigationAction, std::unique_ptr callback) const; + void WebViewChannelDelegate::onReceivedError(std::shared_ptr request, std::shared_ptr error) const; + void WebViewChannelDelegate::onReceivedHttpError(std::shared_ptr request, std::shared_ptr error) const; + }; } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_CHANNEL_DELEGATE_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/include/flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h b/flutter_inappwebview_windows/windows/include/flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h index 019d5283..6a318ec0 100644 --- a/flutter_inappwebview_windows/windows/include/flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h +++ b/flutter_inappwebview_windows/windows/include/flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h @@ -13,7 +13,7 @@ extern "C" { #endif -FLUTTER_PLUGIN_EXPORT void FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar( + FLUTTER_PLUGIN_EXPORT void FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar( FlutterDesktopPluginRegistrarRef registrar); #if defined(__cplusplus) diff --git a/flutter_inappwebview_windows/windows/types/base_callback_result.h b/flutter_inappwebview_windows/windows/types/base_callback_result.h index 66958b5a..d156e1e6 100644 --- a/flutter_inappwebview_windows/windows/types/base_callback_result.h +++ b/flutter_inappwebview_windows/windows/types/base_callback_result.h @@ -1,53 +1,57 @@ #ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_BASE_CALLBACK_RESULT_H_ #define FLUTTER_INAPPWEBVIEW_PLUGIN_BASE_CALLBACK_RESULT_H_ -#include #include +#include #include namespace flutter_inappwebview_plugin { - template - class BaseCallbackResult : public flutter::MethodResultFunctions - { - public: - flutter::ResultHandlerError error; - flutter::ResultHandlerNotImplemented notImplemented; - std::function nonNullSuccess = [](const T result) { return true; }; - std::function nullSuccess = []() { return true; }; - std::function result)> defaultBehaviour = [](const std::optional result) {}; - std::function(const flutter::EncodableValue* result)> decodeResult = [](const flutter::EncodableValue* result) { return std::nullopt; }; + template + class BaseCallbackResult : public flutter::MethodResultFunctions + { + public: + flutter::ResultHandlerError error; + flutter::ResultHandlerNotImplemented notImplemented; + std::function nonNullSuccess = [](const T result) { return true; }; + std::function nullSuccess = []() { return true; }; + std::function result)> defaultBehaviour = [](const std::optional result) {}; + std::function(const flutter::EncodableValue* result)> decodeResult = [](const flutter::EncodableValue* result) { return std::nullopt; }; - BaseCallbackResult() : - MethodResultFunctions( - [this](const flutter::EncodableValue* val) { - std::optional result = decodeResult ? decodeResult(val) : std::nullopt; - auto shouldRunDefaultBehaviour = false; - if (result.has_value()) { - shouldRunDefaultBehaviour = nonNullSuccess ? nonNullSuccess(result.value()) : shouldRunDefaultBehaviour; - } - else { - shouldRunDefaultBehaviour = nullSuccess ? nullSuccess() : shouldRunDefaultBehaviour; - } - if (shouldRunDefaultBehaviour && defaultBehaviour) { - defaultBehaviour(result); - } - }, - [this](const std::string& error_code, const std::string& error_message, const flutter::EncodableValue* error_details) { - if (error) { - error(error_code, error_message, error_details); - } - }, - [this]() { - if (defaultBehaviour) { - defaultBehaviour(std::nullopt); - } - if (notImplemented) { - notImplemented(); - } - }) {}; - virtual ~BaseCallbackResult() {}; - }; + BaseCallbackResult() : + MethodResultFunctions( + [this](const flutter::EncodableValue* val) + { + std::optional result = decodeResult ? decodeResult(val) : std::nullopt; + auto shouldRunDefaultBehaviour = false; + if (result.has_value()) { + shouldRunDefaultBehaviour = nonNullSuccess ? nonNullSuccess(result.value()) : shouldRunDefaultBehaviour; + } + else { + shouldRunDefaultBehaviour = nullSuccess ? nullSuccess() : shouldRunDefaultBehaviour; + } + if (shouldRunDefaultBehaviour && defaultBehaviour) { + defaultBehaviour(result); + } + }, + [this](const std::string& error_code, const std::string& error_message, const flutter::EncodableValue* error_details) + { + if (error) { + error(error_code, error_message, error_details); + } + }, + [this]() + { + if (defaultBehaviour) { + defaultBehaviour(std::nullopt); + } + if (notImplemented) { + notImplemented(); + } + }) + {}; + virtual ~BaseCallbackResult() {}; + }; } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_BASE_CALLBACK_RESULT_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/channel_delegate.cpp b/flutter_inappwebview_windows/windows/types/channel_delegate.cpp index bdec9099..983a2366 100644 --- a/flutter_inappwebview_windows/windows/types/channel_delegate.cpp +++ b/flutter_inappwebview_windows/windows/types/channel_delegate.cpp @@ -1,37 +1,35 @@ #include #include -#include "channel_delegate.h" - #include "../utils/util.h" +#include "channel_delegate.h" namespace flutter_inappwebview_plugin { - ChannelDelegate::ChannelDelegate(flutter::BinaryMessenger* messenger, const std::string& name) : messenger(messenger) - { - channel = std::make_shared>( - this->messenger, name, - &flutter::StandardMethodCodec::GetInstance() - ); - channel->SetMethodCallHandler( - [this](const auto& call, auto result) { - this->HandleMethodCall(call, std::move(result)); - }); - } + ChannelDelegate::ChannelDelegate(flutter::BinaryMessenger* messenger, const std::string& name) : messenger(messenger) + { + channel = std::make_shared>( + this->messenger, name, + &flutter::StandardMethodCodec::GetInstance() + ); + channel->SetMethodCallHandler( + [this](const auto& call, auto result) + { + this->HandleMethodCall(call, std::move(result)); + }); + } - void ChannelDelegate::HandleMethodCall( - const flutter::MethodCall& method_call, - std::unique_ptr> result) - { + void ChannelDelegate::HandleMethodCall( + const flutter::MethodCall& method_call, + std::unique_ptr> result) + {} - } - - ChannelDelegate::~ChannelDelegate() - { - messenger = nullptr; - if (channel != nullptr) { - channel->SetMethodCallHandler(nullptr); - } - channel.reset(); - } + ChannelDelegate::~ChannelDelegate() + { + messenger = nullptr; + if (channel != nullptr) { + channel->SetMethodCallHandler(nullptr); + } + channel.reset(); + } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/channel_delegate.h b/flutter_inappwebview_windows/windows/types/channel_delegate.h index c637e02f..a412b7d1 100644 --- a/flutter_inappwebview_windows/windows/types/channel_delegate.h +++ b/flutter_inappwebview_windows/windows/types/channel_delegate.h @@ -5,21 +5,21 @@ namespace flutter_inappwebview_plugin { - class ChannelDelegate - { - using FlutterMethodChannel = std::shared_ptr>; + class ChannelDelegate + { + using FlutterMethodChannel = std::shared_ptr>; - public: - FlutterMethodChannel channel; - flutter::BinaryMessenger* messenger; + public: + FlutterMethodChannel channel; + flutter::BinaryMessenger* messenger; - ChannelDelegate(flutter::BinaryMessenger* messenger, const std::string& name); - virtual ~ChannelDelegate(); + ChannelDelegate(flutter::BinaryMessenger* messenger, const std::string& name); + virtual ~ChannelDelegate(); - virtual void HandleMethodCall( - const flutter::MethodCall& method_call, - std::unique_ptr> result); - }; + virtual void HandleMethodCall( + const flutter::MethodCall& method_call, + std::unique_ptr> result); + }; } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_CHANNEL_DELEGATE_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/navigation_action.cpp b/flutter_inappwebview_windows/windows/types/navigation_action.cpp index 9541dcdb..680d0483 100644 --- a/flutter_inappwebview_windows/windows/types/navigation_action.cpp +++ b/flutter_inappwebview_windows/windows/types/navigation_action.cpp @@ -1,20 +1,17 @@ +#include "../utils/flutter.h" #include "navigation_action.h" -#include "../utils/util.h" - namespace flutter_inappwebview_plugin { - NavigationAction::NavigationAction(std::shared_ptr request, const bool& isForMainFrame) - : request(std::move(request)), isForMainFrame(isForMainFrame) - { + NavigationAction::NavigationAction(std::shared_ptr request, const bool& isForMainFrame) + : request(std::move(request)), isForMainFrame(isForMainFrame) + {} - } - - flutter::EncodableMap NavigationAction::toEncodableMap() - { - return flutter::EncodableMap{ - {flutter::EncodableValue("request"), request->toEncodableMap()}, - {flutter::EncodableValue("isForMainFrame"), flutter::EncodableValue(isForMainFrame)} - }; - } + flutter::EncodableMap NavigationAction::toEncodableMap() const + { + return flutter::EncodableMap{ + {make_fl_value("request"), request->toEncodableMap()}, + {make_fl_value("isForMainFrame"), make_fl_value(isForMainFrame)} + }; + } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/navigation_action.h b/flutter_inappwebview_windows/windows/types/navigation_action.h index 974b4478..ae100e63 100644 --- a/flutter_inappwebview_windows/windows/types/navigation_action.h +++ b/flutter_inappwebview_windows/windows/types/navigation_action.h @@ -3,20 +3,22 @@ #include #include + #include "url_request.h" namespace flutter_inappwebview_plugin { - class NavigationAction - { - public: - const std::shared_ptr request; - const bool isForMainFrame; + class NavigationAction + { + public: + const std::shared_ptr request; + const bool isForMainFrame; - NavigationAction(std::shared_ptr request, const bool& isForMainFrame); - ~NavigationAction() = default; - flutter::EncodableMap toEncodableMap(); - }; + NavigationAction(std::shared_ptr request, const bool& isForMainFrame); + ~NavigationAction() = default; + + flutter::EncodableMap toEncodableMap() const; + }; } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_NAVIGATION_ACTION_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/url_request.cpp b/flutter_inappwebview_windows/windows/types/url_request.cpp index 01789955..ec997b24 100644 --- a/flutter_inappwebview_windows/windows/types/url_request.cpp +++ b/flutter_inappwebview_windows/windows/types/url_request.cpp @@ -1,32 +1,27 @@ -#include "url_request.h" - #include "../utils/flutter.h" +#include "url_request.h" namespace flutter_inappwebview_plugin { - URLRequest::URLRequest(const std::optional& url, const std::optional& method, - const std::optional>& headers, const std::optional>& body) - : url(url), method(method), headers(headers), body(body) - { + URLRequest::URLRequest(const std::optional& url, const std::optional& method, + const std::optional>& headers, const std::optional>& body) + : url(url), method(method), headers(headers), body(body) + {} - } + URLRequest::URLRequest(const flutter::EncodableMap& map) + : url(get_optional_fl_map_value(map, "url")), + method(get_optional_fl_map_value(map, "method")), + headers(get_optional_fl_map_value(map, "headers")), + body(get_optional_fl_map_value>(map, "body")) + {} - URLRequest::URLRequest(const flutter::EncodableMap& map) - : url(get_optional_fl_map_value(map, "url")), - method(get_optional_fl_map_value(map, "method")), - headers(get_optional_fl_map_value(map, "headers")), - body(get_optional_fl_map_value>(map, "body")) - { - - } - - flutter::EncodableMap URLRequest::toEncodableMap() - { - return flutter::EncodableMap{ - {make_fl_value("url"), make_fl_value(url)}, - {make_fl_value("method"), make_fl_value(method)}, - {make_fl_value("headers"), make_fl_value(headers)}, - {make_fl_value("body"), make_fl_value(body)} - }; - } + flutter::EncodableMap URLRequest::toEncodableMap() const + { + return flutter::EncodableMap{ + {make_fl_value("url"), make_fl_value(url)}, + {make_fl_value("method"), make_fl_value(method)}, + {make_fl_value("headers"), make_fl_value(headers)}, + {make_fl_value("body"), make_fl_value(body)} + }; + } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/url_request.h b/flutter_inappwebview_windows/windows/types/url_request.h index 0bebc7ad..37373d1c 100644 --- a/flutter_inappwebview_windows/windows/types/url_request.h +++ b/flutter_inappwebview_windows/windows/types/url_request.h @@ -2,25 +2,27 @@ #define FLUTTER_INAPPWEBVIEW_PLUGIN_URL_REQUEST_H_ #include - #include +#include "../utils/flutter.h" + namespace flutter_inappwebview_plugin { - class URLRequest - { - public: - const std::optional url; - const std::optional method; - const std::optional> headers; - const std::optional> body; + class URLRequest + { + public: + const std::optional url; + const std::optional method; + const std::optional> headers; + const std::optional> body; - URLRequest(const std::optional& url, const std::optional& method, - const std::optional>& headers, const std::optional>& body); - URLRequest(const flutter::EncodableMap& map); - ~URLRequest() = default; - flutter::EncodableMap toEncodableMap(); - }; + URLRequest(const std::optional& url, const std::optional& method, + const std::optional>& headers, const std::optional>& body); + URLRequest(const flutter::EncodableMap& map); + ~URLRequest() = default; + + flutter::EncodableMap toEncodableMap() const; + }; } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_URL_REQUEST_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/web_resource_error.cpp b/flutter_inappwebview_windows/windows/types/web_resource_error.cpp index cdadc378..107fd682 100644 --- a/flutter_inappwebview_windows/windows/types/web_resource_error.cpp +++ b/flutter_inappwebview_windows/windows/types/web_resource_error.cpp @@ -1,27 +1,22 @@ -#include "web_resource_error.h" - #include "../utils/flutter.h" +#include "web_resource_error.h" namespace flutter_inappwebview_plugin { - WebResourceError::WebResourceError(const std::string& description, const int type) - : description(description), type(type) - { + WebResourceError::WebResourceError(const std::string& description, const int type) + : description(description), type(type) + {} - } + WebResourceError::WebResourceError(const flutter::EncodableMap& map) + : description(get_fl_map_value(map, "description")), + type(get_fl_map_value(map, "type")) + {} - WebResourceError::WebResourceError(const flutter::EncodableMap& map) - : description(get_fl_map_value(map, "description")), - type(get_fl_map_value(map, "type")) - { - - } - - flutter::EncodableMap WebResourceError::toEncodableMap() - { - return flutter::EncodableMap{ - {make_fl_value("description"), make_fl_value(description)}, - {make_fl_value("type"), make_fl_value(type)} - }; - } + flutter::EncodableMap WebResourceError::toEncodableMap() const + { + return flutter::EncodableMap{ + {make_fl_value("description"), make_fl_value(description)}, + {make_fl_value("type"), make_fl_value(type)} + }; + } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/web_resource_error.h b/flutter_inappwebview_windows/windows/types/web_resource_error.h index 42f6d797..b1d2a55b 100644 --- a/flutter_inappwebview_windows/windows/types/web_resource_error.h +++ b/flutter_inappwebview_windows/windows/types/web_resource_error.h @@ -2,45 +2,45 @@ #define FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_ERROR_H_ #include - #include namespace flutter_inappwebview_plugin { - static const std::string WebErrorStatusDescription[] = - { - "Indicates that an unknown error occurred.", - "Indicates that the SSL certificate common name does not match the web address.", - "Indicates that the SSL certificate has expired.", - "Indicates that the SSL client certificate contains errors.", - "Indicates that the SSL certificate has been revoked.", - "Indicates that the SSL certificate is not valid.", - "Indicates that the host is unreachable.", - "Indicates that the connection has timed out.", - "Indicates that the server returned an invalid or unrecognized response.", - "Indicates that the connection was stopped.", - "Indicates that the connection was reset.", - "Indicates that the Internet connection has been lost.", - "Indicates that a connection to the destination was not established.", - "Indicates that the provided host name was not able to be resolved.", - "Indicates that the operation was canceled.", - "Indicates that the request redirect failed.", - "Indicates that an unexpected error occurred.", - "Indicates that user is prompted with a login, waiting on user action.", - "Indicates that user lacks proper authentication credentials for a proxy server.", - }; + static const std::string WebErrorStatusDescription[] = + { + "Indicates that an unknown error occurred.", + "Indicates that the SSL certificate common name does not match the web address.", + "Indicates that the SSL certificate has expired.", + "Indicates that the SSL client certificate contains errors.", + "Indicates that the SSL certificate has been revoked.", + "Indicates that the SSL certificate is not valid.", + "Indicates that the host is unreachable.", + "Indicates that the connection has timed out.", + "Indicates that the server returned an invalid or unrecognized response.", + "Indicates that the connection was stopped.", + "Indicates that the connection was reset.", + "Indicates that the Internet connection has been lost.", + "Indicates that a connection to the destination was not established.", + "Indicates that the provided host name was not able to be resolved.", + "Indicates that the operation was canceled.", + "Indicates that the request redirect failed.", + "Indicates that an unexpected error occurred.", + "Indicates that user is prompted with a login, waiting on user action.", + "Indicates that user lacks proper authentication credentials for a proxy server.", + }; - class WebResourceError - { - public: - const std::string description; - const int type; + class WebResourceError + { + public: + const std::string description; + const int type; - WebResourceError(const std::string& description, const int type); - WebResourceError(const flutter::EncodableMap& map); - ~WebResourceError() = default; - flutter::EncodableMap toEncodableMap(); - }; + WebResourceError(const std::string& description, const int type); + WebResourceError(const flutter::EncodableMap& map); + ~WebResourceError() = default; + + flutter::EncodableMap toEncodableMap() const; + }; } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_ERROR_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/web_resource_request.cpp b/flutter_inappwebview_windows/windows/types/web_resource_request.cpp index c017e199..3ab71d93 100644 --- a/flutter_inappwebview_windows/windows/types/web_resource_request.cpp +++ b/flutter_inappwebview_windows/windows/types/web_resource_request.cpp @@ -1,32 +1,27 @@ -#include "web_resource_request.h" - #include "../utils/flutter.h" +#include "web_resource_request.h" namespace flutter_inappwebview_plugin { - WebResourceRequest::WebResourceRequest(const std::optional& url, const std::optional& method, - const std::optional>& headers, const std::optional& isForMainFrame) - : url(url), method(method), headers(headers), isForMainFrame(isForMainFrame) - { + WebResourceRequest::WebResourceRequest(const std::optional& url, const std::optional& method, + const std::optional>& headers, const std::optional& isForMainFrame) + : url(url), method(method), headers(headers), isForMainFrame(isForMainFrame) + {} - } + WebResourceRequest::WebResourceRequest(const flutter::EncodableMap& map) + : url(get_optional_fl_map_value(map, "url")), + method(get_optional_fl_map_value(map, "method")), + headers(get_optional_fl_map_value(map, "headers")), + isForMainFrame(get_optional_fl_map_value(map, "isForMainFrame")) + {} - WebResourceRequest::WebResourceRequest(const flutter::EncodableMap& map) - : url(get_optional_fl_map_value(map, "url")), - method(get_optional_fl_map_value(map, "method")), - headers(get_optional_fl_map_value(map, "headers")), - isForMainFrame(get_optional_fl_map_value(map, "isForMainFrame")) - { - - } - - flutter::EncodableMap WebResourceRequest::toEncodableMap() - { - return flutter::EncodableMap{ - {make_fl_value("url"), make_fl_value(url)}, - {make_fl_value("method"), make_fl_value(method)}, - {make_fl_value("headers"), make_fl_value(headers)}, - {make_fl_value("isForMainFrame"), make_fl_value(isForMainFrame)} - }; - } + flutter::EncodableMap WebResourceRequest::toEncodableMap() const + { + return flutter::EncodableMap{ + {make_fl_value("url"), make_fl_value(url)}, + {make_fl_value("method"), make_fl_value(method)}, + {make_fl_value("headers"), make_fl_value(headers)}, + {make_fl_value("isForMainFrame"), make_fl_value(isForMainFrame)} + }; + } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/web_resource_request.h b/flutter_inappwebview_windows/windows/types/web_resource_request.h index 4f8ac07f..ea9bb587 100644 --- a/flutter_inappwebview_windows/windows/types/web_resource_request.h +++ b/flutter_inappwebview_windows/windows/types/web_resource_request.h @@ -2,25 +2,25 @@ #define FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_REQUEST_H_ #include - #include namespace flutter_inappwebview_plugin { - class WebResourceRequest - { - public: - const std::optional url; - const std::optional method; - const std::optional> headers; - const std::optional isForMainFrame; + class WebResourceRequest + { + public: + const std::optional url; + const std::optional method; + const std::optional> headers; + const std::optional isForMainFrame; - WebResourceRequest(const std::optional& url, const std::optional& method, - const std::optional>& headers, const std::optional& isForMainFrame); - WebResourceRequest(const flutter::EncodableMap& map); - ~WebResourceRequest() = default; - flutter::EncodableMap toEncodableMap(); - }; + WebResourceRequest(const std::optional& url, const std::optional& method, + const std::optional>& headers, const std::optional& isForMainFrame); + WebResourceRequest(const flutter::EncodableMap& map); + ~WebResourceRequest() = default; + + flutter::EncodableMap toEncodableMap() const; + }; } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_REQUEST_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/web_resource_response.cpp b/flutter_inappwebview_windows/windows/types/web_resource_response.cpp index 5d1d748d..934b94fb 100644 --- a/flutter_inappwebview_windows/windows/types/web_resource_response.cpp +++ b/flutter_inappwebview_windows/windows/types/web_resource_response.cpp @@ -1,25 +1,20 @@ -#include "web_resource_response.h" - #include "../utils/flutter.h" +#include "web_resource_response.h" namespace flutter_inappwebview_plugin { - WebResourceResponse::WebResourceResponse(const std::optional& statusCode) - : statusCode(statusCode) - { + WebResourceResponse::WebResourceResponse(const std::optional& statusCode) + : statusCode(statusCode) + {} - } + WebResourceResponse::WebResourceResponse(const flutter::EncodableMap& map) + : statusCode(get_optional_fl_map_value(map, "statusCode")) + {} - WebResourceResponse::WebResourceResponse(const flutter::EncodableMap& map) - : statusCode(get_optional_fl_map_value(map, "statusCode")) - { - - } - - flutter::EncodableMap WebResourceResponse::toEncodableMap() - { - return flutter::EncodableMap{ - {make_fl_value("statusCode"), make_fl_value(statusCode)} - }; - } + flutter::EncodableMap WebResourceResponse::toEncodableMap() const + { + return flutter::EncodableMap{ + {make_fl_value("statusCode"), make_fl_value(statusCode)} + }; + } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/web_resource_response.h b/flutter_inappwebview_windows/windows/types/web_resource_response.h index caed73b3..123080aa 100644 --- a/flutter_inappwebview_windows/windows/types/web_resource_response.h +++ b/flutter_inappwebview_windows/windows/types/web_resource_response.h @@ -2,21 +2,21 @@ #define FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_RESPONSE_H_ #include - #include namespace flutter_inappwebview_plugin { - class WebResourceResponse - { - public: - const std::optional statusCode; + class WebResourceResponse + { + public: + const std::optional statusCode; - WebResourceResponse(const std::optional& statusCode); - WebResourceResponse(const flutter::EncodableMap& map); - ~WebResourceResponse() = default; - flutter::EncodableMap toEncodableMap(); - }; + WebResourceResponse(const std::optional& statusCode); + WebResourceResponse(const flutter::EncodableMap& map); + ~WebResourceResponse() = default; + + flutter::EncodableMap toEncodableMap() const; + }; } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_RESPONSE_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/utils/flutter.h b/flutter_inappwebview_windows/windows/utils/flutter.h index e08ac630..d539333d 100644 --- a/flutter_inappwebview_windows/windows/utils/flutter.h +++ b/flutter_inappwebview_windows/windows/utils/flutter.h @@ -1,77 +1,110 @@ #ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_ #define FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_ -#include -#include #include +#include +#include #include "util.h" namespace flutter_inappwebview_plugin { - static inline flutter::EncodableValue make_fl_value() - { - return flutter::EncodableValue(); - } + static inline flutter::EncodableValue make_fl_value() + { + return flutter::EncodableValue(); + } - template - static inline flutter::EncodableValue make_fl_value(const T& val) - { - return flutter::EncodableValue(val); - } + template + static inline flutter::EncodableValue make_fl_value(const T& val) + { + return flutter::EncodableValue(val); + } - template - static inline flutter::EncodableValue make_fl_value(const T* val) - { - return val == nullptr ? make_fl_value() : flutter::EncodableValue(val); - } + template + static inline flutter::EncodableValue make_fl_value(const T* val) + { + return val == nullptr ? make_fl_value() : flutter::EncodableValue(val); + } - template - static inline flutter::EncodableValue make_fl_value(const std::optional& optional) - { - return optional.has_value() ? make_fl_value(optional.value()) : make_fl_value(); + template + static inline flutter::EncodableValue make_fl_value(const std::vector& vec) + { + auto encodableList = flutter::EncodableList{}; + for (auto const& val : vec) { + encodableList.push_back(make_fl_value(val)); } + return encodableList; + } - static inline flutter::EncodableValue make_fl_value(const std::optional>& optional) - { - if (!optional.has_value()) { - return make_fl_value(); - } - auto& mapValue = optional.value(); - auto encodableMap = flutter::EncodableMap{}; - for (auto const& [key, val] : mapValue) - { - encodableMap.insert({ make_fl_value(key), make_fl_value(val) }); - } - return encodableMap; + template + static inline flutter::EncodableValue make_fl_value(const std::map& map) + { + auto encodableMap = flutter::EncodableMap{}; + for (auto const& [key, val] : map) { + encodableMap.insert({ make_fl_value(key), make_fl_value(val) }); } + return encodableMap; + } - template - static inline T get_fl_map_value(const flutter::EncodableMap& map, const char* string) - { - return std::get(map.at(make_fl_value(string))); - } + template + static inline flutter::EncodableValue make_fl_value(const std::optional& optional) + { + return optional.has_value() ? make_fl_value(optional.value()) : make_fl_value(); + } - template - static inline std::optional get_optional_fl_map_value(const flutter::EncodableMap& map, const char* string) - { - return make_pointer_optional(std::get_if(&map.at(make_fl_value(string)))); + template + static inline flutter::EncodableValue make_fl_value(const std::optional>& optional) + { + if (!optional.has_value()) { + return make_fl_value(); } + auto& vecValue = optional.value(); + auto encodableList = flutter::EncodableList{}; + for (auto const& val : vecValue) { + encodableList.push_back(make_fl_value(val)); + } + return encodableList; + } - template - static inline std::optional> get_optional_fl_map_value(const flutter::EncodableMap& map, const char* string) - { - auto flMap = std::get_if(&map.at(make_fl_value(string))); - if (flMap) { - auto mapValue = std::map{}; - for (auto itr = flMap->begin(); itr != flMap->end(); itr++) - { - mapValue.insert({ std::get(itr->first), std::get(itr->second) }); - } - return make_pointer_optional>(&mapValue); - } - return std::nullopt; + template + static inline flutter::EncodableValue make_fl_value(const std::optional>& optional) + { + if (!optional.has_value()) { + return make_fl_value(); } + auto& mapValue = optional.value(); + auto encodableMap = flutter::EncodableMap{}; + for (auto const& [key, val] : mapValue) { + encodableMap.insert({ make_fl_value(key), make_fl_value(val) }); + } + return encodableMap; + } + + template + static inline T get_fl_map_value(const flutter::EncodableMap& map, const char* string) + { + return std::get(map.at(make_fl_value(string))); + } + + template + static inline std::optional get_optional_fl_map_value(const flutter::EncodableMap& map, const char* string) + { + return make_pointer_optional(std::get_if(&map.at(make_fl_value(string)))); + } + + template + static inline std::optional> get_optional_fl_map_value(const flutter::EncodableMap& map, const char* string) + { + auto flMap = std::get_if(&map.at(make_fl_value(string))); + if (flMap) { + auto mapValue = std::map{}; + for (auto itr = flMap->begin(); itr != flMap->end(); itr++) { + mapValue.insert({ std::get(itr->first), std::get(itr->second) }); + } + return make_pointer_optional>(&mapValue); + } + return std::nullopt; + } } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/utils/strconv.h b/flutter_inappwebview_windows/windows/utils/strconv.h index 715a2297..0f1483ff 100644 --- a/flutter_inappwebview_windows/windows/utils/strconv.h +++ b/flutter_inappwebview_windows/windows/utils/strconv.h @@ -57,152 +57,152 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. namespace flutter_inappwebview_plugin { #if __cplusplus >= 201103L && !defined(STRCONV_CPP98) - static inline std::wstring cp_to_wide(const std::string& s, UINT codepage) - { - int in_length = (int)s.length(); - int out_length = MultiByteToWideChar(codepage, 0, s.c_str(), in_length, 0, 0); - std::wstring result(out_length, L'\0'); - if (out_length) - MultiByteToWideChar(codepage, 0, s.c_str(), in_length, &result[0], out_length); - return result; - } - static inline std::string wide_to_cp(const std::wstring& s, UINT codepage) - { - int in_length = (int)s.length(); - int out_length = WideCharToMultiByte(codepage, 0, s.c_str(), in_length, 0, 0, 0, 0); - std::string result(out_length, '\0'); - if (out_length) - WideCharToMultiByte(codepage, 0, s.c_str(), in_length, &result[0], out_length, 0, 0); - return result; - } + static inline std::wstring cp_to_wide(const std::string& s, UINT codepage) + { + int in_length = (int)s.length(); + int out_length = MultiByteToWideChar(codepage, 0, s.c_str(), in_length, 0, 0); + std::wstring result(out_length, L'\0'); + if (out_length) + MultiByteToWideChar(codepage, 0, s.c_str(), in_length, &result[0], out_length); + return result; + } + static inline std::string wide_to_cp(const std::wstring& s, UINT codepage) + { + int in_length = (int)s.length(); + int out_length = WideCharToMultiByte(codepage, 0, s.c_str(), in_length, 0, 0, 0, 0); + std::string result(out_length, '\0'); + if (out_length) + WideCharToMultiByte(codepage, 0, s.c_str(), in_length, &result[0], out_length, 0, 0); + return result; + } #else /* __cplusplus < 201103L */ - static inline std::wstring cp_to_wide(const std::string& s, UINT codepage) - { - int in_length = (int)s.length(); - int out_length = MultiByteToWideChar(codepage, 0, s.c_str(), in_length, 0, 0); - std::vector buffer(out_length); - if (out_length) - MultiByteToWideChar(codepage, 0, s.c_str(), in_length, &buffer[0], out_length); - std::wstring result(buffer.begin(), buffer.end()); - return result; - } - static inline std::string wide_to_cp(const std::wstring& s, UINT codepage) - { - int in_length = (int)s.length(); - int out_length = WideCharToMultiByte(codepage, 0, s.c_str(), in_length, 0, 0, 0, 0); - std::vector buffer(out_length); - if (out_length) - WideCharToMultiByte(codepage, 0, s.c_str(), in_length, &buffer[0], out_length, 0, 0); - std::string result(buffer.begin(), buffer.end()); - return result; - } + static inline std::wstring cp_to_wide(const std::string& s, UINT codepage) + { + int in_length = (int)s.length(); + int out_length = MultiByteToWideChar(codepage, 0, s.c_str(), in_length, 0, 0); + std::vector buffer(out_length); + if (out_length) + MultiByteToWideChar(codepage, 0, s.c_str(), in_length, &buffer[0], out_length); + std::wstring result(buffer.begin(), buffer.end()); + return result; + } + static inline std::string wide_to_cp(const std::wstring& s, UINT codepage) + { + int in_length = (int)s.length(); + int out_length = WideCharToMultiByte(codepage, 0, s.c_str(), in_length, 0, 0, 0, 0); + std::vector buffer(out_length); + if (out_length) + WideCharToMultiByte(codepage, 0, s.c_str(), in_length, &buffer[0], out_length, 0, 0); + std::string result(buffer.begin(), buffer.end()); + return result; + } #endif - static inline std::string cp_to_utf8(const std::string& s, UINT codepage) - { - if (codepage == CP_UTF8) - return s; - std::wstring wide = cp_to_wide(s, codepage); - return wide_to_cp(wide, CP_UTF8); - } - static inline std::string utf8_to_cp(const std::string& s, UINT codepage) - { - if (codepage == CP_UTF8) - return s; - std::wstring wide = cp_to_wide(s, CP_UTF8); - return wide_to_cp(wide, codepage); - } + static inline std::string cp_to_utf8(const std::string& s, UINT codepage) + { + if (codepage == CP_UTF8) + return s; + std::wstring wide = cp_to_wide(s, codepage); + return wide_to_cp(wide, CP_UTF8); + } + static inline std::string utf8_to_cp(const std::string& s, UINT codepage) + { + if (codepage == CP_UTF8) + return s; + std::wstring wide = cp_to_wide(s, CP_UTF8); + return wide_to_cp(wide, codepage); + } - static inline std::wstring ansi_to_wide(const std::string& s) - { - return cp_to_wide(s, CP_ACP); - } - static inline std::string wide_to_ansi(const std::wstring& s) - { - return wide_to_cp(s, CP_ACP); - } + static inline std::wstring ansi_to_wide(const std::string& s) + { + return cp_to_wide(s, CP_ACP); + } + static inline std::string wide_to_ansi(const std::wstring& s) + { + return wide_to_cp(s, CP_ACP); + } - static inline std::wstring sjis_to_wide(const std::string& s) - { - return cp_to_wide(s, 932); - } - static inline std::string wide_to_sjis(const std::wstring& s) - { - return wide_to_cp(s, 932); - } + static inline std::wstring sjis_to_wide(const std::string& s) + { + return cp_to_wide(s, 932); + } + static inline std::string wide_to_sjis(const std::wstring& s) + { + return wide_to_cp(s, 932); + } - static inline std::wstring utf8_to_wide(const std::string& s) - { - return cp_to_wide(s, CP_UTF8); - } - static inline std::string wide_to_utf8(const std::wstring& s) - { - return wide_to_cp(s, CP_UTF8); - } + static inline std::wstring utf8_to_wide(const std::string& s) + { + return cp_to_wide(s, CP_UTF8); + } + static inline std::string wide_to_utf8(const std::wstring& s) + { + return wide_to_cp(s, CP_UTF8); + } - static inline std::string ansi_to_utf8(const std::string& s) - { - return cp_to_utf8(s, CP_ACP); - } - static inline std::string utf8_to_ansi(const std::string& s) - { - return utf8_to_cp(s, CP_ACP); - } + static inline std::string ansi_to_utf8(const std::string& s) + { + return cp_to_utf8(s, CP_ACP); + } + static inline std::string utf8_to_ansi(const std::string& s) + { + return utf8_to_cp(s, CP_ACP); + } - static inline std::string sjis_to_utf8(const std::string& s) - { - return cp_to_utf8(s, 932); - } - static inline std::string utf8_to_sjis(const std::string& s) - { - return utf8_to_cp(s, 932); - } + static inline std::string sjis_to_utf8(const std::string& s) + { + return cp_to_utf8(s, 932); + } + static inline std::string utf8_to_sjis(const std::string& s) + { + return utf8_to_cp(s, 932); + } #ifdef __cpp_char8_t - static inline std::u8string utf8_to_char8(const std::string& s) - { - return std::u8string(s.begin(), s.end()); - } - static inline std::string char8_to_utf8(const std::u8string& s) - { - return std::string(s.begin(), s.end()); - } + static inline std::u8string utf8_to_char8(const std::string& s) + { + return std::u8string(s.begin(), s.end()); + } + static inline std::string char8_to_utf8(const std::u8string& s) + { + return std::string(s.begin(), s.end()); + } - static inline std::wstring char8_to_wide(const std::u8string& s) - { - return cp_to_wide(char8_to_utf8(s), CP_UTF8); - } - static inline std::u8string wide_to_char8(const std::wstring& s) - { - return utf8_to_char8(wide_to_cp(s, CP_UTF8)); - } + static inline std::wstring char8_to_wide(const std::u8string& s) + { + return cp_to_wide(char8_to_utf8(s), CP_UTF8); + } + static inline std::u8string wide_to_char8(const std::wstring& s) + { + return utf8_to_char8(wide_to_cp(s, CP_UTF8)); + } - static inline std::u8string cp_to_char8(const std::string& s, UINT codepage) - { - return utf8_to_char8(cp_to_utf8(s, codepage)); - } - static inline std::string char8_to_cp(const std::u8string& s, UINT codepage) - { - return utf8_to_cp(char8_to_utf8(s), codepage); - } + static inline std::u8string cp_to_char8(const std::string& s, UINT codepage) + { + return utf8_to_char8(cp_to_utf8(s, codepage)); + } + static inline std::string char8_to_cp(const std::u8string& s, UINT codepage) + { + return utf8_to_cp(char8_to_utf8(s), codepage); + } - static inline std::u8string ansi_to_char8(const std::string& s) - { - return cp_to_char8(s, CP_ACP); - } - static inline std::string char8_to_ansi(const std::u8string& s) - { - return char8_to_cp(s, CP_ACP); - } + static inline std::u8string ansi_to_char8(const std::string& s) + { + return cp_to_char8(s, CP_ACP); + } + static inline std::string char8_to_ansi(const std::u8string& s) + { + return char8_to_cp(s, CP_ACP); + } - static inline std::u8string sjis_to_char8(const std::string& s) - { - return cp_to_char8(s, 932); - } - static inline std::string char8_to_sjis(const std::u8string& s) - { - return char8_to_cp(s, 932); - } + static inline std::u8string sjis_to_char8(const std::string& s) + { + return cp_to_char8(s, 932); + } + static inline std::string char8_to_sjis(const std::u8string& s) + { + return char8_to_cp(s, 932); + } #endif #if defined(_MSC_VER) @@ -210,360 +210,346 @@ namespace flutter_inappwebview_plugin #pragma warning(disable : 4996) #endif - static inline std::wstring vformat(const wchar_t* format, va_list args) - { - int len = _vsnwprintf(0, 0, format, args); - if (len < 0) - return L""; - std::vector buffer(len + 1); - len = _vsnwprintf(&buffer[0], len, format, args); - if (len < 0) - return L""; - buffer[len] = L'\0'; - return &buffer[0]; - } - static inline std::string vformat(const char* format, va_list args) - { - int len = _vsnprintf(0, 0, format, args); - if (len < 0) - return ""; - std::vector buffer(len + 1); - len = _vsnprintf(&buffer[0], len, format, args); - if (len < 0) - return ""; - buffer[len] = '\0'; - return &buffer[0]; - } + static inline std::wstring vformat(const wchar_t* format, va_list args) + { + int len = _vsnwprintf(0, 0, format, args); + if (len < 0) + return L""; + std::vector buffer(len + 1); + len = _vsnwprintf(&buffer[0], len, format, args); + if (len < 0) + return L""; + buffer[len] = L'\0'; + return &buffer[0]; + } + static inline std::string vformat(const char* format, va_list args) + { + int len = _vsnprintf(0, 0, format, args); + if (len < 0) + return ""; + std::vector buffer(len + 1); + len = _vsnprintf(&buffer[0], len, format, args); + if (len < 0) + return ""; + buffer[len] = '\0'; + return &buffer[0]; + } #ifdef __cpp_char8_t - static inline std::u8string vformat(const char8_t* format, va_list args) - { - int len = _vsnprintf(0, 0, (const char*)format, args); - if (len < 0) - return u8""; - std::vector buffer(len + 1); - len = _vsnprintf(&buffer[0], len, (const char*)format, args); - if (len < 0) - return u8""; - buffer[len] = '\0'; - return (char8_t*)&buffer[0]; - } + static inline std::u8string vformat(const char8_t* format, va_list args) + { + int len = _vsnprintf(0, 0, (const char*)format, args); + if (len < 0) + return u8""; + std::vector buffer(len + 1); + len = _vsnprintf(&buffer[0], len, (const char*)format, args); + if (len < 0) + return u8""; + buffer[len] = '\0'; + return (char8_t*)&buffer[0]; + } #endif #if defined(_MSC_VER) #pragma warning(pop) #endif - static inline std::wstring format(const wchar_t* format, ...) - { - va_list args; - va_start(args, format); - std::wstring s = vformat(format, args); - va_end(args); - return s; - } - static inline std::string format(const char* format, ...) - { - va_list args; - va_start(args, format); - std::string s = vformat(format, args); - va_end(args); - return s; - } + static inline std::wstring format(const wchar_t* format, ...) + { + va_list args; + va_start(args, format); + std::wstring s = vformat(format, args); + va_end(args); + return s; + } + static inline std::string format(const char* format, ...) + { + va_list args; + va_start(args, format); + std::string s = vformat(format, args); + va_end(args); + return s; + } #ifdef __cpp_char8_t - static inline std::u8string format(const char8_t* format, ...) - { - va_list args; - va_start(args, format); - std::u8string s = vformat(format, args); - va_end(args); - return s; - } + static inline std::u8string format(const char8_t* format, ...) + { + va_list args; + va_start(args, format); + std::u8string s = vformat(format, args); + va_end(args); + return s; + } #endif - static inline void format(std::ostream& ostrm, const wchar_t* format, ...) - { - va_list args; - va_start(args, format); - std::wstring s = vformat(format, args); - va_end(args); - ostrm << wide_to_utf8(s) << std::flush; - } - static inline void format(std::ostream& ostrm, const char* format, ...) - { - va_list args; - va_start(args, format); - std::string s = vformat(format, args); - va_end(args); - ostrm << s << std::flush; - } + static inline void format(std::ostream& ostrm, const wchar_t* format, ...) + { + va_list args; + va_start(args, format); + std::wstring s = vformat(format, args); + va_end(args); + ostrm << wide_to_utf8(s) << std::flush; + } + static inline void format(std::ostream& ostrm, const char* format, ...) + { + va_list args; + va_start(args, format); + std::string s = vformat(format, args); + va_end(args); + ostrm << s << std::flush; + } #ifdef __cpp_char8_t - static inline void format(std::ostream& ostrm, const char8_t* format, ...) - { - va_list args; - va_start(args, format); - std::u8string s = vformat(format, args); - va_end(args); - ostrm << char8_to_utf8(s) << std::flush; - } + static inline void format(std::ostream& ostrm, const char8_t* format, ...) + { + va_list args; + va_start(args, format); + std::u8string s = vformat(format, args); + va_end(args); + ostrm << char8_to_utf8(s) << std::flush; + } #endif - static inline std::string formatA(const wchar_t* format, ...) - { - va_list args; - va_start(args, format); - std::wstring s = vformat(format, args); - va_end(args); - return wide_to_ansi(s); - } - static inline std::string formatA(const char* format, ...) - { - va_list args; - va_start(args, format); - std::string s = vformat(format, args); - va_end(args); - return utf8_to_ansi(s); - } + static inline std::string formatA(const wchar_t* format, ...) + { + va_list args; + va_start(args, format); + std::wstring s = vformat(format, args); + va_end(args); + return wide_to_ansi(s); + } + static inline std::string formatA(const char* format, ...) + { + va_list args; + va_start(args, format); + std::string s = vformat(format, args); + va_end(args); + return utf8_to_ansi(s); + } #ifdef __cpp_char8_t - static inline std::string formatA(const char8_t* format, ...) - { - va_list args; - va_start(args, format); - std::u8string s = vformat(format, args); - va_end(args); - return char8_to_ansi(s); - } + static inline std::string formatA(const char8_t* format, ...) + { + va_list args; + va_start(args, format); + std::u8string s = vformat(format, args); + va_end(args); + return char8_to_ansi(s); + } #endif - static inline void formatA(std::ostream& ostrm, const wchar_t* format, ...) - { - va_list args; - va_start(args, format); - std::wstring s = vformat(format, args); - va_end(args); - ostrm << wide_to_ansi(s) << std::flush; - } - static inline void formatA(std::ostream& ostrm, const char* format, ...) - { - va_list args; - va_start(args, format); - std::string s = vformat(format, args); - va_end(args); - ostrm << utf8_to_ansi(s) << std::flush; - } + static inline void formatA(std::ostream& ostrm, const wchar_t* format, ...) + { + va_list args; + va_start(args, format); + std::wstring s = vformat(format, args); + va_end(args); + ostrm << wide_to_ansi(s) << std::flush; + } + static inline void formatA(std::ostream& ostrm, const char* format, ...) + { + va_list args; + va_start(args, format); + std::string s = vformat(format, args); + va_end(args); + ostrm << utf8_to_ansi(s) << std::flush; + } #ifdef __cpp_char8_t - static inline void formatA(std::ostream& ostrm, const char8_t* format, ...) - { - va_list args; - va_start(args, format); - std::u8string s = vformat(format, args); - va_end(args); - ostrm << char8_to_ansi(s) << std::flush; - } + static inline void formatA(std::ostream& ostrm, const char8_t* format, ...) + { + va_list args; + va_start(args, format); + std::u8string s = vformat(format, args); + va_end(args); + ostrm << char8_to_ansi(s) << std::flush; + } #endif - static inline void dbgmsg(const wchar_t* title, const wchar_t* format, ...) - { - va_list args; - va_start(args, format); - std::wstring s = vformat(format, args); - va_end(args); - MessageBoxW(0, s.c_str(), title, MB_OK); - } - static inline void dbgmsg(const char* title, const char* format, ...) - { - va_list args; - va_start(args, format); - std::string s = vformat(format, args); - va_end(args); - MessageBoxW(0, utf8_to_wide(s).c_str(), utf8_to_wide(title).c_str(), MB_OK); - } + static inline void dbgmsg(const wchar_t* title, const wchar_t* format, ...) + { + va_list args; + va_start(args, format); + std::wstring s = vformat(format, args); + va_end(args); + MessageBoxW(0, s.c_str(), title, MB_OK); + } + static inline void dbgmsg(const char* title, const char* format, ...) + { + va_list args; + va_start(args, format); + std::string s = vformat(format, args); + va_end(args); + MessageBoxW(0, utf8_to_wide(s).c_str(), utf8_to_wide(title).c_str(), MB_OK); + } #ifdef __cpp_char8_t - static inline void dbgmsg(const char8_t* title, const char8_t* format, ...) - { - va_list args; - va_start(args, format); - std::u8string s = vformat(format, args); - va_end(args); - MessageBoxW(0, char8_to_wide(s).c_str(), char8_to_wide(title).c_str(), MB_OK); - } + static inline void dbgmsg(const char8_t* title, const char8_t* format, ...) + { + va_list args; + va_start(args, format); + std::u8string s = vformat(format, args); + va_end(args); + MessageBoxW(0, char8_to_wide(s).c_str(), char8_to_wide(title).c_str(), MB_OK); + } #endif - static inline HANDLE handle_for_ostream(std::ostream& ostrm) - { - if (&ostrm == &std::cout) - { - return GetStdHandle(STD_OUTPUT_HANDLE); - } - else if (&ostrm == &std::cerr) - { - return GetStdHandle(STD_ERROR_HANDLE); - } - return INVALID_HANDLE_VALUE; + static inline HANDLE handle_for_ostream(std::ostream& ostrm) + { + if (&ostrm == &std::cout) { + return GetStdHandle(STD_OUTPUT_HANDLE); } - static inline void dbgout(std::ostream& ostrm, const wchar_t* format, ...) - { - va_list args; - va_start(args, format); - std::wstring ws = vformat(format, args); - va_end(args); - HANDLE h = handle_for_ostream(ostrm); - if (h == INVALID_HANDLE_VALUE) - { - return; - } - DWORD dwNumberOfCharsWrite; - if (GetFileType(h) != FILE_TYPE_CHAR) - { - std::string s = wide_to_cp(ws, GetConsoleOutputCP()); - WriteFile(h, s.c_str(), (DWORD)s.size(), &dwNumberOfCharsWrite, NULL); - } - else - { - WriteConsoleW(h, - ws.c_str(), - (DWORD)ws.size(), - &dwNumberOfCharsWrite, - NULL); - } + else if (&ostrm == &std::cerr) { + return GetStdHandle(STD_ERROR_HANDLE); } - static inline void dbgout(std::ostream& ostrm, const char* format, ...) - { - va_list args; - va_start(args, format); - std::string s = vformat(format, args); - va_end(args); - HANDLE h = handle_for_ostream(ostrm); - if (h == INVALID_HANDLE_VALUE) - { - return; - } - DWORD dwNumberOfCharsWrite; - if (GetFileType(h) != FILE_TYPE_CHAR) - { - s = utf8_to_cp(s, GetConsoleOutputCP()); - WriteFile(h, s.c_str(), (DWORD)s.size(), &dwNumberOfCharsWrite, NULL); - } - else - { - std::wstring ws = utf8_to_wide(s); - WriteConsoleW(h, - ws.c_str(), - (DWORD)ws.size(), - &dwNumberOfCharsWrite, - NULL); - } + return INVALID_HANDLE_VALUE; + } + static inline void dbgout(std::ostream& ostrm, const wchar_t* format, ...) + { + va_list args; + va_start(args, format); + std::wstring ws = vformat(format, args); + va_end(args); + HANDLE h = handle_for_ostream(ostrm); + if (h == INVALID_HANDLE_VALUE) { + return; } + DWORD dwNumberOfCharsWrite; + if (GetFileType(h) != FILE_TYPE_CHAR) { + std::string s = wide_to_cp(ws, GetConsoleOutputCP()); + WriteFile(h, s.c_str(), (DWORD)s.size(), &dwNumberOfCharsWrite, NULL); + } + else { + WriteConsoleW(h, + ws.c_str(), + (DWORD)ws.size(), + &dwNumberOfCharsWrite, + NULL); + } + } + static inline void dbgout(std::ostream& ostrm, const char* format, ...) + { + va_list args; + va_start(args, format); + std::string s = vformat(format, args); + va_end(args); + HANDLE h = handle_for_ostream(ostrm); + if (h == INVALID_HANDLE_VALUE) { + return; + } + DWORD dwNumberOfCharsWrite; + if (GetFileType(h) != FILE_TYPE_CHAR) { + s = utf8_to_cp(s, GetConsoleOutputCP()); + WriteFile(h, s.c_str(), (DWORD)s.size(), &dwNumberOfCharsWrite, NULL); + } + else { + std::wstring ws = utf8_to_wide(s); + WriteConsoleW(h, + ws.c_str(), + (DWORD)ws.size(), + &dwNumberOfCharsWrite, + NULL); + } + } #ifdef __cpp_char8_t - static inline void dbgout(std::ostream& ostrm, const char8_t* format, ...) - { - va_list args; - va_start(args, format); - std::u8string s = vformat(format, args); - va_end(args); - HANDLE h = handle_for_ostream(ostrm); - if (h == INVALID_HANDLE_VALUE) - { - return; - } - DWORD dwNumberOfCharsWrite; - if (GetFileType(h) != FILE_TYPE_CHAR) - { - std::string str = char8_to_cp(s, GetConsoleOutputCP()); - WriteFile(h, (const char*)str.c_str(), (DWORD)str.size(), &dwNumberOfCharsWrite, NULL); - } - else - { - std::wstring ws = char8_to_wide(s); - WriteConsoleW(h, - ws.c_str(), - (DWORD)ws.size(), - &dwNumberOfCharsWrite, - NULL); - } + static inline void dbgout(std::ostream& ostrm, const char8_t* format, ...) + { + va_list args; + va_start(args, format); + std::u8string s = vformat(format, args); + va_end(args); + HANDLE h = handle_for_ostream(ostrm); + if (h == INVALID_HANDLE_VALUE) { + return; } + DWORD dwNumberOfCharsWrite; + if (GetFileType(h) != FILE_TYPE_CHAR) { + std::string str = char8_to_cp(s, GetConsoleOutputCP()); + WriteFile(h, (const char*)str.c_str(), (DWORD)str.size(), &dwNumberOfCharsWrite, NULL); + } + else { + std::wstring ws = char8_to_wide(s); + WriteConsoleW(h, + ws.c_str(), + (DWORD)ws.size(), + &dwNumberOfCharsWrite, + NULL); + } + } #endif - class unicode_ostream + class unicode_ostream + { + private: + std::ostream* m_ostrm; + UINT m_target_cp; + bool is_ascii(const std::string& s) { - private: - std::ostream* m_ostrm; - UINT m_target_cp; - bool is_ascii(const std::string& s) - { - for (std::size_t i = 0; i < s.size(); i++) - { - unsigned char c = (unsigned char)s[i]; - if (c > 0x7f) - return false; - } - return true; - } + for (std::size_t i = 0; i < s.size(); i++) { + unsigned char c = (unsigned char)s[i]; + if (c > 0x7f) + return false; + } + return true; + } - public: - unicode_ostream(std::ostream& ostrm, UINT target_cp = CP_ACP) : m_ostrm(&ostrm), m_target_cp(target_cp) {} - std::ostream& stream() { return *m_ostrm; } - void stream(std::ostream& ostrm) { m_ostrm = &ostrm; } - UINT target_cp() { return m_target_cp; } - void target_cp(UINT cp) { m_target_cp = cp; } - template - unicode_ostream& operator<<(const T& x) - { - std::ostringstream oss; - oss << x; - std::string output = oss.str(); - if (is_ascii(output)) - { - (*m_ostrm) << x; - } - else - { - (*m_ostrm) << utf8_to_cp(output, m_target_cp); - } - return *this; - } - unicode_ostream& operator<<(const std::wstring& x) - { - (*m_ostrm) << wide_to_cp(x, m_target_cp); - return *this; - } - unicode_ostream& operator<<(const wchar_t* x) - { - (*m_ostrm) << wide_to_cp(x, m_target_cp); - return *this; - } - unicode_ostream& operator<<(const std::string& x) - { - (*m_ostrm) << utf8_to_cp(x, m_target_cp); - return *this; - } - unicode_ostream& operator<<(const char* x) - { - (*m_ostrm) << utf8_to_cp(x, m_target_cp); - return *this; - } + public: + unicode_ostream(std::ostream& ostrm, UINT target_cp = CP_ACP) : m_ostrm(&ostrm), m_target_cp(target_cp) {} + std::ostream& stream() { return *m_ostrm; } + void stream(std::ostream& ostrm) { m_ostrm = &ostrm; } + UINT target_cp() { return m_target_cp; } + void target_cp(UINT cp) { m_target_cp = cp; } + template + unicode_ostream& operator<<(const T& x) + { + std::ostringstream oss; + oss << x; + std::string output = oss.str(); + if (is_ascii(output)) { + (*m_ostrm) << x; + } + else { + (*m_ostrm) << utf8_to_cp(output, m_target_cp); + } + return *this; + } + unicode_ostream& operator<<(const std::wstring& x) + { + (*m_ostrm) << wide_to_cp(x, m_target_cp); + return *this; + } + unicode_ostream& operator<<(const wchar_t* x) + { + (*m_ostrm) << wide_to_cp(x, m_target_cp); + return *this; + } + unicode_ostream& operator<<(const std::string& x) + { + (*m_ostrm) << utf8_to_cp(x, m_target_cp); + return *this; + } + unicode_ostream& operator<<(const char* x) + { + (*m_ostrm) << utf8_to_cp(x, m_target_cp); + return *this; + } #ifdef __cpp_char8_t - unicode_ostream& operator<<(const std::u8string& x) - { - (*m_ostrm) << char8_to_cp(x, m_target_cp); - return *this; - } - unicode_ostream& operator<<(const char8_t* x) - { - (*m_ostrm) << char8_to_cp(x, m_target_cp); - return *this; - } + unicode_ostream& operator<<(const std::u8string& x) + { + (*m_ostrm) << char8_to_cp(x, m_target_cp); + return *this; + } + unicode_ostream& operator<<(const char8_t* x) + { + (*m_ostrm) << char8_to_cp(x, m_target_cp); + return *this; + } #endif - unicode_ostream& operator<<(std::ostream& (*pf)(std::ostream&)) // For manipulators... - { - (*m_ostrm) << pf; - return *this; - } - unicode_ostream& operator<<(std::basic_ios& (*pf)(std::basic_ios&)) // For manipulators... - { - (*m_ostrm) << pf; - return *this; - } - }; + unicode_ostream& operator<<(std::ostream& (*pf)(std::ostream&)) // For manipulators... + { + (*m_ostrm) << pf; + return *this; + } + unicode_ostream& operator<<(std::basic_ios& (*pf)(std::basic_ios&)) // For manipulators... + { + (*m_ostrm) << pf; + return *this; + } + }; } #define U8(X) ((const char *)u8##X) diff --git a/flutter_inappwebview_windows/windows/utils/util.h b/flutter_inappwebview_windows/windows/utils/util.h index 34562bce..e619a246 100644 --- a/flutter_inappwebview_windows/windows/utils/util.h +++ b/flutter_inappwebview_windows/windows/utils/util.h @@ -1,52 +1,57 @@ #ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_ #define FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_ -#include -#include -#include #include +#include +#include +#include +#include +#include + #include "strconv.h" namespace flutter_inappwebview_plugin { - static inline void debugLog(const std::string& msg) { + static inline void debugLog(const std::string& msg) + { #ifndef NDEBUG - std::cout << msg << std::endl; - OutputDebugString(ansi_to_wide(msg + "\n").c_str()); + std::cout << msg << std::endl; + OutputDebugString(ansi_to_wide(msg + "\n").c_str()); #endif - } + } - template - static inline std::optional make_pointer_optional(const T* value) - { - return value == nullptr ? std::nullopt : std::make_optional(*value); - } + template + static inline std::optional make_pointer_optional(const T* value) + { + return value == nullptr ? std::nullopt : std::make_optional(*value); + } - static inline std::string variant_to_string(const std::variant& var) - { - return std::visit([](auto&& arg) { - using T = std::decay_t; - if constexpr (std::is_same_v) - return arg; - else if constexpr (std::is_arithmetic_v) - return std::to_string(arg); - else - static_assert(always_false_v, "non-exhaustive visitor!"); - }, var); - } + static inline std::string variant_to_string(const std::variant& var) + { + return std::visit([](auto&& arg) + { + using T = std::decay_t; + if constexpr (std::is_same_v) + return arg; + else if constexpr (std::is_arithmetic_v) + return std::to_string(arg); + else + static_assert(always_false_v, "non-exhaustive visitor!"); + }, var); + } - template - static inline bool map_contains(const std::map& map, const K& key) - { - return map.find(key) != map.end(); - } + template + static inline bool map_contains(const std::map& map, const K& key) + { + return map.find(key) != map.end(); + } - template - static inline T map_at_or_null(const std::map& map, const K& key) - { - auto itr = map.find(key); - return itr != map.end() ? itr->second : nullptr; - } + template + static inline T map_at_or_null(const std::map& map, const K& key) + { + auto itr = map.find(key); + return itr != map.end() ? itr->second : nullptr; + } } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_ \ No newline at end of file