windows: added c++ nlohmann.json dependency, added getCopyBackForwardList implementation
This commit is contained in:
parent
914316e6d3
commit
a8e960c4d0
|
@ -783,6 +783,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- Android native WebView ([Official API - WebView.copyBackForwardList](https://developer.android.com/reference/android/webkit/WebView#copyBackForwardList()))
|
||||
///- iOS ([Official API - WKWebView.backForwardList](https://developer.apple.com/documentation/webkit/wkwebview/1414977-backforwardlist))
|
||||
///- MacOS ([Official API - WKWebView.backForwardList](https://developer.apple.com/documentation/webkit/wkwebview/1414977-backforwardlist))
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
Future<WebHistory?> getCopyBackForwardList() {
|
||||
throw UnimplementedError(
|
||||
|
|
|
@ -6,6 +6,7 @@ cmake_minimum_required(VERSION 3.14)
|
|||
|
||||
set(WIL_VERSION "1.0.231216.1")
|
||||
set(WEBVIEW_VERSION "1.0.2210.55")
|
||||
set(NLOHMANN_JSON "3.11.2")
|
||||
|
||||
message(VERBOSE "CMake system version is ${CMAKE_SYSTEM_VERSION} (using SDK ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION})")
|
||||
|
||||
|
@ -31,6 +32,7 @@ add_custom_command(
|
|||
TARGET ${PROJECT_NAME}_DEPENDENCIES_DOWNLOAD PRE_BUILD
|
||||
COMMAND ${NUGET} install Microsoft.Windows.ImplementationLibrary -Version ${WIL_VERSION} -ExcludeVersion -OutputDirectory ${CMAKE_BINARY_DIR}/packages
|
||||
COMMAND ${NUGET} install Microsoft.Web.WebView2 -Version ${WEBVIEW_VERSION} -ExcludeVersion -OutputDirectory ${CMAKE_BINARY_DIR}/packages
|
||||
COMMAND ${NUGET} install nlohmann.json -Version ${NLOHMANN_JSON} -ExcludeVersion -OutputDirectory ${CMAKE_BINARY_DIR}/packages
|
||||
DEPENDS ${NUGET}
|
||||
)
|
||||
|
||||
|
@ -54,6 +56,10 @@ list(APPEND PLUGIN_SOURCES
|
|||
"types/web_resource_request.h"
|
||||
"types/web_resource_response.cpp"
|
||||
"types/web_resource_response.h"
|
||||
"types/web_history.cpp"
|
||||
"types/web_history.h"
|
||||
"types/web_history_item.cpp"
|
||||
"types/web_history_item.h"
|
||||
"custom_platform_view/custom_platform_view.cc"
|
||||
"custom_platform_view/custom_platform_view.h"
|
||||
"custom_platform_view/texture_bridge.cc"
|
||||
|
@ -123,6 +129,7 @@ apply_standard_settings(${PLUGIN_NAME})
|
|||
|
||||
target_link_libraries(${PLUGIN_NAME} PRIVATE ${CMAKE_BINARY_DIR}/packages/Microsoft.Web.WebView2/build/native/Microsoft.Web.WebView2.targets)
|
||||
target_link_libraries(${PLUGIN_NAME} PRIVATE ${CMAKE_BINARY_DIR}/packages/Microsoft.Windows.ImplementationLibrary/build/native/Microsoft.Windows.ImplementationLibrary.targets)
|
||||
target_link_libraries(${PLUGIN_NAME} PRIVATE ${CMAKE_BINARY_DIR}/packages/nlohmann.json/build/native/nlohmann.json.targets)
|
||||
|
||||
# Symbols are hidden by default to reduce the chance of accidental conflicts
|
||||
# between plugins. This should not be removed; any symbols that should be
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <cstring>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <Shlwapi.h>
|
||||
#include <WebView2EnvironmentOptions.h>
|
||||
#include <wil/wrl.h>
|
||||
|
@ -21,11 +22,15 @@ namespace flutter_inappwebview_plugin
|
|||
: plugin(plugin), id(params.id), webViewEnv(std::move(webViewEnv)), webViewController(std::move(webViewController)), webViewCompositionController(std::move(webViewCompositionController)),
|
||||
settings(params.initialSettings)
|
||||
{
|
||||
this->webViewController->get_CoreWebView2(webView.put());
|
||||
auto hrWebView2 = this->webViewController->get_CoreWebView2(webView.put());
|
||||
if (FAILED(hrWebView2)) {
|
||||
std::cerr << "Cannot create CoreWebView2." << std::endl;
|
||||
debugLog(getErrorMessage(hrWebView2));
|
||||
}
|
||||
|
||||
if (this->webViewCompositionController) {
|
||||
if (!createSurface(parentWindow, plugin->inAppWebViewManager->compositor())) {
|
||||
std::cerr << "Cannot create InAppWebView surface\n";
|
||||
std::cerr << "Cannot create InAppWebView surface." << std::endl;
|
||||
}
|
||||
registerSurfaceEventHandlers();
|
||||
}
|
||||
|
@ -37,7 +42,8 @@ namespace flutter_inappwebview_plugin
|
|||
}
|
||||
|
||||
wil::com_ptr<ICoreWebView2Settings> webView2Settings;
|
||||
if (SUCCEEDED(webView->get_Settings(&webView2Settings))) {
|
||||
auto hrWebView2Settings = webView->get_Settings(&webView2Settings);
|
||||
if (SUCCEEDED(hrWebView2Settings)) {
|
||||
webView2Settings->put_IsScriptEnabled(settings->javaScriptEnabled);
|
||||
webView2Settings->put_IsZoomControlEnabled(settings->supportZoom);
|
||||
|
||||
|
@ -48,6 +54,9 @@ namespace flutter_inappwebview_plugin
|
|||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
debugLog(getErrorMessage(hrWebView2Settings));
|
||||
}
|
||||
|
||||
registerEventHandlers();
|
||||
}
|
||||
|
@ -182,7 +191,7 @@ namespace flutter_inappwebview_plugin
|
|||
|
||||
UINT64 navigationId;
|
||||
if (SUCCEEDED(args->get_NavigationId(&navigationId))) {
|
||||
navigationActions.insert({ navigationId, navigationAction }); callShouldOverrideUrlLoading_ =
|
||||
navigationActions.insert({ navigationId, navigationAction });
|
||||
}
|
||||
|
||||
if (callShouldOverrideUrlLoading_ && requestMethod == nullptr) {
|
||||
|
@ -363,16 +372,55 @@ namespace flutter_inappwebview_plugin
|
|||
webView->Reload();
|
||||
}
|
||||
|
||||
void InAppWebView::goBack() const
|
||||
void InAppWebView::goBack()
|
||||
{
|
||||
callShouldOverrideUrlLoading_ = false;
|
||||
webView->GoBack();
|
||||
}
|
||||
|
||||
void InAppWebView::goForward() const
|
||||
void InAppWebView::goForward()
|
||||
{
|
||||
callShouldOverrideUrlLoading_ = false;
|
||||
webView->GoForward();
|
||||
}
|
||||
|
||||
void InAppWebView::getCopyBackForwardList(const std::function<void(std::unique_ptr<WebHistory>)> completionHandler) const
|
||||
{
|
||||
webView->CallDevToolsProtocolMethod(L"Page.getNavigationHistory", L"{}", Callback<ICoreWebView2CallDevToolsProtocolMethodCompletedHandler>(
|
||||
[completionHandler](HRESULT errorCode, LPCWSTR returnObjectAsJson)
|
||||
{
|
||||
if (errorCode == S_OK) {
|
||||
auto historyJson = nlohmann::json::parse(wide_to_ansi(returnObjectAsJson));
|
||||
|
||||
int64_t currentIndex = historyJson.at("currentIndex").is_number_unsigned() ? historyJson.at("currentIndex").get<int64_t>() : 0;
|
||||
auto entries = historyJson.at("entries").is_array() ? historyJson.at("entries").get<std::vector<nlohmann::json>>() : std::vector<nlohmann::json>{};
|
||||
|
||||
std::vector<std::shared_ptr<WebHistoryItem>> webHistoryItems;
|
||||
webHistoryItems.reserve(entries.size());
|
||||
int64_t i = 0;
|
||||
for (auto const& entry : entries) {
|
||||
int64_t offset = i - currentIndex;
|
||||
webHistoryItems.push_back(std::make_shared<WebHistoryItem>(
|
||||
i,
|
||||
offset,
|
||||
entry.at("userTypedURL").is_string() ? entry.at("userTypedURL").get<std::string>() : std::optional<std::string>{},
|
||||
entry.at("title").is_string() ? entry.at("title").get<std::string>() : std::optional<std::string>{},
|
||||
entry.at("url").is_string() ? entry.at("url").get<std::string>() : std::optional<std::string>{}
|
||||
));
|
||||
i++;
|
||||
}
|
||||
|
||||
completionHandler(std::make_unique<WebHistory>(currentIndex, webHistoryItems));
|
||||
}
|
||||
else {
|
||||
debugLog(getErrorMessage(errorCode));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
).Get());
|
||||
}
|
||||
|
||||
void InAppWebView::evaluateJavascript(const std::string& source, std::function<void(std::string)> completionHanlder) const
|
||||
{
|
||||
webView->ExecuteScript(ansi_to_wide(source).c_str(),
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "../flutter_inappwebview_windows_plugin.h"
|
||||
#include "../types/navigation_action.h"
|
||||
#include "../types/url_request.h"
|
||||
#include "../types/web_history.h"
|
||||
#include "in_app_webview_settings.h"
|
||||
#include "webview_channel_delegate.h"
|
||||
|
||||
|
@ -130,9 +131,10 @@ namespace flutter_inappwebview_plugin
|
|||
std::optional<std::string> getTitle() const;
|
||||
void loadUrl(const URLRequest& urlRequest) const;
|
||||
void reload() const;
|
||||
void goBack() const;
|
||||
void goForward() const;
|
||||
void goBack();
|
||||
void goForward();
|
||||
void evaluateJavascript(const std::string& source, std::function<void(std::string)> completionHanlder) const;
|
||||
void getCopyBackForwardList(const std::function<void(std::unique_ptr<WebHistory>)> completionHandler) const;
|
||||
|
||||
static bool isSslError(const COREWEBVIEW2_WEB_ERROR_STATUS& webErrorStatus);
|
||||
private:
|
||||
|
|
|
@ -46,19 +46,19 @@ namespace flutter_inappwebview_plugin
|
|||
else if (method_call.method_name().compare("loadUrl") == 0) {
|
||||
auto urlRequest = std::make_unique<URLRequest>(get_fl_map_value<flutter::EncodableMap>(arguments, "urlRequest"));
|
||||
webView->loadUrl(*urlRequest);
|
||||
result->Success(make_fl_value(true));
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("reload") == 0) {
|
||||
webView->reload();
|
||||
result->Success(make_fl_value(true));
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("goBack") == 0) {
|
||||
webView->goBack();
|
||||
result->Success(make_fl_value(true));
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("goForward") == 0) {
|
||||
webView->goForward();
|
||||
result->Success(make_fl_value(true));
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("evaluateJavascript") == 0) {
|
||||
auto result_ = std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result));
|
||||
|
@ -66,21 +66,28 @@ namespace flutter_inappwebview_plugin
|
|||
auto source = get_fl_map_value<std::string>(arguments, "source");
|
||||
webView->evaluateJavascript(source, [result_ = std::move(result_)](const std::string& value)
|
||||
{
|
||||
result_->Success(make_fl_value(value));
|
||||
result_->Success(value);
|
||||
});
|
||||
}
|
||||
else if (method_call.method_name().compare("getCopyBackForwardList") == 0) {
|
||||
auto result_ = std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result));
|
||||
webView->getCopyBackForwardList([result_ = std::move(result_)](const std::unique_ptr<WebHistory> value)
|
||||
{
|
||||
result_->Success(value->toEncodableMap());
|
||||
});
|
||||
}
|
||||
// for inAppBrowser
|
||||
else if (webView->inAppBrowser && method_call.method_name().compare("show") == 0) {
|
||||
webView->inAppBrowser->show();
|
||||
result->Success(make_fl_value(true));
|
||||
result->Success(true);
|
||||
}
|
||||
else if (webView->inAppBrowser && method_call.method_name().compare("hide") == 0) {
|
||||
webView->inAppBrowser->hide();
|
||||
result->Success(make_fl_value(true));
|
||||
result->Success(true);
|
||||
}
|
||||
else if (webView->inAppBrowser && method_call.method_name().compare("close") == 0) {
|
||||
webView->inAppBrowser->close();
|
||||
result->Success(make_fl_value(true));
|
||||
result->Success(true);
|
||||
}
|
||||
else {
|
||||
result->NotImplemented();
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#include "../utils/util.h"
|
||||
#include "web_history.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
WebHistory::WebHistory(const std::optional<int64_t> currentIndex, const std::optional<std::vector<std::shared_ptr<WebHistoryItem>>>& list)
|
||||
: currentIndex(currentIndex), list(list)
|
||||
{}
|
||||
|
||||
WebHistory::WebHistory(const flutter::EncodableMap& map)
|
||||
: currentIndex(get_optional_fl_map_value<int64_t>(map, "currentIndex")),
|
||||
list(functional_map(get_optional_fl_map_value<flutter::EncodableList>(map, "list"), [](const flutter::EncodableValue& m) { return std::make_shared<WebHistoryItem>(std::get<flutter::EncodableMap>(m)); }))
|
||||
{}
|
||||
|
||||
flutter::EncodableMap WebHistory::toEncodableMap() const
|
||||
{
|
||||
return flutter::EncodableMap{
|
||||
{"currentIndex", make_fl_value(currentIndex)},
|
||||
{"list", make_fl_value(functional_map(list, [](const std::shared_ptr<WebHistoryItem>& item) { return item->toEncodableMap(); }))}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_HISTORY_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_HISTORY_H_
|
||||
|
||||
#include <flutter/standard_method_codec.h>
|
||||
#include <optional>
|
||||
|
||||
#include "../utils/flutter.h"
|
||||
#include "web_history_item.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
class WebHistory
|
||||
{
|
||||
public:
|
||||
const std::optional<int64_t> currentIndex;
|
||||
const std::optional<std::vector<std::shared_ptr<WebHistoryItem>>> list;
|
||||
|
||||
WebHistory(const std::optional<int64_t> currentIndex, const std::optional<std::vector<std::shared_ptr<WebHistoryItem>>>& list);
|
||||
WebHistory(const flutter::EncodableMap& map);
|
||||
~WebHistory() = default;
|
||||
|
||||
flutter::EncodableMap toEncodableMap() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_HISTORY_H_
|
|
@ -0,0 +1,29 @@
|
|||
#include "web_history_item.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
WebHistoryItem::WebHistoryItem(const std::optional<int64_t>& index, const std::optional<int64_t>& offset,
|
||||
const std::optional<std::string>& originalUrl, const std::optional<std::string>& title,
|
||||
const std::optional<std::string>& url)
|
||||
: index(index), offset(offset), originalUrl(originalUrl), title(title), url(url)
|
||||
{}
|
||||
|
||||
WebHistoryItem::WebHistoryItem(const flutter::EncodableMap& map)
|
||||
: index(get_optional_fl_map_value<int64_t>(map, "index")),
|
||||
offset(get_optional_fl_map_value<int64_t>(map, "offset")),
|
||||
originalUrl(get_optional_fl_map_value<std::string>(map, "originalUrl")),
|
||||
title(get_optional_fl_map_value<std::string>(map, "title")),
|
||||
url(get_optional_fl_map_value<std::string>(map, "url"))
|
||||
{}
|
||||
|
||||
flutter::EncodableMap WebHistoryItem::toEncodableMap() const
|
||||
{
|
||||
return flutter::EncodableMap{
|
||||
{"index", make_fl_value(index)},
|
||||
{"offset", make_fl_value(offset)},
|
||||
{"originalUrl", make_fl_value(originalUrl)},
|
||||
{"title", make_fl_value(title)},
|
||||
{"url", make_fl_value(url)}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_HISTORY_ITEM_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_HISTORY_ITEM_H_
|
||||
|
||||
#include <flutter/standard_method_codec.h>
|
||||
#include <optional>
|
||||
|
||||
#include "../utils/flutter.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
class WebHistoryItem
|
||||
{
|
||||
public:
|
||||
const std::optional<int64_t> index;
|
||||
const std::optional<int64_t> offset;
|
||||
const std::optional<std::string> originalUrl;
|
||||
const std::optional<std::string> title;
|
||||
const std::optional<std::string> url;
|
||||
|
||||
WebHistoryItem(const std::optional<int64_t>& index, const std::optional<int64_t>& offset,
|
||||
const std::optional<std::string>& originalUrl, const std::optional<std::string>& title,
|
||||
const std::optional<std::string>& url);
|
||||
WebHistoryItem(const flutter::EncodableMap& map);
|
||||
~WebHistoryItem() = default;
|
||||
|
||||
flutter::EncodableMap toEncodableMap() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_HISTORY_ITEM_H_
|
|
@ -87,6 +87,39 @@ namespace flutter_inappwebview_plugin
|
|||
auto itr = map.find(key);
|
||||
return itr != map.end() ? itr->second : nullptr;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Func>
|
||||
static inline auto functional_map(Iterator begin, Iterator end, Func&& func) ->
|
||||
std::vector<decltype(func(std::declval<typename Iterator::value_type>()))>
|
||||
{
|
||||
using value_type = decltype(func(std::declval<typename Iterator::value_type>()));
|
||||
|
||||
std::vector<value_type> out_vector;
|
||||
out_vector.reserve(std::distance(begin, end));
|
||||
|
||||
std::transform(begin, end, std::back_inserter(out_vector),
|
||||
std::forward<Func>(func));
|
||||
|
||||
return out_vector;
|
||||
}
|
||||
|
||||
template <typename T, typename Func>
|
||||
static inline auto functional_map(const T& iterable, Func&& func) ->
|
||||
std::vector<decltype(func(std::declval<typename T::value_type>()))>
|
||||
{
|
||||
return functional_map(std::begin(iterable), std::end(iterable),
|
||||
std::forward<Func>(func));
|
||||
}
|
||||
|
||||
template <typename T, typename Func>
|
||||
static inline auto functional_map(const std::optional<T>& iterable, Func&& func) ->
|
||||
std::vector<decltype(func(std::declval<typename T::value_type>()))>
|
||||
{
|
||||
if (!iterable.has_value()) {
|
||||
return {};
|
||||
}
|
||||
return functional_map(iterable.value(), std::forward<Func>(func));
|
||||
}
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_
|
Loading…
Reference in New Issue