windows c++ code format

This commit is contained in:
unknown 2024-01-08 12:36:48 +01:00
parent dcfeeb7497
commit 8499949a22
31 changed files with 1538 additions and 1533 deletions

View File

@ -30,7 +30,6 @@ class MyInAppBrowser extends InAppBrowser {
@override
Future onLoadStop(url) async {
pullToRefreshController?.endRefreshing();
print(await webViewController?.getUrl());
}
@override

View File

@ -7,21 +7,20 @@
namespace flutter_inappwebview_plugin
{
// static
void FlutterInappwebviewWindowsPlugin::RegisterWithRegistrar(
flutter::PluginRegistrarWindows* registrar) {
auto plugin = std::make_unique<FlutterInappwebviewWindowsPlugin>(registrar);
registrar->AddPlugin(std::move(plugin));
}
// static
void FlutterInappwebviewWindowsPlugin::RegisterWithRegistrar(
flutter::PluginRegistrarWindows* registrar)
{
auto plugin = std::make_unique<FlutterInappwebviewWindowsPlugin>(registrar);
registrar->AddPlugin(std::move(plugin));
}
FlutterInappwebviewWindowsPlugin::FlutterInappwebviewWindowsPlugin(flutter::PluginRegistrarWindows* registrar)
: registrar(registrar)
{
inAppBrowserManager = std::make_unique<InAppBrowserManager>(this);
}
FlutterInappwebviewWindowsPlugin::FlutterInappwebviewWindowsPlugin(flutter::PluginRegistrarWindows* registrar)
: registrar(registrar)
{
inAppBrowserManager = std::make_unique<InAppBrowserManager>(this);
}
FlutterInappwebviewWindowsPlugin::~FlutterInappwebviewWindowsPlugin()
{
}
FlutterInappwebviewWindowsPlugin::~FlutterInappwebviewWindowsPlugin()
{}
}

View File

@ -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> inAppBrowserManager;
class FlutterInappwebviewWindowsPlugin : public flutter::Plugin {
public:
flutter::PluginRegistrarWindows* registrar;
std::unique_ptr<InAppBrowserManager> 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_

View File

@ -5,8 +5,9 @@
#include "flutter_inappwebview_windows_plugin.h"
void FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar(
FlutterDesktopPluginRegistrarRef registrar) {
flutter_inappwebview_plugin::FlutterInappwebviewWindowsPlugin::RegisterWithRegistrar(
flutter::PluginRegistrarManager::GetInstance()
->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
FlutterDesktopPluginRegistrarRef registrar)
{
flutter_inappwebview_plugin::FlutterInappwebviewWindowsPlugin::RegisterWithRegistrar(
flutter::PluginRegistrarManager::GetInstance()
->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
}

View File

@ -1,221 +1,226 @@
#include <Windows.h>
#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<InAppBrowserChannelDelegate>(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<InAppBrowserChannelDelegate>(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<InAppWebView>(plugin, id, m_hWnd, InAppBrowser::METHOD_CHANNEL_NAME_PREFIX + id, [this]() -> void {
if (channelDelegate) {
channelDelegate->onBrowserCreated();
}
webView = std::make_unique<InAppWebView>(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<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
// [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<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
// [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<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
// [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<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
// [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<ICoreWebView2Settings> 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<ICoreWebView2Settings> 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());
// // <NavigationEvents>
// // Step 4 - Navigation events
// // register an ICoreWebView2NavigationStartingEventHandler to cancel any non-https navigation
// EventRegistrationToken token;
// inAppBrowser->webview->add_NavigationStarting(Callback<ICoreWebView2NavigationStartingEventHandler>(
// [](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);
// // </NavigationEvents>
// // <NavigationEvents>
// // Step 4 - Navigation events
// // register an ICoreWebView2NavigationStartingEventHandler to cancel any non-https navigation
// EventRegistrationToken token;
// inAppBrowser->webview->add_NavigationStarting(Callback<ICoreWebView2NavigationStartingEventHandler>(
// [](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);
// // </NavigationEvents>
// // <Scripting>
// // 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<ICoreWebView2ExecuteScriptCompletedHandler>(
// [](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT {
// LPCWSTR URL = resultObjectAsJson;
// OutputDebugStringW(URL);
// //doSomethingWithURL(URL);
// return S_OK;
// }).Get());
// // </Scripting>
// // <Scripting>
// // 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<ICoreWebView2ExecuteScriptCompletedHandler>(
// [](HRESULT errorCode, LPCWSTR resultObjectAsJson) -> HRESULT {
// LPCWSTR URL = resultObjectAsJson;
// OutputDebugStringW(URL);
// //doSomethingWithURL(URL);
// return S_OK;
// }).Get());
// // </Scripting>
// // <CommunicationHostWeb>
// // 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<ICoreWebView2WebMessageReceivedEventHandler>(
// [](ICoreWebView2* webview, ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT {
// wil::unique_cotaskmem_string message;
// args->TryGetWebMessageAsString(&message);
// // processMessage(&message);
// webview->PostWebMessageAsString(message.get());
// return S_OK;
// }).Get(), &token);
// // <CommunicationHostWeb>
// // 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<ICoreWebView2WebMessageReceivedEventHandler>(
// [](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);
// // </CommunicationHostWeb>
// nullptr);
// // </CommunicationHostWeb>
// 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<CREATESTRUCT*>(lparam);
SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(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<CREATESTRUCT*>(lparam);
SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(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<RECT*>(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<RECT*>(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<InAppBrowser*>(
GetWindowLongPtr(window, GWLP_USERDATA));
}
InAppBrowser* InAppBrowser::GetThisFromHandle(HWND const window) noexcept
{
return reinterpret_cast<InAppBrowser*>(
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;
}
}

View File

@ -1,11 +1,11 @@
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_H_
#define FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_H_
#include <Windows.h>
#include <string>
#include <optional>
#include <string>
#include <wil/com.h>
#include <Windows.h>
#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> urlRequest;
};
struct InAppBrowserCreationParams
{
std::string id;
std::optional<URLRequest> 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<URLRequest> initialUrlRequest;
std::unique_ptr<InAppWebView> webView;
std::unique_ptr<InAppBrowserChannelDelegate> channelDelegate;
FlutterInappwebviewWindowsPlugin* plugin;
std::string id;
std::optional<URLRequest> initialUrlRequest;
std::unique_ptr<InAppWebView> webView;
std::unique_ptr<InAppBrowserChannelDelegate> 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_

View File

@ -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<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
{
result->NotImplemented();
}
void InAppBrowserChannelDelegate::HandleMethodCall(const flutter::MethodCall<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> 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");
}
}

View File

@ -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<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void HandleMethodCall(
const flutter::MethodCall<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void onBrowserCreated() const;
void onExit() const;
};
void onBrowserCreated() const;
void onExit() const;
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_CHANNEL_DELEGATE_H_

View File

@ -1,53 +1,47 @@
#include <memory>
#include <flutter/method_channel.h>
#include <flutter/standard_method_codec.h>
#include <optional>
#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<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
{
if (method_call.method_name().compare("open") == 0) {
auto* arguments = std::get_if<flutter::EncodableMap>(method_call.arguments());
open(arguments);
result->Success(flutter::EncodableValue(true));
}
else {
result->NotImplemented();
}
}
void InAppBrowserManager::HandleMethodCall(const flutter::MethodCall<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
{
if (method_call.method_name().compare("open") == 0) {
auto* arguments = std::get_if<flutter::EncodableMap>(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<std::string>(*arguments, "id");
auto urlRequestMap = get_optional_fl_map_value<flutter::EncodableMap>(*arguments, "urlRequest");
std::optional<URLRequest> urlRequest = urlRequestMap.has_value() ? std::make_optional<URLRequest>(urlRequestMap.value()) : std::optional<URLRequest>{};
void InAppBrowserManager::open(const flutter::EncodableMap* arguments)
{
auto id = get_fl_map_value<std::string>(*arguments, "id");
auto urlRequestMap = get_optional_fl_map_value<flutter::EncodableMap>(*arguments, "urlRequest");
std::optional<URLRequest> urlRequest = urlRequestMap.has_value() ? std::make_optional<URLRequest>(urlRequestMap.value()) : std::optional<URLRequest>{};
InAppBrowserCreationParams params = {
id,
urlRequest
};
auto inAppBrowser = std::make_unique<InAppBrowser>(plugin, params);
browsers.insert({ id, std::move(inAppBrowser) });
}
InAppBrowserCreationParams params = {
id,
urlRequest
};
auto inAppBrowser = std::make_unique<InAppBrowser>(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;
}
}

View File

@ -1,35 +1,33 @@
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_MANAGER_H_
#define FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_MANAGER_H_
#include <string>
#include <map>
#include <flutter/method_channel.h>
#include <flutter/standard_message_codec.h>
#include <map>
#include <string>
#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<std::string, std::unique_ptr<InAppBrowser>> browsers;
FlutterInappwebviewWindowsPlugin* plugin;
std::map<std::string, std::unique_ptr<InAppBrowser>> browsers;
InAppBrowserManager(FlutterInappwebviewWindowsPlugin* plugin);
~InAppBrowserManager();
InAppBrowserManager(FlutterInappwebviewWindowsPlugin* plugin);
~InAppBrowserManager();
void HandleMethodCall(
const flutter::MethodCall<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void HandleMethodCall(
const flutter::MethodCall<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void open(const flutter::EncodableMap* arguments);
};
void open(const flutter::EncodableMap* arguments);
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_MANAGER_H_

View File

@ -1,258 +1,266 @@
#pragma comment(lib, "Shlwapi.lib")
#include "in_app_webview.h"
#include <Shlwapi.h>
#include <WebView2EnvironmentOptions.h>
#include <wil/wrl.h>
#include <Shlwapi.h>
#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<std::string, int>& id, const HWND parentWindow, const std::function<void()> completionHandler)
: plugin(plugin), id(id), channelDelegate(std::make_unique<WebViewChannelDelegate>(this, plugin->registrar->messenger()))
{
createWebView(parentWindow, completionHandler);
}
InAppWebView::InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant<std::string, int>& id, const HWND parentWindow, const std::function<void()> completionHandler)
: plugin(plugin), id(id), channelDelegate(std::make_unique<WebViewChannelDelegate>(this, plugin->registrar->messenger()))
{
createWebView(parentWindow, completionHandler);
}
InAppWebView::InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant<std::string, int>& id, const HWND parentWindow, const std::string& channelName, const std::function<void()> completionHandler)
: plugin(plugin), id(id), channelDelegate(std::make_unique<WebViewChannelDelegate>(this, plugin->registrar->messenger(), channelName))
{
createWebView(parentWindow, completionHandler);
}
InAppWebView::InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant<std::string, int>& id, const HWND parentWindow, const std::string& channelName, const std::function<void()> completionHandler)
: plugin(plugin), id(id), channelDelegate(std::make_unique<WebViewChannelDelegate>(this, plugin->registrar->messenger(), channelName))
{
createWebView(parentWindow, completionHandler);
}
void InAppWebView::createWebView(const HWND parentWindow, const std::function<void()> completionHandler)
{
CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
[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<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
[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<void()> completionHandler)
{
CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
[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<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
[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<ICoreWebView2NavigationStartingEventHandler>(
[this](ICoreWebView2* sender, ICoreWebView2NavigationStartingEventArgs* args) {
if (!channelDelegate) {
args->put_Cancel(false);
return S_OK;
}
wil::unique_cotaskmem_string uri = nullptr;
std::optional<std::string> url = SUCCEEDED(args->get_Uri(&uri)) ? wide_to_utf8(uri.get()) : std::optional<std::string>{};
webView->add_NavigationStarting(
Callback<ICoreWebView2NavigationStartingEventHandler>(
[this](ICoreWebView2* sender, ICoreWebView2NavigationStartingEventArgs* args)
{
if (!channelDelegate) {
args->put_Cancel(false);
return S_OK;
}
wil::unique_cotaskmem_string requestMethod = nullptr;
wil::com_ptr<ICoreWebView2HttpRequestHeaders> requestHeaders = nullptr;
std::optional<std::map<std::string, std::string>> headers = std::optional<std::map<std::string, std::string>>{};
if (SUCCEEDED(args->get_RequestHeaders(&requestHeaders))) {
headers = std::make_optional<std::map<std::string, std::string>>({});
wil::com_ptr<ICoreWebView2HttpHeadersCollectionIterator> 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<std::string> url = SUCCEEDED(args->get_Uri(&uri)) ? wide_to_utf8(uri.get()) : std::optional<std::string>{};
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<ICoreWebView2HttpRequestHeaders> requestHeaders = nullptr;
std::optional<std::map<std::string, std::string>> headers = std::optional<std::map<std::string, std::string>>{};
if (SUCCEEDED(args->get_RequestHeaders(&requestHeaders))) {
headers = std::make_optional<std::map<std::string, std::string>>({});
wil::com_ptr<ICoreWebView2HttpHeadersCollectionIterator> 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<std::string> method = requestMethod ? wide_to_utf8(requestMethod.get()) : std::optional<std::string>{};
requestHeaders->GetHeader(L"Flutter-InAppWebView-Request-Method", &requestMethod);
requestHeaders->RemoveHeader(L"Flutter-InAppWebView-Request-Method");
}
auto urlRequest = std::make_shared<URLRequest>(url, method, headers, std::nullopt);
auto navigationAction = std::make_shared<NavigationAction>(
urlRequest,
true
);
std::optional<std::string> method = requestMethod ? wide_to_utf8(requestMethod.get()) : std::optional<std::string>{};
UINT64 navigationId;
if (SUCCEEDED(args->get_NavigationId(&navigationId))) {
navigationActions.insert({navigationId, navigationAction});
}
auto urlRequest = std::make_shared<URLRequest>(url, method, headers, std::nullopt);
auto navigationAction = std::make_shared<NavigationAction>(
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<WebViewChannelDelegate::ShouldOverrideUrlLoadingCallback>();
callback->nonNullSuccess = [this, urlRequest](const NavigationActionPolicy actionPolicy) {
callShouldOverrideUrlLoading = false;
if (actionPolicy == allow) {
loadUrl(*urlRequest);
}
return false;
};
auto defaultBehaviour = [this, urlRequest](const std::optional<NavigationActionPolicy> 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<ICoreWebView2NavigationCompletedEventHandler>(
[this](ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args) {
std::shared_ptr<NavigationAction> 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<WebViewChannelDelegate::ShouldOverrideUrlLoadingCallback>();
callback->nonNullSuccess = [this, urlRequest](const NavigationActionPolicy actionPolicy)
{
callShouldOverrideUrlLoading = false;
if (actionPolicy == allow) {
loadUrl(*urlRequest);
}
return false;
};
auto defaultBehaviour = [this, urlRequest](const std::optional<NavigationActionPolicy> 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<ICoreWebView2NavigationCompletedEventHandler>(
[this](ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args)
{
std::shared_ptr<NavigationAction> 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<std::string> url = SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(std::wstring(uri)) : std::optional<std::string>{};
if (isSuccess) {
channelDelegate->onLoadStop(url);
}
else if (!InAppWebView::isSslError(webErrorType) && navigationAction) {
auto webResourceRequest = std::make_unique<WebResourceRequest>(url, navigationAction->request->method, navigationAction->request->headers, navigationAction->isForMainFrame);
int httpStatusCode = 0;
wil::com_ptr<ICoreWebView2NavigationCompletedEventArgs2> args2;
if (SUCCEEDED(args->QueryInterface(IID_PPV_ARGS(&args2))) && SUCCEEDED(args2->get_HttpStatusCode(&httpStatusCode)) && httpStatusCode >= 400) {
auto webResourceResponse = std::make_unique<WebResourceResponse>(httpStatusCode);
channelDelegate->onReceivedHttpError(std::move(webResourceRequest), std::move(webResourceResponse));
}
else if (httpStatusCode < 400) {
auto webResourceError = std::make_unique<WebResourceError>(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<std::string> InAppWebView::getUrl() const
{
LPWSTR uri = nullptr;
return SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(uri) : std::optional<std::string>{};
}
if (channelDelegate) {
LPWSTR uri = nullptr;
std::optional<std::string> url = SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(std::wstring(uri)) : std::optional<std::string>{};
if (isSuccess) {
channelDelegate->onLoadStop(url);
}
else if (!InAppWebView::isSslError(webErrorType) && navigationAction) {
auto webResourceRequest = std::make_unique<WebResourceRequest>(url, navigationAction->request->method, navigationAction->request->headers, navigationAction->isForMainFrame);
int httpStatusCode = 0;
wil::com_ptr<ICoreWebView2NavigationCompletedEventArgs2> args2;
if (SUCCEEDED(args->QueryInterface(IID_PPV_ARGS(&args2))) && SUCCEEDED(args2->get_HttpStatusCode(&httpStatusCode)) && httpStatusCode >= 400) {
auto webResourceResponse = std::make_unique<WebResourceResponse>(httpStatusCode);
channelDelegate->onReceivedHttpError(std::move(webResourceRequest), std::move(webResourceResponse));
}
else if (httpStatusCode < 400) {
auto webResourceError = std::make_unique<WebResourceError>(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<std::string> InAppWebView::getUrl() const
{
LPWSTR uri = nullptr;
return SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(uri) : std::optional<std::string>{};
}
wil::com_ptr<ICoreWebView2Environment2> webViewEnv2;
wil::com_ptr<ICoreWebView2_2> webView2;
if (SUCCEEDED(webViewEnv->QueryInterface(IID_PPV_ARGS(&webViewEnv2))) && SUCCEEDED(webView->QueryInterface(IID_PPV_ARGS(&webView2)))) {
wil::com_ptr<ICoreWebView2WebResourceRequest> webResourceRequest;
std::wstring method = urlRequest.method.has_value() ? ansi_to_wide(urlRequest.method.value()) : L"GET";
wil::com_ptr<IStream> postDataStream = nullptr;
if (urlRequest.body.has_value()) {
auto postData = std::string(urlRequest.body->begin(), urlRequest.body->end());
postDataStream = SHCreateMemStream(
reinterpret_cast<const BYTE*>(postData.data()), static_cast<UINT>(postData.length()));
}
webViewEnv2->CreateWebResourceRequest(
url.c_str(),
method.c_str(),
postDataStream.get(),
L"",
&webResourceRequest
);
wil::com_ptr<ICoreWebView2HttpRequestHeaders> 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<ICoreWebView2Environment2> webViewEnv2;
wil::com_ptr<ICoreWebView2_2> webView2;
if (SUCCEEDED(webViewEnv->QueryInterface(IID_PPV_ARGS(&webViewEnv2))) && SUCCEEDED(webView->QueryInterface(IID_PPV_ARGS(&webView2)))) {
wil::com_ptr<ICoreWebView2WebResourceRequest> webResourceRequest;
std::wstring method = urlRequest.method.has_value() ? ansi_to_wide(urlRequest.method.value()) : L"GET";
wil::com_ptr<IStream> postDataStream = nullptr;
if (urlRequest.body.has_value()) {
auto postData = std::string(urlRequest.body->begin(), urlRequest.body->end());
postDataStream = SHCreateMemStream(
reinterpret_cast<const BYTE*>(postData.data()), static_cast<UINT>(postData.length()));
}
webViewEnv2->CreateWebResourceRequest(
url.c_str(),
method.c_str(),
postDataStream.get(),
L"",
&webResourceRequest
);
wil::com_ptr<ICoreWebView2HttpRequestHeaders> 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;
}
}

View File

@ -2,43 +2,43 @@
#define FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_WEBVIEW_H_
#include <functional>
#include <WebView2.h>
#include <wil/com.h>
#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<std::string, int> id;
wil::com_ptr<ICoreWebView2Environment> webViewEnv;
wil::com_ptr<ICoreWebView2Controller> webViewController;
wil::com_ptr<ICoreWebView2> webView;
const std::unique_ptr<WebViewChannelDelegate> channelDelegate;
std::map<UINT64, std::shared_ptr<NavigationAction>> navigationActions = {};
const FlutterInappwebviewWindowsPlugin* plugin;
const std::variant<std::string, int> id;
wil::com_ptr<ICoreWebView2Environment> webViewEnv;
wil::com_ptr<ICoreWebView2Controller> webViewController;
wil::com_ptr<ICoreWebView2> webView;
const std::unique_ptr<WebViewChannelDelegate> channelDelegate;
std::map<UINT64, std::shared_ptr<NavigationAction>> navigationActions = {};
InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant<std::string, int>& id, const HWND parentWindow, const std::function<void()> completionHandler);
InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant<std::string, int>& id, const HWND parentWindow, const std::string& channelName, const std::function<void()> completionHandler);
~InAppWebView();
InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant<std::string, int>& id, const HWND parentWindow, const std::function<void()> completionHandler);
InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant<std::string, int>& id, const HWND parentWindow, const std::string& channelName, const std::function<void()> completionHandler);
~InAppWebView();
std::optional<std::string> getUrl() const;
void loadUrl(const URLRequest& urlRequest) const;
std::optional<std::string> 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<void()> 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<void()> completionHandler);
void InAppWebView::registerEventHandlers();
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_WEBVIEW_H_

View File

@ -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<int>(*value);
return static_cast<NavigationActionPolicy>(navigationPolicy);
};
}
void WebViewChannelDelegate::HandleMethodCall(const flutter::MethodCall<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> 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<int>(*value);
return static_cast<NavigationActionPolicy>(navigationPolicy);
};
}
void WebViewChannelDelegate::HandleMethodCall(const flutter::MethodCall<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> 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<flutter::EncodableMap>(*method_call.arguments());
auto urlRequest = std::make_unique<URLRequest>(get_fl_map_value<flutter::EncodableMap>(arguments, "urlRequest"));
webView->loadUrl(*urlRequest);
result->Success(make_fl_value(true));
}
else {
result->NotImplemented();
}
}
void WebViewChannelDelegate::onLoadStart(const std::optional<std::string>& url) const
{
if (!channel) {
return;
}
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap {
{flutter::EncodableValue("url"), make_fl_value(url)},
});
channel->InvokeMethod("onLoadStart", std::move(arguments));
}
void WebViewChannelDelegate::onLoadStop(const std::optional<std::string>& url) const
{
if (!channel) {
return;
}
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("url"), make_fl_value(url)},
});
channel->InvokeMethod("onLoadStop", std::move(arguments));
}
void WebViewChannelDelegate::shouldOverrideUrlLoading(std::shared_ptr<NavigationAction> navigationAction, std::unique_ptr<ShouldOverrideUrlLoadingCallback> callback) const
{
if (!channel) {
return;
}
auto arguments = std::make_unique<flutter::EncodableValue>(navigationAction->toEncodableMap());
channel->InvokeMethod("shouldOverrideUrlLoading", std::move(arguments), std::move(callback));
}
void WebViewChannelDelegate::onReceivedError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceError> error) const
{
if (!channel) {
return;
}
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("request"), request->toEncodableMap()},
{flutter::EncodableValue("error"), error->toEncodableMap()},
});
channel->InvokeMethod("onReceivedError", std::move(arguments));
}
void WebViewChannelDelegate::onReceivedHttpError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceResponse> errorResponse) const
{
if (!channel) {
return;
}
auto arguments = std::make_unique<flutter::EncodableValue>(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<flutter::EncodableMap>(*method_call.arguments());
auto urlRequest = std::make_unique<URLRequest>(get_fl_map_value<flutter::EncodableMap>(arguments, "urlRequest"));
webView->loadUrl(*urlRequest);
result->Success(make_fl_value(true));
}
else {
result->NotImplemented();
}
}
void WebViewChannelDelegate::onLoadStart(const std::optional<std::string>& url) const
{
if (!channel) {
return;
}
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("url"), make_fl_value(url)},
});
channel->InvokeMethod("onLoadStart", std::move(arguments));
}
void WebViewChannelDelegate::onLoadStop(const std::optional<std::string>& url) const
{
if (!channel) {
return;
}
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("url"), make_fl_value(url)},
});
channel->InvokeMethod("onLoadStop", std::move(arguments));
}
void WebViewChannelDelegate::shouldOverrideUrlLoading(std::shared_ptr<NavigationAction> navigationAction, std::unique_ptr<ShouldOverrideUrlLoadingCallback> callback) const
{
if (!channel) {
return;
}
auto arguments = std::make_unique<flutter::EncodableValue>(navigationAction->toEncodableMap());
channel->InvokeMethod("shouldOverrideUrlLoading", std::move(arguments), std::move(callback));
}
void WebViewChannelDelegate::onReceivedError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceError> error) const
{
if (!channel) {
return;
}
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("request"), request->toEncodableMap()},
{flutter::EncodableValue("error"), error->toEncodableMap()},
});
channel->InvokeMethod("onReceivedError", std::move(arguments));
}
void WebViewChannelDelegate::onReceivedHttpError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceResponse> errorResponse) const
{
if (!channel) {
return;
}
auto arguments = std::make_unique<flutter::EncodableValue>(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;
}
}

View File

@ -4,44 +4,44 @@
#include <flutter/method_channel.h>
#include <flutter/standard_message_codec.h>
#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<NavigationActionPolicy> {
public:
InAppWebView* webView;
class ShouldOverrideUrlLoadingCallback : public BaseCallbackResult<NavigationActionPolicy> {
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<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void onLoadStart(const std::optional<std::string>& url) const;
void onLoadStop(const std::optional<std::string>& url) const;
void shouldOverrideUrlLoading(std::shared_ptr<NavigationAction> navigationAction, std::unique_ptr<ShouldOverrideUrlLoadingCallback> callback) const;
void WebViewChannelDelegate::onReceivedError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceError> error) const;
void WebViewChannelDelegate::onReceivedHttpError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceResponse> 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<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void onLoadStart(const std::optional<std::string>& url) const;
void onLoadStop(const std::optional<std::string>& url) const;
void shouldOverrideUrlLoading(std::shared_ptr<NavigationAction> navigationAction, std::unique_ptr<ShouldOverrideUrlLoadingCallback> callback) const;
void WebViewChannelDelegate::onReceivedError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceError> error) const;
void WebViewChannelDelegate::onReceivedHttpError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceResponse> error) const;
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEBVIEW_CHANNEL_DELEGATE_H_

View File

@ -13,7 +13,7 @@
extern "C" {
#endif
FLUTTER_PLUGIN_EXPORT void FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar(
FLUTTER_PLUGIN_EXPORT void FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar(
FlutterDesktopPluginRegistrarRef registrar);
#if defined(__cplusplus)

View File

@ -1,53 +1,57 @@
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_BASE_CALLBACK_RESULT_H_
#define FLUTTER_INAPPWEBVIEW_PLUGIN_BASE_CALLBACK_RESULT_H_
#include <flutter/standard_method_codec.h>
#include <flutter/method_result_functions.h>
#include <flutter/standard_method_codec.h>
#include <optional>
namespace flutter_inappwebview_plugin
{
template <typename T>
class BaseCallbackResult : public flutter::MethodResultFunctions<flutter::EncodableValue>
{
public:
flutter::ResultHandlerError<flutter::EncodableValue> error;
flutter::ResultHandlerNotImplemented<flutter::EncodableValue> notImplemented;
std::function<bool(const T result)> nonNullSuccess = [](const T result) { return true; };
std::function<bool()> nullSuccess = []() { return true; };
std::function<void(const std::optional<T> result)> defaultBehaviour = [](const std::optional<T> result) {};
std::function<std::optional<T>(const flutter::EncodableValue* result)> decodeResult = [](const flutter::EncodableValue* result) { return std::nullopt; };
template <typename T>
class BaseCallbackResult : public flutter::MethodResultFunctions<flutter::EncodableValue>
{
public:
flutter::ResultHandlerError<flutter::EncodableValue> error;
flutter::ResultHandlerNotImplemented<flutter::EncodableValue> notImplemented;
std::function<bool(const T result)> nonNullSuccess = [](const T result) { return true; };
std::function<bool()> nullSuccess = []() { return true; };
std::function<void(const std::optional<T> result)> defaultBehaviour = [](const std::optional<T> result) {};
std::function<std::optional<T>(const flutter::EncodableValue* result)> decodeResult = [](const flutter::EncodableValue* result) { return std::nullopt; };
BaseCallbackResult<T>() :
MethodResultFunctions(
[this](const flutter::EncodableValue* val) {
std::optional<T> 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<T>() {};
};
BaseCallbackResult<T>() :
MethodResultFunctions(
[this](const flutter::EncodableValue* val)
{
std::optional<T> 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<T>() {};
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_BASE_CALLBACK_RESULT_H_

View File

@ -1,37 +1,35 @@
#include <flutter/method_channel.h>
#include <flutter/standard_method_codec.h>
#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<flutter::MethodChannel<flutter::EncodableValue>>(
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<flutter::MethodChannel<flutter::EncodableValue>>(
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<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
{
void ChannelDelegate::HandleMethodCall(
const flutter::MethodCall<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> 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();
}
}

View File

@ -5,21 +5,21 @@
namespace flutter_inappwebview_plugin
{
class ChannelDelegate
{
using FlutterMethodChannel = std::shared_ptr<flutter::MethodChannel<flutter::EncodableValue>>;
class ChannelDelegate
{
using FlutterMethodChannel = std::shared_ptr<flutter::MethodChannel<flutter::EncodableValue>>;
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<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
};
virtual void HandleMethodCall(
const flutter::MethodCall<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_CHANNEL_DELEGATE_H_

View File

@ -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<URLRequest> request, const bool& isForMainFrame)
: request(std::move(request)), isForMainFrame(isForMainFrame)
{
NavigationAction::NavigationAction(std::shared_ptr<URLRequest> 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)}
};
}
}

View File

@ -3,20 +3,22 @@
#include <flutter/standard_method_codec.h>
#include <optional>
#include "url_request.h"
namespace flutter_inappwebview_plugin
{
class NavigationAction
{
public:
const std::shared_ptr<URLRequest> request;
const bool isForMainFrame;
class NavigationAction
{
public:
const std::shared_ptr<URLRequest> request;
const bool isForMainFrame;
NavigationAction(std::shared_ptr<URLRequest> request, const bool& isForMainFrame);
~NavigationAction() = default;
flutter::EncodableMap toEncodableMap();
};
NavigationAction(std::shared_ptr<URLRequest> request, const bool& isForMainFrame);
~NavigationAction() = default;
flutter::EncodableMap toEncodableMap() const;
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_NAVIGATION_ACTION_H_

View File

@ -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<std::string>& url, const std::optional<std::string>& method,
const std::optional<std::map<std::string, std::string>>& headers, const std::optional<std::vector<uint8_t>>& body)
: url(url), method(method), headers(headers), body(body)
{
URLRequest::URLRequest(const std::optional<std::string>& url, const std::optional<std::string>& method,
const std::optional<std::map<std::string, std::string>>& headers, const std::optional<std::vector<uint8_t>>& body)
: url(url), method(method), headers(headers), body(body)
{}
}
URLRequest::URLRequest(const flutter::EncodableMap& map)
: url(get_optional_fl_map_value<std::string>(map, "url")),
method(get_optional_fl_map_value<std::string>(map, "method")),
headers(get_optional_fl_map_value<std::string, std::string>(map, "headers")),
body(get_optional_fl_map_value<std::vector<uint8_t>>(map, "body"))
{}
URLRequest::URLRequest(const flutter::EncodableMap& map)
: url(get_optional_fl_map_value<std::string>(map, "url")),
method(get_optional_fl_map_value<std::string>(map, "method")),
headers(get_optional_fl_map_value<std::string, std::string>(map, "headers")),
body(get_optional_fl_map_value<std::vector<uint8_t>>(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)}
};
}
}

View File

@ -2,25 +2,27 @@
#define FLUTTER_INAPPWEBVIEW_PLUGIN_URL_REQUEST_H_
#include <flutter/standard_method_codec.h>
#include <optional>
#include "../utils/flutter.h"
namespace flutter_inappwebview_plugin
{
class URLRequest
{
public:
const std::optional<std::string> url;
const std::optional<std::string> method;
const std::optional<std::map<std::string, std::string>> headers;
const std::optional<std::vector<uint8_t>> body;
class URLRequest
{
public:
const std::optional<std::string> url;
const std::optional<std::string> method;
const std::optional<std::map<std::string, std::string>> headers;
const std::optional<std::vector<uint8_t>> body;
URLRequest(const std::optional<std::string>& url, const std::optional<std::string>& method,
const std::optional<std::map<std::string, std::string>>& headers, const std::optional<std::vector<uint8_t>>& body);
URLRequest(const flutter::EncodableMap& map);
~URLRequest() = default;
flutter::EncodableMap toEncodableMap();
};
URLRequest(const std::optional<std::string>& url, const std::optional<std::string>& method,
const std::optional<std::map<std::string, std::string>>& headers, const std::optional<std::vector<uint8_t>>& body);
URLRequest(const flutter::EncodableMap& map);
~URLRequest() = default;
flutter::EncodableMap toEncodableMap() const;
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_URL_REQUEST_H_

View File

@ -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<std::string>(map, "description")),
type(get_fl_map_value<int>(map, "type"))
{}
WebResourceError::WebResourceError(const flutter::EncodableMap& map)
: description(get_fl_map_value<std::string>(map, "description")),
type(get_fl_map_value<int>(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)}
};
}
}

View File

@ -2,45 +2,45 @@
#define FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_ERROR_H_
#include <flutter/standard_method_codec.h>
#include <optional>
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_

View File

@ -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<std::string>& url, const std::optional<std::string>& method,
const std::optional<std::map<std::string, std::string>>& headers, const std::optional<bool>& isForMainFrame)
: url(url), method(method), headers(headers), isForMainFrame(isForMainFrame)
{
WebResourceRequest::WebResourceRequest(const std::optional<std::string>& url, const std::optional<std::string>& method,
const std::optional<std::map<std::string, std::string>>& headers, const std::optional<bool>& isForMainFrame)
: url(url), method(method), headers(headers), isForMainFrame(isForMainFrame)
{}
}
WebResourceRequest::WebResourceRequest(const flutter::EncodableMap& map)
: url(get_optional_fl_map_value<std::string>(map, "url")),
method(get_optional_fl_map_value<std::string>(map, "method")),
headers(get_optional_fl_map_value<std::string, std::string>(map, "headers")),
isForMainFrame(get_optional_fl_map_value<bool>(map, "isForMainFrame"))
{}
WebResourceRequest::WebResourceRequest(const flutter::EncodableMap& map)
: url(get_optional_fl_map_value<std::string>(map, "url")),
method(get_optional_fl_map_value<std::string>(map, "method")),
headers(get_optional_fl_map_value<std::string, std::string>(map, "headers")),
isForMainFrame(get_optional_fl_map_value<bool>(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)}
};
}
}

View File

@ -2,25 +2,25 @@
#define FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_REQUEST_H_
#include <flutter/standard_method_codec.h>
#include <optional>
namespace flutter_inappwebview_plugin
{
class WebResourceRequest
{
public:
const std::optional<std::string> url;
const std::optional<std::string> method;
const std::optional<std::map<std::string, std::string>> headers;
const std::optional<bool> isForMainFrame;
class WebResourceRequest
{
public:
const std::optional<std::string> url;
const std::optional<std::string> method;
const std::optional<std::map<std::string, std::string>> headers;
const std::optional<bool> isForMainFrame;
WebResourceRequest(const std::optional<std::string>& url, const std::optional<std::string>& method,
const std::optional<std::map<std::string, std::string>>& headers, const std::optional<bool>& isForMainFrame);
WebResourceRequest(const flutter::EncodableMap& map);
~WebResourceRequest() = default;
flutter::EncodableMap toEncodableMap();
};
WebResourceRequest(const std::optional<std::string>& url, const std::optional<std::string>& method,
const std::optional<std::map<std::string, std::string>>& headers, const std::optional<bool>& isForMainFrame);
WebResourceRequest(const flutter::EncodableMap& map);
~WebResourceRequest() = default;
flutter::EncodableMap toEncodableMap() const;
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_REQUEST_H_

View File

@ -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<int>& statusCode)
: statusCode(statusCode)
{
WebResourceResponse::WebResourceResponse(const std::optional<int>& statusCode)
: statusCode(statusCode)
{}
}
WebResourceResponse::WebResourceResponse(const flutter::EncodableMap& map)
: statusCode(get_optional_fl_map_value<int>(map, "statusCode"))
{}
WebResourceResponse::WebResourceResponse(const flutter::EncodableMap& map)
: statusCode(get_optional_fl_map_value<int>(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)}
};
}
}

