windows: added initial webview settings, updated flutter.h get fl options implementations

This commit is contained in:
unknown 2024-01-11 11:10:10 +01:00
parent 8499949a22
commit 11659f22e1
20 changed files with 359 additions and 54 deletions

75
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,75 @@
{
"cmake.configureOnOpen": false,
"files.associations": {
"algorithm": "cpp",
"any": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"cctype": "cpp",
"charconv": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"compare": "cpp",
"concepts": "cpp",
"coroutine": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"exception": "cpp",
"format": "cpp",
"forward_list": "cpp",
"functional": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"ios": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"iterator": "cpp",
"limits": "cpp",
"list": "cpp",
"locale": "cpp",
"map": "cpp",
"memory": "cpp",
"new": "cpp",
"optional": "cpp",
"ostream": "cpp",
"ratio": "cpp",
"set": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"string": "cpp",
"system_error": "cpp",
"thread": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"typeinfo": "cpp",
"unordered_map": "cpp",
"utility": "cpp",
"variant": "cpp",
"vector": "cpp",
"xfacet": "cpp",
"xhash": "cpp",
"xiosbase": "cpp",
"xlocale": "cpp",
"xlocbuf": "cpp",
"xlocinfo": "cpp",
"xlocmes": "cpp",
"xlocmon": "cpp",
"xlocnum": "cpp",
"xloctime": "cpp",
"xmemory": "cpp",
"xstring": "cpp",
"xtr1common": "cpp",
"xtree": "cpp",
"xutility": "cpp"
}
}

View File

