added implementation for callback result, impl for shouldOverrideUrlLoading
This commit is contained in:
parent
81b72b3213
commit
43aa01d944
|
@ -57,8 +57,11 @@ list(APPEND PLUGIN_SOURCES
|
|||
"utils/util.h"
|
||||
"types/channel_delegate.cpp"
|
||||
"types/channel_delegate.h"
|
||||
"types/base_callback_result.h"
|
||||
"types/url_request.cpp"
|
||||
"types/url_request.h"
|
||||
"types/navigation_action.cpp"
|
||||
"types/navigation_action.h"
|
||||
"in_app_webview/in_app_webview.cpp"
|
||||
"in_app_webview/in_app_webview.h"
|
||||
"in_app_webview/webview_channel_delegate.cpp"
|
||||
|
|
|
@ -1,17 +1,7 @@
|
|||
#include "flutter_inappwebview_windows_plugin.h"
|
||||
|
||||
// This must be included before many other Windows headers.
|
||||
#include <windows.h>
|
||||
|
||||
// For getPlatformVersion; remove unless needed for your plugin implementation.
|
||||
#include <VersionHelpers.h>
|
||||
|
||||
#include <flutter/method_channel.h>
|
||||
#include <flutter/plugin_registrar_windows.h>
|
||||
#include <flutter/standard_method_codec.h>
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
|
@ -30,6 +20,6 @@ namespace flutter_inappwebview_plugin
|
|||
|
||||
FlutterInappwebviewWindowsPlugin::~FlutterInappwebviewWindowsPlugin()
|
||||
{
|
||||
inAppBrowserManager.release();
|
||||
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
#include <wil/wrl.h>
|
||||
#include <wil/com.h>
|
||||
#include "../utils/strconv.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
#include <WebView2.h>
|
||||
#include <WebView2EnvironmentOptions.h>
|
||||
|
@ -229,7 +230,7 @@ namespace flutter_inappwebview_plugin
|
|||
|
||||
InAppBrowser::~InAppBrowser()
|
||||
{
|
||||
std::cout << "dealloc InAppBrowser\n";
|
||||
debugLog("dealloc InAppBrowser");
|
||||
webView.reset();
|
||||
SetWindowLongPtr(m_hWnd, GWLP_USERDATA, 0);
|
||||
plugin = nullptr;
|
||||
|
|
|
@ -35,6 +35,6 @@ namespace flutter_inappwebview_plugin
|
|||
|
||||
InAppBrowserChannelDelegate::~InAppBrowserChannelDelegate()
|
||||
{
|
||||
std::cout << "dealloc InAppBrowserChannelDelegate\n";
|
||||
debugLog("dealloc InAppBrowserChannelDelegate");
|
||||
}
|
||||
}
|
|
@ -45,11 +45,7 @@ namespace flutter_inappwebview_plugin
|
|||
|
||||
InAppBrowserManager::~InAppBrowserManager()
|
||||
{
|
||||
std::cout << "dealloc InAppBrowserManager\n";
|
||||
for (std::map<std::string, std::unique_ptr<InAppBrowser>>::iterator itr = browsers.begin(); itr != browsers.end(); itr++)
|
||||
{
|
||||
browsers.erase(itr->first);
|
||||
}
|
||||
debugLog("dealloc InAppBrowserManager");
|
||||
browsers.clear();
|
||||
plugin = nullptr;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
#pragma comment(lib, "Shlwapi.lib")
|
||||
|
||||
#include "in_app_webview.h"
|
||||
#include <WebView2EnvironmentOptions.h>
|
||||
#include <wil/wrl.h>
|
||||
#include <Shlwapi.h>
|
||||
#include "../utils/strconv.h"
|
||||
#include "../utils/util.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
|
@ -24,6 +28,7 @@ namespace flutter_inappwebview_plugin
|
|||
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 {
|
||||
|
@ -56,13 +61,74 @@ namespace flutter_inappwebview_plugin
|
|||
webView->add_NavigationStarting(
|
||||
Callback<ICoreWebView2NavigationStartingEventHandler>(
|
||||
[this](ICoreWebView2* sender, ICoreWebView2NavigationStartingEventArgs* args) {
|
||||
if (channelDelegate) {
|
||||
LPWSTR uri = nullptr;
|
||||
std::optional<std::string> url = SUCCEEDED(args->get_Uri(&uri)) ? wide_to_utf8(std::wstring(uri)) : std::optional<std::string>{};
|
||||
channelDelegate->onLoadStart(url);
|
||||
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(std::wstring(uri.get())) : std::optional<std::string>{};
|
||||
|
||||
wil::unique_cotaskmem_string method = 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;
|
||||
|
||||
if (SUCCEEDED(iterator->GetCurrentHeader(&name, &value))) {
|
||||
headers->insert({ wide_to_utf8(std::wstring(name.get())), wide_to_utf8(std::wstring(value.get())) });
|
||||
}
|
||||
|
||||
BOOL hasNext = FALSE;
|
||||
iterator->MoveNext(&hasNext);
|
||||
}
|
||||
|
||||
requestHeaders->GetHeader(L"Flutter-InAppWebView-Request-Method", &method);
|
||||
requestHeaders->RemoveHeader(L"Flutter-InAppWebView-Request-Method");
|
||||
}
|
||||
|
||||
args->put_Cancel(false);
|
||||
if (callShouldOverrideUrlLoading && method == nullptr) {
|
||||
// for some reason, we can't cancel and load an URL with other HTTP methods other than GET,
|
||||
// so ignore the shouldOverrideUrlLoading event.
|
||||
|
||||
auto urlRequest = std::make_shared<URLRequest>(url, std::nullopt, headers, std::nullopt);
|
||||
auto navigationAction = std::make_unique<NavigationAction>(
|
||||
urlRequest,
|
||||
true
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -71,10 +137,19 @@ namespace flutter_inappwebview_plugin
|
|||
webView->add_NavigationCompleted(
|
||||
Callback<ICoreWebView2NavigationCompletedEventHandler>(
|
||||
[this](ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args) {
|
||||
COREWEBVIEW2_WEB_ERROR_STATUS web_error_status;
|
||||
args->get_WebErrorStatus(&web_error_status);
|
||||
debugLog("WebErrorStatus " + std::to_string(web_error_status) + "\n");
|
||||
|
||||
BOOL isSuccess;
|
||||
args->get_IsSuccess(&isSuccess);
|
||||
|
||||
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>{};
|
||||
channelDelegate->onLoadStop(url);
|
||||
if (isSuccess) {
|
||||
channelDelegate->onLoadStop(url);
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -89,20 +164,53 @@ namespace flutter_inappwebview_plugin
|
|||
|
||||
void InAppWebView::loadUrl(const URLRequest urlRequest) const
|
||||
{
|
||||
if (!webView) {
|
||||
if (!webView || !urlRequest.url.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto url = urlRequest.url.value();
|
||||
std::wstring stemp = ansi_to_wide(url);
|
||||
std::wstring url = ansi_to_wide(urlRequest.url.value());
|
||||
|
||||
// Schedule an async task to navigate to Bing
|
||||
webView->Navigate(stemp.c_str());
|
||||
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 (urlRequest.method.has_value() && urlRequest.method.value().compare("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());
|
||||
}
|
||||
}
|
||||
|
||||
InAppWebView::~InAppWebView()
|
||||
{
|
||||
std::cout << "dealloc InAppWebView\n";
|
||||
debugLog("dealloc InAppWebView");
|
||||
if (webView) {
|
||||
webView->Stop();
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace flutter_inappwebview_plugin
|
|||
|
||||
FlutterInappwebviewWindowsBasePlugin* plugin;
|
||||
std::variant<std::string, int> id;
|
||||
wil::com_ptr<ICoreWebView2Environment> webViewEnv;
|
||||
wil::com_ptr<ICoreWebView2Controller> webViewController;
|
||||
wil::com_ptr<ICoreWebView2> webView;
|
||||
std::unique_ptr<WebViewChannelDelegate> channelDelegate;
|
||||
|
@ -32,6 +33,7 @@ namespace flutter_inappwebview_plugin
|
|||
void loadUrl(const URLRequest urlRequest) const;
|
||||
|
||||
private:
|
||||
bool callShouldOverrideUrlLoading = true;
|
||||
void createWebView(const HWND parentWindow, const std::function<void()> completionHandler);
|
||||
void InAppWebView::registerEventHandlers();
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "../utils/util.h"
|
||||
#include "../utils/strconv.h"
|
||||
#include "../types/base_callback_result.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
|
@ -18,6 +19,16 @@ namespace flutter_inappwebview_plugin
|
|||
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -27,8 +38,12 @@ namespace flutter_inappwebview_plugin
|
|||
}
|
||||
|
||||
if (method_call.method_name().compare("getUrl") == 0) {
|
||||
std::optional<std::string> url = webView->getUrl();
|
||||
result->Success(url.has_value() ? flutter::EncodableValue(url.value()) : flutter::EncodableValue());
|
||||
result->Success(optional_to_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(flutter::EncodableValue(true));
|
||||
}
|
||||
else {
|
||||
result->NotImplemented();
|
||||
|
@ -42,7 +57,7 @@ namespace flutter_inappwebview_plugin
|
|||
}
|
||||
|
||||
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap {
|
||||
{flutter::EncodableValue("url"), url.has_value() ? flutter::EncodableValue(url.value()) : flutter::EncodableValue()},
|
||||
{flutter::EncodableValue("url"), optional_to_fl_value(url)},
|
||||
});
|
||||
channel->InvokeMethod("onLoadStart", std::move(arguments));
|
||||
}
|
||||
|
@ -54,14 +69,24 @@ namespace flutter_inappwebview_plugin
|
|||
}
|
||||
|
||||
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
|
||||
{flutter::EncodableValue("url"), url.has_value() ? flutter::EncodableValue(url.value()) : flutter::EncodableValue()},
|
||||
{flutter::EncodableValue("url"), optional_to_fl_value(url)},
|
||||
});
|
||||
channel->InvokeMethod("onLoadStop", std::move(arguments));
|
||||
}
|
||||
|
||||
void WebViewChannelDelegate::shouldOverrideUrlLoading(std::shared_ptr<NavigationAction> navigationAction, std::unique_ptr<ShouldOverrideUrlLoadingCallback> callback)
|
||||
{
|
||||
if (!channel) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto arguments = std::make_unique<flutter::EncodableValue>(navigationAction->toEncodableMap());
|
||||
channel->InvokeMethod("shouldOverrideUrlLoading", std::move(arguments), std::move(callback));
|
||||
}
|
||||
|
||||
WebViewChannelDelegate::~WebViewChannelDelegate()
|
||||
{
|
||||
std::cout << "dealloc WebViewChannelDelegate\n";
|
||||
debugLog("dealloc WebViewChannelDelegate");
|
||||
webView = nullptr;
|
||||
}
|
||||
}
|
|
@ -5,16 +5,26 @@
|
|||
#include <flutter/standard_message_codec.h>
|
||||
|
||||
#include "../types/channel_delegate.h"
|
||||
#include "../types/base_callback_result.h"
|
||||
#include "../types/navigation_action.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
class InAppWebView;
|
||||
|
||||
enum NavigationActionPolicy {cancel = 0, allow = 1};
|
||||
|
||||
class WebViewChannelDelegate : public ChannelDelegate
|
||||
{
|
||||
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();
|
||||
|
@ -25,6 +35,7 @@ namespace flutter_inappwebview_plugin
|
|||
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
#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 <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; };
|
||||
|
||||
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_
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_CHANNEL_DELEGATE_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_CHANNEL_DELEGATE_H_
|
||||
|
||||
#include <flutter/method_channel.h>
|
||||
|
||||
|
@ -18,10 +19,12 @@ namespace flutter_inappwebview_plugin
|
|||
flutter::BinaryMessenger* messenger;
|
||||
|
||||
ChannelDelegate(flutter::BinaryMessenger* messenger, const std::string& name);
|
||||
~ChannelDelegate();
|
||||
virtual ~ChannelDelegate();
|
||||
|
||||
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_
|
|
@ -0,0 +1,20 @@
|
|||
#include "navigation_action.h"
|
||||
|
||||
#include "../utils/util.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
NavigationAction::NavigationAction(std::shared_ptr<URLRequest> request, 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)}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_NAVIGATION_ACTION_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_NAVIGATION_ACTION_H_
|
||||
|
||||
#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;
|
||||
|
||||
NavigationAction(std::shared_ptr<URLRequest> request, bool isForMainFrame);
|
||||
~NavigationAction() = default;
|
||||
flutter::EncodableMap toEncodableMap();
|
||||
};
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_NAVIGATION_ACTION_H_
|
|
@ -4,10 +4,28 @@
|
|||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
URLRequest::URLRequest(const flutter::EncodableMap map)
|
||||
: url(get_optional_flutter_value<std::string>(map, "url")),
|
||||
method(get_optional_flutter_value<std::string>(map, "method"))
|
||||
URLRequest::URLRequest(std::optional<std::string> url, std::optional<std::string> method, std::optional<std::map<std::string, std::string>> headers, 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(map, "headers")),
|
||||
body(get_optional_fl_map_value<std::vector<uint8_t>>(map, "body"))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
flutter::EncodableMap URLRequest::toEncodableMap()
|
||||
{
|
||||
return flutter::EncodableMap{
|
||||
{flutter::EncodableValue("url"), optional_to_fl_value(url)},
|
||||
{flutter::EncodableValue("method"), optional_to_fl_value(method)},
|
||||
{flutter::EncodableValue("headers"), optional_to_fl_value(headers)},
|
||||
{flutter::EncodableValue("body"), optional_to_fl_value(body)}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -12,8 +12,13 @@ namespace flutter_inappwebview_plugin
|
|||
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(std::optional<std::string> url, std::optional<std::string> method, std::optional<std::map<std::string, std::string>> headers, std::optional<std::vector<uint8_t>> body);
|
||||
URLRequest(const flutter::EncodableMap map);
|
||||
~URLRequest() = default;
|
||||
flutter::EncodableMap toEncodableMap();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,21 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <algorithm>
|
||||
#include "strconv.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
static inline void debugLog(const std::string& msg) {
|
||||
#ifndef NDEBUG
|
||||
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)
|
||||
{
|
||||
|
@ -13,17 +23,50 @@ namespace flutter_inappwebview_plugin
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
static inline T get_flutter_value(const flutter::EncodableMap map, const char* string)
|
||||
static inline T get_fl_map_value(const flutter::EncodableMap map, const char* string)
|
||||
{
|
||||
return std::get<T>(map.at(flutter::EncodableValue(string)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline std::optional<T> get_optional_flutter_value(const flutter::EncodableMap map, const char* string)
|
||||
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(flutter::EncodableValue(string))));
|
||||
}
|
||||
|
||||
static inline std::optional<std::map<std::string, std::string>> get_optional_fl_map_value(const flutter::EncodableMap map, const char* string)
|
||||
{
|
||||
auto mapValue = std::map<std::string, std::string>{};
|
||||
auto flMap = std::get_if<flutter::EncodableMap>(&map.at(flutter::EncodableValue(string)));
|
||||
if (flMap) {
|
||||
for (auto itr = flMap->begin(); itr != flMap->end(); itr++)
|
||||
{
|
||||
mapValue.insert({ std::get<std::string>(itr->first), std::get<std::string>(itr->second) });
|
||||
}
|
||||
}
|
||||
return make_pointer_optional<std::map<std::string, std::string>>(&mapValue);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline flutter::EncodableValue optional_to_fl_value(const std::optional<T> optional)
|
||||
{
|
||||
return optional.has_value() ? flutter::EncodableValue(optional.value()) : flutter::EncodableValue();
|
||||
}
|
||||
|
||||
static inline flutter::EncodableValue optional_to_fl_value(const std::optional<std::map<std::string, std::string>> optional)
|
||||
{
|
||||
if (!optional.has_value()) {
|
||||
return flutter::EncodableValue();
|
||||
}
|
||||
auto& mapValue = optional.value();
|
||||
auto encodableMap = flutter::EncodableMap{};
|
||||
for (auto const& [key, val] : mapValue)
|
||||
{
|
||||
encodableMap.insert({ flutter::EncodableValue(key), flutter::EncodableValue(val) });
|
||||
}
|
||||
return encodableMap;
|
||||
}
|
||||
|
||||
static inline std::string variant_to_string(std::variant<std::string, int> var)
|
||||
{
|
||||
return std::visit([](auto&& arg) {
|
||||
|
|
Loading…
Reference in New Issue