View File

@ -2,21 +2,21 @@
#define FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_RESPONSE_H_
#include <flutter/standard_method_codec.h>
#include <optional>
namespace flutter_inappwebview_plugin
{
class WebResourceResponse
{
public:
const std::optional<int> statusCode;
class WebResourceResponse
{
public:
const std::optional<int> statusCode;
WebResourceResponse(const std::optional<int>& statusCode);
WebResourceResponse(const flutter::EncodableMap& map);
~WebResourceResponse() = default;
flutter::EncodableMap toEncodableMap();
};
WebResourceResponse(const std::optional<int>& statusCode);
WebResourceResponse(const flutter::EncodableMap& map);
~WebResourceResponse() = default;
flutter::EncodableMap toEncodableMap() const;
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_RESPONSE_H_

View File

@ -1,77 +1,110 @@
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_
#define FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_
#include <string>
#include <optional>
#include <flutter/encodable_value.h>
#include <optional>
#include <string>
#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<typename T>
static inline flutter::EncodableValue make_fl_value(const T& val)
{
return flutter::EncodableValue(val);
}
template<typename T>
static inline flutter::EncodableValue make_fl_value(const T& val)
{
return flutter::EncodableValue(val);
}
template<typename T>
static inline flutter::EncodableValue make_fl_value(const T* val)
{
return val == nullptr ? make_fl_value() : flutter::EncodableValue(val);
}
template<typename T>
static inline flutter::EncodableValue make_fl_value(const T* val)
{
return val == nullptr ? make_fl_value() : flutter::EncodableValue(val);
}
template<typename T>
static inline flutter::EncodableValue make_fl_value(const std::optional<T>& optional)
{
return optional.has_value() ? make_fl_value(optional.value()) : make_fl_value();
template<typename T>
static inline flutter::EncodableValue make_fl_value(const std::vector<T>& 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<std::map<std::string, std::string>>& 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<typename K, typename T>
static inline flutter::EncodableValue make_fl_value(const std::map<K, T>& map)
{
auto encodableMap = flutter::EncodableMap{};
for (auto const& [key, val] : map) {
encodableMap.insert({ make_fl_value(key), make_fl_value(val) });
}
return encodableMap;
}
template<typename T>
static inline T get_fl_map_value(const flutter::EncodableMap& map, const char* string)
{
return std::get<T>(map.at(make_fl_value(string)));
}
template<typename T>
static inline flutter::EncodableValue make_fl_value(const std::optional<T>& optional)
{
return optional.has_value() ? make_fl_value(optional.value()) : make_fl_value();
}
template<typename T>
static inline std::optional<T> get_optional_fl_map_value(const flutter::EncodableMap& map, const char* string)
{
return make_pointer_optional<T>(std::get_if<T>(&map.at(make_fl_value(string))));
template<typename T>
static inline flutter::EncodableValue make_fl_value(const std::optional<std::vector<T>>& 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<typename K, typename T>
static inline std::optional<std::map<K, T>> get_optional_fl_map_value(const flutter::EncodableMap& map, const char* string)
{
auto flMap = std::get_if<flutter::EncodableMap>(&map.at(make_fl_value(string)));
if (flMap) {
auto mapValue = std::map<K, T>{};
for (auto itr = flMap->begin(); itr != flMap->end(); itr++)
{
mapValue.insert({ std::get<K>(itr->first), std::get<T>(itr->second) });
}
return make_pointer_optional<std::map<K, T>>(&mapValue);
}
return std::nullopt;
template<typename K, typename T>
static inline flutter::EncodableValue make_fl_value(const std::optional<std::map<K, T>>& 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<typename T>
static inline T get_fl_map_value(const flutter::EncodableMap& map, const char* string)
{
return std::get<T>(map.at(make_fl_value(string)));
}
template<typename T>
static inline std::optional<T> get_optional_fl_map_value(const flutter::EncodableMap& map, const char* string)
{
return make_pointer_optional<T>(std::get_if<T>(&map.at(make_fl_value(string))));
}
template<typename K, typename T>
static inline std::optional<std::map<K, T>> get_optional_fl_map_value(const flutter::EncodableMap& map, const char* string)
{
auto flMap = std::get_if<flutter::EncodableMap>(&map.at(make_fl_value(string)));
if (flMap) {
auto mapValue = std::map<K, T>{};
for (auto itr = flMap->begin(); itr != flMap->end(); itr++) {
mapValue.insert({ std::get<K>(itr->first), std::get<T>(itr->second) });
}
return make_pointer_optional<std::map<K, T>>(&mapValue);
}
return std::nullopt;
}
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_

View File

@ -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<wchar_t> 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<char> 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<wchar_t> 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<char> 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<wchar_t> 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<char> 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<wchar_t> 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<char> 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<char> 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<char> 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 <typename T>
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 <typename T>
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<char>& (*pf)(std::basic_ios<char>&)) // 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<char>& (*pf)(std::basic_ios<char>&)) // For manipulators...
{
(*m_ostrm) << pf;
return *this;
}
};
}
#define U8(X) ((const char *)u8##X)

View File

@ -1,52 +1,57 @@
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_
#define FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_
#include <iostream>
#include <string>
#include <optional>
#include <algorithm>
#include <iostream>
#include <map>
#include <optional>
#include <string>
#include <variant>
#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<typename T>
static inline std::optional<T> make_pointer_optional(const T* value)
{
return value == nullptr ? std::nullopt : std::make_optional<T>(*value);
}
template<typename T>
static inline std::optional<T> make_pointer_optional(const T* value)
{
return value == nullptr ? std::nullopt : std::make_optional<T>(*value);
}
static inline std::string variant_to_string(const std::variant<std::string, int>& var)
{
return std::visit([](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, std::string>)
return arg;
else if constexpr (std::is_arithmetic_v<T>)
return std::to_string(arg);
else
static_assert(always_false_v<T>, "non-exhaustive visitor!");
}, var);
}
static inline std::string variant_to_string(const std::variant<std::string, int>& var)
{
return std::visit([](auto&& arg)
{
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, std::string>)
return arg;
else if constexpr (std::is_arithmetic_v<T>)
return std::to_string(arg);
else
static_assert(always_false_v<T>, "non-exhaustive visitor!");
}, var);
}
template<typename K, typename T>
static inline bool map_contains(const std::map<K, T>& map, const K& key)
{
return map.find(key) != map.end();
}
template<typename K, typename T>
static inline bool map_contains(const std::map<K, T>& map, const K& key)
{
return map.find(key) != map.end();
}
template<typename K, typename T>
static inline T map_at_or_null(const std::map<K, T>& map, const K& key)
{
auto itr = map.find(key);
return itr != map.end() ? itr->second : nullptr;
}
template<typename K, typename T>
static inline T map_at_or_null(const std::map<K, T>& map, const K& key)
{
auto itr = map.find(key);
return itr != map.end() ? itr->second : nullptr;
}
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_