@ -22,7 +22,6 @@ cmake_policy(VERSION 3.14...3.25)
set(PLUGIN_NAME "flutter_inappwebview_windows_plugin")
set(NUGET_URL https://dist.nuget.org/win-x86-commandline/latest/nuget.exe)
set(NUGET_SHA256 852b71cc8c8c2d40d09ea49d321ff56fd2397b9d6ea9f96e532530307bbbafd3)
find_program(NUGET nuget)
if(NOT NUGET)
@ -32,11 +31,6 @@ if(NOT NUGET)
message(NOTICE "Attempting to download nuget.")
file(DOWNLOAD ${NUGET_URL} ${NUGET})
endif()
file(SHA256 ${NUGET} NUGET_DL_HASH)
if (NOT NUGET_DL_HASH STREQUAL NUGET_SHA256)
message(FATAL_ERROR "Integrity check for ${NUGET} failed.")
endif()
endif()
add_custom_target(${PROJECT_NAME}_DEPENDENCIES_DOWNLOAD ALL)
@ -67,10 +61,14 @@ list(APPEND PLUGIN_SOURCES
"types/web_resource_request.h"
"types/web_resource_response.cpp"
"types/web_resource_response.h"
"in_app_webview/in_app_webview_settings.cpp"
"in_app_webview/in_app_webview_settings.h"
"in_app_webview/in_app_webview.cpp"
"in_app_webview/in_app_webview.h"
"in_app_webview/webview_channel_delegate.cpp"
"in_app_webview/webview_channel_delegate.h"
"in_app_browser/in_app_browser_settings.cpp"
"in_app_browser/in_app_browser_settings.h"
"in_app_browser/in_app_browser_manager.cpp"
"in_app_browser/in_app_browser_manager.h"
"in_app_browser/in_app_browser.cpp"

View File

@ -6,13 +6,15 @@
namespace flutter_inappwebview_plugin
{
InAppBrowser::InAppBrowser(FlutterInappwebviewWindowsPlugin* plugin, const InAppBrowserCreationParams& params)
InAppBrowser::InAppBrowser(const FlutterInappwebviewWindowsPlugin* plugin, const InAppBrowserCreationParams& params)
: plugin(plugin),
m_hInstance(GetModuleHandle(nullptr)),
id(params.id),
initialUrlRequest(params.urlRequest),
settings(params.initialSettings),
channelDelegate(std::make_unique<InAppBrowserChannelDelegate>(id, plugin->registrar->messenger()))
{
WNDCLASS wndClass = {};
wndClass.lpszClassName = InAppBrowser::CLASS_NAME;
wndClass.hInstance = m_hInstance;
@ -39,7 +41,12 @@ namespace flutter_inappwebview_plugin
ShowWindow(m_hWnd, SW_SHOW);
webView = std::make_unique<InAppWebView>(plugin, id, m_hWnd, InAppBrowser::METHOD_CHANNEL_NAME_PREFIX + id, [this]() -> void
InAppWebViewCreationParams webViewParams = {
id,
params.initialWebViewSettings
};
webView = std::make_unique<InAppWebView>(plugin, webViewParams, m_hWnd, InAppBrowser::METHOD_CHANNEL_NAME_PREFIX + id, [this]() -> void
{
if (channelDelegate) {
channelDelegate->onBrowserCreated();

View File

@ -8,15 +8,19 @@
#include "../flutter_inappwebview_windows_plugin.h"
#include "../in_app_webview/in_app_webview.h"
#include "../in_app_webview/in_app_webview_settings.h"
#include "../types/url_request.h"
#include "in_app_browser_channel_delegate.h"
#include "in_app_browser_settings.h"
namespace flutter_inappwebview_plugin
{
struct InAppBrowserCreationParams
{
std::string id;
std::optional<URLRequest> urlRequest;
const std::string id;
const std::optional<URLRequest> urlRequest;
const std::shared_ptr<InAppBrowserSettings> initialSettings;
const std::shared_ptr<InAppWebViewSettings> initialWebViewSettings;
};
class InAppBrowser {
@ -29,17 +33,18 @@ namespace flutter_inappwebview_plugin
WPARAM wparam,
LPARAM lparam) noexcept;
FlutterInappwebviewWindowsPlugin* plugin;
std::string id;
std::optional<URLRequest> initialUrlRequest;
const FlutterInappwebviewWindowsPlugin* plugin;
const std::string id;
const std::optional<URLRequest> initialUrlRequest;
std::unique_ptr<InAppWebView> webView;
std::unique_ptr<InAppBrowserChannelDelegate> channelDelegate;
const std::shared_ptr<InAppBrowserSettings> settings;
InAppBrowser(FlutterInappwebviewWindowsPlugin* plugin, const InAppBrowserCreationParams& params);
InAppBrowser(const FlutterInappwebviewWindowsPlugin* plugin, const InAppBrowserCreationParams& params);
~InAppBrowser();
private:
HINSTANCE m_hInstance;
const HINSTANCE m_hInstance;
HWND m_hWnd;
bool destroyed_ = false;
static InAppBrowser* GetThisFromHandle(HWND window) noexcept;

View File

@ -1,13 +1,15 @@
#include <flutter/method_channel.h>
#include <flutter/standard_method_codec.h>
#include "../in_app_webview/in_app_webview_settings.h"
#include "../types/url_request.h"
#include "../utils/flutter.h"
#include "in_app_browser_manager.h"
#include "in_app_browser_settings.h"
namespace flutter_inappwebview_plugin
{
InAppBrowserManager::InAppBrowserManager(FlutterInappwebviewWindowsPlugin* plugin)
InAppBrowserManager::InAppBrowserManager(const FlutterInappwebviewWindowsPlugin* plugin)
: plugin(plugin), ChannelDelegate(plugin->registrar->messenger(), InAppBrowserManager::METHOD_CHANNEL_NAME)
{}
@ -30,10 +32,17 @@ namespace flutter_inappwebview_plugin
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>{};
auto settingsMap = get_fl_map_value<flutter::EncodableMap>(*arguments, "settings");
auto initialSettings = std::make_unique<InAppBrowserSettings>(settingsMap);
auto initialWebViewSettings = std::make_unique<InAppWebViewSettings>(settingsMap);
InAppBrowserCreationParams params = {
id,
urlRequest
urlRequest,
std::move(initialSettings),
std::move(initialWebViewSettings)
};
auto inAppBrowser = std::make_unique<InAppBrowser>(plugin, params);
browsers.insert({ id, std::move(inAppBrowser) });
}

View File

@ -17,10 +17,10 @@ namespace flutter_inappwebview_plugin
public:
static inline const std::string METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappbrowser";
FlutterInappwebviewWindowsPlugin* plugin;
const FlutterInappwebviewWindowsPlugin* plugin;
std::map<std::string, std::unique_ptr<InAppBrowser>> browsers;
InAppBrowserManager(FlutterInappwebviewWindowsPlugin* plugin);
InAppBrowserManager(const FlutterInappwebviewWindowsPlugin* plugin);
~InAppBrowserManager();
void HandleMethodCall(

View File

@ -0,0 +1,45 @@
#include "../utils/flutter.h"
#include "in_app_browser_settings.h"
namespace flutter_inappwebview_plugin
{
namespace
{
InAppBrowserWindowType inAppBrowserWindowTypeFromString(const std::string& s)
{
if (s.compare("CHILD") == 0) {
return child;
}
else if (s.compare("TABBED") == 0) {
return tabbed;
}
return window;
}
std::string inAppBrowserWindowTypeToString(const InAppBrowserWindowType& t)
{
switch (t) {
case child:
return "CHILD";
case tabbed:
return "TABBED";
default:
return "WINDOW";
}
}
}
InAppBrowserSettings::InAppBrowserSettings() {};
InAppBrowserSettings::InAppBrowserSettings(const flutter::EncodableMap& encodableMap)
{
hidden = get_fl_map_value(encodableMap, "hidden", hidden);
windowType = inAppBrowserWindowTypeFromString(get_fl_map_value<std::string>(encodableMap, "windowType", inAppBrowserWindowTypeToString(window)));
windowAlphaValue = get_fl_map_value(encodableMap, "windowAlphaValue", windowAlphaValue);
}
InAppBrowserSettings::~InAppBrowserSettings()
{
debugLog("dealloc InAppBrowserSettings");
};
}

View File

@ -0,0 +1,27 @@
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_SETTINGS_H_
#define FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_SETTINGS_H_
#include <flutter/standard_message_codec.h>
#include <string>
namespace flutter_inappwebview_plugin
{
enum InAppBrowserWindowType {
window,
child,
tabbed
};
class InAppBrowserSettings
{
public:
bool hidden = false;
InAppBrowserWindowType windowType = window;
double windowAlphaValue = 1.0;
InAppBrowserSettings();
InAppBrowserSettings(const flutter::EncodableMap& encodableMap);
~InAppBrowserSettings();
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_BROWSER_SETTINGS_H_

View File

@ -1,5 +1,6 @@
#pragma comment(lib, "Shlwapi.lib")
#include <cstring>
#include <Shlwapi.h>
#include <WebView2EnvironmentOptions.h>
#include <wil/wrl.h>
@ -14,14 +15,14 @@ namespace flutter_inappwebview_plugin
{
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()))
InAppWebView::InAppWebView(const FlutterInappwebviewWindowsPlugin* plugin, const InAppWebViewCreationParams& params, const HWND parentWindow, const std::function<void()> completionHandler)
: plugin(plugin), id(params.id), settings(params.initialSettings), 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))
InAppWebView::InAppWebView(const FlutterInappwebviewWindowsPlugin* plugin, const InAppWebViewCreationParams& params, const HWND parentWindow, const std::string& channelName, const std::function<void()> completionHandler)
: plugin(plugin), id(params.id), settings(params.initialSettings), channelDelegate(std::make_unique<WebViewChannelDelegate>(this, plugin->registrar->messenger(), channelName))
{
createWebView(parentWindow, completionHandler);
}
@ -42,6 +43,20 @@ namespace flutter_inappwebview_plugin
webViewController->get_CoreWebView2(webView.put());
}
wil::com_ptr<ICoreWebView2Settings> webView2Settings;
if (SUCCEEDED(webView->get_Settings(&webView2Settings))) {
webView2Settings->put_IsScriptEnabled(settings->javaScriptEnabled);
webView2Settings->put_IsZoomControlEnabled(settings->supportZoom);
webView2Settings->put_IsStatusBarEnabled(true);
wil::com_ptr<ICoreWebView2Settings2> webView2Settings2;
if (SUCCEEDED(webView2Settings->QueryInterface(IID_PPV_ARGS(&webView2Settings2)))) {
if (!settings->userAgent.empty()) {
webView2Settings2->put_UserAgent(ansi_to_wide(settings->userAgent).c_str());
}
}
}
// Resize WebView to fit the bounds of the parent window
RECT bounds;
GetClientRect(parentWindow, &bounds);

View File

@ -8,12 +8,18 @@
#include "../flutter_inappwebview_windows_plugin.h"
#include "../types/navigation_action.h"
#include "../types/url_request.h"
#include "in_app_webview_settings.h"
#include "webview_channel_delegate.h"
namespace flutter_inappwebview_plugin
{
using namespace Microsoft::WRL;
struct InAppWebViewCreationParams {
const std::variant<std::string, int> id;
const std::shared_ptr<InAppWebViewSettings> initialSettings;
};
class InAppWebView
{
public:
@ -26,9 +32,10 @@ namespace flutter_inappwebview_plugin
wil::com_ptr<ICoreWebView2> webView;
const std::unique_ptr<WebViewChannelDelegate> channelDelegate;
std::map<UINT64, std::shared_ptr<NavigationAction>> navigationActions = {};
const std::shared_ptr<InAppWebViewSettings> settings;
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(const FlutterInappwebviewWindowsPlugin* plugin, const InAppWebViewCreationParams& params, const HWND parentWindow, const std::function<void()> completionHandler);
InAppWebView(const FlutterInappwebviewWindowsPlugin* plugin, const InAppWebViewCreationParams& params, const HWND parentWindow, const std::string& channelName, const std::function<void()> completionHandler);
~InAppWebView();
std::optional<std::string> getUrl() const;

View File

@ -0,0 +1,24 @@
#include "../utils/flutter.h"
#include "in_app_webview_settings.h"
namespace flutter_inappwebview_plugin
{
InAppWebViewSettings::InAppWebViewSettings() {};
InAppWebViewSettings::InAppWebViewSettings(const flutter::EncodableMap& encodableMap)
{
useShouldOverrideUrlLoading = get_fl_map_value(encodableMap, "useShouldOverrideUrlLoading", useShouldOverrideUrlLoading);
useOnLoadResource = get_fl_map_value(encodableMap, "useOnLoadResource", useOnLoadResource);
useOnDownloadStart = get_fl_map_value(encodableMap, "useOnDownloadStart", useOnDownloadStart);
userAgent = get_fl_map_value(encodableMap, "userAgent", userAgent);
javaScriptEnabled = get_fl_map_value(encodableMap, "javaScriptEnabled", javaScriptEnabled);
resourceCustomSchemes = get_fl_map_value(encodableMap, "resourceCustomSchemes", resourceCustomSchemes);
transparentBackground = get_fl_map_value(encodableMap, "transparentBackground", transparentBackground);
supportZoom = get_fl_map_value(encodableMap, "supportZoom", supportZoom);
}
InAppWebViewSettings::~InAppWebViewSettings()
{
debugLog("dealloc InAppWebViewSettings");
}
}

View File

@ -0,0 +1,26 @@
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_WEBVIEW_SETTINGS_H_
#define FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_WEBVIEW_SETTINGS_H_
#include <flutter/standard_message_codec.h>
#include <string>
namespace flutter_inappwebview_plugin
{
class InAppWebViewSettings
{
public:
bool useShouldOverrideUrlLoading = false;
bool useOnLoadResource = false;
bool useOnDownloadStart = false;
std::string userAgent;
bool javaScriptEnabled = true;
std::vector<std::string> resourceCustomSchemes;
bool transparentBackground = false;
bool supportZoom = true;
InAppWebViewSettings();
InAppWebViewSettings(const flutter::EncodableMap& encodableMap);
~InAppWebViewSettings();
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_IN_APP_WEBVIEW_SETTINGS_H_

View File

@ -55,7 +55,7 @@ namespace flutter_inappwebview_plugin
}
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("url"), make_fl_value(url)},
{"url", make_fl_value(url)},
});
channel->InvokeMethod("onLoadStart", std::move(arguments));
}
@ -67,7 +67,7 @@ namespace flutter_inappwebview_plugin
}
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("url"), make_fl_value(url)},
{"url", make_fl_value(url)},
});
channel->InvokeMethod("onLoadStop", std::move(arguments));
}
@ -89,8 +89,8 @@ namespace flutter_inappwebview_plugin
}
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("request"), request->toEncodableMap()},
{flutter::EncodableValue("error"), error->toEncodableMap()},
{"request", request->toEncodableMap()},
{"error", error->toEncodableMap()},
});
channel->InvokeMethod("onReceivedError", std::move(arguments));
}
@ -102,8 +102,8 @@ namespace flutter_inappwebview_plugin
}
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("request"), request->toEncodableMap()},
{flutter::EncodableValue("errorResponse"), errorResponse->toEncodableMap()},
{"request", request->toEncodableMap()},
{"errorResponse", errorResponse->toEncodableMap()},
});
channel->InvokeMethod("onReceivedHttpError", std::move(arguments));
}

View File

@ -10,8 +10,8 @@ namespace flutter_inappwebview_plugin
flutter::EncodableMap NavigationAction::toEncodableMap() const
{
return flutter::EncodableMap{
{make_fl_value("request"), request->toEncodableMap()},
{make_fl_value("isForMainFrame"), make_fl_value(isForMainFrame)}
{"request", request->toEncodableMap()},
{"isForMainFrame", make_fl_value(isForMainFrame)}
};
}
}

View File

@ -11,17 +11,17 @@ namespace flutter_inappwebview_plugin
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")),
headers(get_optional_fl_map_value<std::map<std::string, std::string>>(map, "headers")),
body(get_optional_fl_map_value<std::vector<uint8_t>>(map, "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)}
{"url", make_fl_value(url)},
{"method", make_fl_value(method)},
{"headers", make_fl_value(headers)},
{"body", make_fl_value(body)}
};
}
}

View File

@ -15,8 +15,8 @@ namespace flutter_inappwebview_plugin
flutter::EncodableMap WebResourceError::toEncodableMap() const
{
return flutter::EncodableMap{
{make_fl_value("description"), make_fl_value(description)},
{make_fl_value("type"), make_fl_value(type)}
{"description", make_fl_value(description)},
{"type", make_fl_value(type)}
};
}
}

View File

@ -11,17 +11,17 @@ namespace flutter_inappwebview_plugin
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")),
headers(get_optional_fl_map_value<std::map<std::string, std::string>>(map, "headers")),
isForMainFrame(get_optional_fl_map_value<bool>(map, "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)}
{"url", make_fl_value(url)},
{"method", make_fl_value(method)},
{"headers", make_fl_value(headers)},
{"isForMainFrame", make_fl_value(isForMainFrame)}
};
}
}

View File

@ -14,7 +14,7 @@ namespace flutter_inappwebview_plugin
flutter::EncodableMap WebResourceResponse::toEncodableMap() const
{
return flutter::EncodableMap{
{make_fl_value("statusCode"), make_fl_value(statusCode)}
{"statusCode", make_fl_value(statusCode)}
};
}
}

View File

@ -2,8 +2,6 @@
#define FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_
#include <flutter/encodable_value.h>
#include <optional>
#include <string>
#include "util.h"
@ -86,25 +84,66 @@ namespace flutter_inappwebview_plugin
return std::get<T>(map.at(make_fl_value(string)));
}
template<typename T>
template<typename T, typename std::enable_if<((!is_mappish<T>::value && !is_vector<T>::value) ||
std::is_same<T, flutter::EncodableMap>::value || std::is_same<T, flutter::EncodableList>::value), int>::type* = nullptr>
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)
template<typename T>
static inline T get_fl_map_value(const flutter::EncodableMap& map, const char* string, const T& defaultValue)
{
auto optional = get_optional_fl_map_value<T>(map, string);
return !optional.has_value() ? defaultValue : optional.value();
}
template<typename T, typename std::enable_if<(is_mappish<T>::value && !std::is_same<T, flutter::EncodableMap>::value)>::type* = nullptr>
static inline std::optional<T> get_optional_fl_map_value(const flutter::EncodableMap& map, const char* string)
{
using K = typename T::key_type;
using V = typename T::mapped_type;
auto flMap = std::get_if<flutter::EncodableMap>(&map.at(make_fl_value(string)));
if (flMap) {
auto mapValue = std::map<K, T>{};
T mapValue = {};
for (auto itr = flMap->begin(); itr != flMap->end(); itr++) {
mapValue.insert({ std::get<K>(itr->first), std::get<T>(itr->second) });
mapValue.insert({ std::get<K>(itr->first), std::get<V>(itr->second) });
}
return make_pointer_optional<std::map<K, T>>(&mapValue);
return make_pointer_optional<T>(&mapValue);
}
return std::nullopt;
}
template<typename K, typename T>
static inline std::map<K, T> get_fl_map_value(const flutter::EncodableMap& map, const char* string, const std::map<K, T>& defaultValue)
{
auto optional = get_optional_fl_map_value<std::map<K, T>>(map, string);
return !optional.has_value() ? defaultValue : optional.value();
}
template<typename T, typename std::enable_if<(is_vector<T>::value && !std::is_same<T, flutter::EncodableList>::value), bool>::type* = nullptr>
static inline std::optional<T> get_optional_fl_map_value(const flutter::EncodableMap& map, const char* string)
{
using V = typename T::value_type;
auto flList = std::get_if<flutter::EncodableList>(&map.at(make_fl_value(string)));
if (flList) {
T vecValue(flList->size());
for (auto itr = flList->begin(); itr != flList->end(); itr++) {
vecValue.push_back(std::get<V>(*itr));
}
return make_pointer_optional<T>(&vecValue);
}
return std::nullopt;
}
template<typename T>
static inline std::vector<T> get_fl_map_value(const flutter::EncodableMap& map, const char* string, const std::vector<T>& defaultValue)
{
auto optional = get_optional_fl_map_value<std::vector<T>>(map, string);
return !optional.has_value() ? defaultValue : optional.value();
}
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_

View File

@ -12,6 +12,34 @@
namespace flutter_inappwebview_plugin
{
template<typename T = void, typename = void>
struct is_vector_impl : std::false_type { };
template<typename T, typename U = void>
struct is_mappish_impl : std::false_type { };
template<typename T>
struct is_vector_impl<T, std::enable_if_t<
std::is_same<T, typename std::vector<std::string>>::value>
> : std::true_type { };
template<typename T>
struct is_vector_impl<T, std::enable_if_t<
std::is_same<T, typename std::vector<typename std::iterator_traits<T>::value_type>::iterator>::value>
> : std::true_type { };
template<typename T>
struct is_mappish_impl<T, std::void_t<typename T::key_type,
typename T::mapped_type,
decltype(std::declval<T&>()[std::declval<const typename T::key_type&>()])>>
: std::true_type { };
template<typename T>
struct is_mappish : is_mappish_impl<T>::type { };
template<typename T>
struct is_vector : is_vector_impl<T>::type { };
static inline void debugLog(const std::string& msg)
{
#ifndef NDEBUG