windows: implemented some other methods and events, initial implementation work for UserScripts and JavaScript handlers
This commit is contained in:
parent
a8e960c4d0
commit
9a5dae03ba
@ -899,6 +899,7 @@ abstract class PlatformInAppBrowserEvents {
|
||||
///- Android native WebView ([Official API - WebViewClient.doUpdateVisitedHistory](https://developer.android.com/reference/android/webkit/WebViewClient#doUpdateVisitedHistory(android.webkit.WebView,%20java.lang.String,%20boolean)))
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows ([Official API - IWebView2WebView.add_HistoryChanged](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#add_historychanged))
|
||||
void onUpdateVisitedHistory(WebUri? url, bool? isReload) {}
|
||||
|
||||
///Use [onPrintRequest] instead
|
||||
|
@ -377,6 +377,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
||||
///- Android native WebView ([Official API - WebView.canGoBack](https://developer.android.com/reference/android/webkit/WebView#canGoBack()))
|
||||
///- iOS ([Official API - WKWebView.canGoBack](https://developer.apple.com/documentation/webkit/wkwebview/1414966-cangoback))
|
||||
///- MacOS ([Official API - WKWebView.canGoBack](https://developer.apple.com/documentation/webkit/wkwebview/1414966-cangoback))
|
||||
///- Windows ([Official API - IWebView2WebView.get_CanGoBack](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#get_cangoback))
|
||||
///{@endtemplate}
|
||||
Future<bool> canGoBack() {
|
||||
throw UnimplementedError(
|
||||
@ -407,6 +408,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
||||
///- Android native WebView ([Official API - WebView.canGoForward](https://developer.android.com/reference/android/webkit/WebView#canGoForward()))
|
||||
///- iOS ([Official API - WKWebView.canGoForward](https://developer.apple.com/documentation/webkit/wkwebview/1414962-cangoforward))
|
||||
///- MacOS ([Official API - WKWebView.canGoForward](https://developer.apple.com/documentation/webkit/wkwebview/1414962-cangoforward))
|
||||
///- Windows ([Official API - IWebView2WebView.get_CanGoForward](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#get_cangoforward))
|
||||
///{@endtemplate}
|
||||
Future<bool> canGoForward() {
|
||||
throw UnimplementedError(
|
||||
@ -423,6 +425,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
||||
///- iOS ([Official API - WKWebView.go](https://developer.apple.com/documentation/webkit/wkwebview/1414991-go))
|
||||
///- MacOS ([Official API - WKWebView.go](https://developer.apple.com/documentation/webkit/wkwebview/1414991-go))
|
||||
///- Web ([Official API - History.go](https://developer.mozilla.org/en-US/docs/Web/API/History/go))
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
Future<void> goBackOrForward({required int steps}) {
|
||||
throw UnimplementedError(
|
||||
@ -436,6 +439,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
||||
///- Android native WebView ([Official API - WebView.canGoBackOrForward](https://developer.android.com/reference/android/webkit/WebView#canGoBackOrForward(int)))
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
Future<bool> canGoBackOrForward({required int steps}) {
|
||||
throw UnimplementedError(
|
||||
@ -452,6 +456,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Web
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
Future<void> goTo({required WebHistoryItem historyItem}) {
|
||||
throw UnimplementedError('goTo is not implemented on the current platform');
|
||||
@ -465,6 +470,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Web
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
Future<bool> isLoading() {
|
||||
throw UnimplementedError(
|
||||
@ -481,6 +487,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
||||
///- iOS ([Official API - WKWebView.stopLoading](https://developer.apple.com/documentation/webkit/wkwebview/1414981-stoploading))
|
||||
///- MacOS ([Official API - WKWebView.stopLoading](https://developer.apple.com/documentation/webkit/wkwebview/1414981-stoploading))
|
||||
///- Web ([Official API - Window.stop](https://developer.mozilla.org/en-US/docs/Web/API/Window/stop))
|
||||
///- Windows ([Official API - IWebView2WebView.Stop](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#stop))
|
||||
///{@endtemplate}
|
||||
Future<void> stopLoading() {
|
||||
throw UnimplementedError(
|
||||
@ -558,6 +565,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Web
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
Future<dynamic> injectJavascriptFileFromAsset(
|
||||
{required String assetFilePath}) {
|
||||
|
@ -38,6 +38,7 @@ class PlatformWebViewCreationParams<T> {
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Web
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
final void Function(T controller)? onWebViewCreated;
|
||||
|
||||
@ -54,6 +55,7 @@ class PlatformWebViewCreationParams<T> {
|
||||
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview))
|
||||
///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview))
|
||||
///- Web
|
||||
///- Windows ([Official API - IWebView2WebView.add_NavigationStarting](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/iwebview2webview?view=webview2-0.8.355#add_navigationstarting))
|
||||
///{@endtemplate}
|
||||
final void Function(T controller, WebUri? url)? onLoadStart;
|
||||
|
||||
@ -68,6 +70,7 @@ class PlatformWebViewCreationParams<T> {
|
||||
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview))
|
||||
///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview))
|
||||
///- Web ([Official API - Window.onload](https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event))
|
||||
///- Windows ([Official API - IWebView2WebView.add_NavigationCompleted](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/iwebview2webview?view=webview2-0.8.355#add_navigationcompleted))
|
||||
///{@endtemplate}
|
||||
final void Function(T controller, WebUri? url)? onLoadStop;
|
||||
|
||||
@ -83,6 +86,7 @@ class PlatformWebViewCreationParams<T> {
|
||||
///- Android native WebView ([Official API - WebViewClient.onReceivedError](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedError(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20android.webkit.WebResourceError)))
|
||||
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455623-webview))
|
||||
///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455623-webview))
|
||||
///- Windows ([Official API - IWebView2WebView.add_NavigationCompleted](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/iwebview2webview?view=webview2-0.8.355#add_navigationcompleted))
|
||||
///{@endtemplate}
|
||||
final void Function(
|
||||
T controller, WebResourceRequest request, WebResourceError error)?
|
||||
@ -107,6 +111,7 @@ class PlatformWebViewCreationParams<T> {
|
||||
///- Android native WebView ([Official API - WebViewClient.onReceivedHttpError](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpError(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20android.webkit.WebResourceResponse)))
|
||||
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview))
|
||||
///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview))
|
||||
///- Windows ([Official API - IWebView2WebView.add_NavigationCompleted](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/iwebview2webview?view=webview2-0.8.355#add_navigationcompleted))
|
||||
///{@endtemplate}
|
||||
final void Function(T controller, WebResourceRequest request,
|
||||
WebResourceResponse errorResponse)? onReceivedHttpError;
|
||||
@ -499,6 +504,7 @@ class PlatformWebViewCreationParams<T> {
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Web
|
||||
///- Windows ([Official API - IWebView2WebView.add_HistoryChanged](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#add_historychanged))
|
||||
///{@endtemplate}
|
||||
final void Function(T controller, WebUri? url, bool? isReload)?
|
||||
onUpdateVisitedHistory;
|
||||
@ -593,6 +599,7 @@ class PlatformWebViewCreationParams<T> {
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Web
|
||||
///- Windows ([Official API - IWebView2WebView.add_DocumentTitleChanged](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#add_documenttitlechanged))
|
||||
///{@endtemplate}
|
||||
final void Function(T controller, String? title)? onTitleChanged;
|
||||
|
||||
|
@ -54,7 +54,8 @@ class NavigationAction_ {
|
||||
available: "21",
|
||||
apiName: "WebResourceRequest.isRedirect",
|
||||
apiUrl:
|
||||
"https://developer.android.com/reference/android/webkit/WebResourceRequest#isRedirect()")
|
||||
"https://developer.android.com/reference/android/webkit/WebResourceRequest#isRedirect()"),
|
||||
WindowsPlatform()
|
||||
])
|
||||
bool? isRedirect;
|
||||
|
||||
@ -62,7 +63,7 @@ class NavigationAction_ {
|
||||
@Deprecated("Use navigationType instead")
|
||||
IOSWKNavigationType_? iosWKNavigationType;
|
||||
|
||||
///The type of action triggering the navigation.ì
|
||||
///The type of action triggering the navigation.
|
||||
@SupportedPlatforms(platforms: [
|
||||
IOSPlatform(
|
||||
apiName: "WKNavigationAction.navigationType",
|
||||
@ -71,7 +72,8 @@ class NavigationAction_ {
|
||||
MacOSPlatform(
|
||||
apiName: "WKNavigationAction.navigationType",
|
||||
apiUrl:
|
||||
"https://developer.apple.com/documentation/webkit/wknavigationaction/1401914-navigationtype")
|
||||
"https://developer.apple.com/documentation/webkit/wknavigationaction/1401914-navigationtype"),
|
||||
WindowsPlatform()
|
||||
])
|
||||
NavigationType_? navigationType;
|
||||
|
||||
|
@ -52,13 +52,15 @@ class NavigationAction {
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView 21+ ([Official API - WebResourceRequest.isRedirect](https://developer.android.com/reference/android/webkit/WebResourceRequest#isRedirect()))
|
||||
///- Windows
|
||||
bool? isRedirect;
|
||||
|
||||
///The type of action triggering the navigation.ì
|
||||
///The type of action triggering the navigation.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS ([Official API - WKNavigationAction.navigationType](https://developer.apple.com/documentation/webkit/wknavigationaction/1401914-navigationtype))
|
||||
///- MacOS ([Official API - WKNavigationAction.navigationType](https://developer.apple.com/documentation/webkit/wknavigationaction/1401914-navigationtype))
|
||||
///- Windows
|
||||
NavigationType? navigationType;
|
||||
|
||||
///The URL request object associated with the navigation action.
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
|
||||
import '../in_app_webview/platform_webview.dart';
|
||||
part 'navigation_type.g.dart';
|
||||
@ -6,26 +7,119 @@ part 'navigation_type.g.dart';
|
||||
@ExchangeableEnum()
|
||||
class NavigationType_ {
|
||||
// ignore: unused_field
|
||||
final int _value;
|
||||
final String _value;
|
||||
// ignore: unused_field
|
||||
final int? _nativeValue = null;
|
||||
|
||||
const NavigationType_._internal(this._value);
|
||||
|
||||
///A link with an href attribute was activated by the user.
|
||||
static const LINK_ACTIVATED = const NavigationType_._internal(0);
|
||||
@EnumSupportedPlatforms(platforms: [
|
||||
EnumIOSPlatform(
|
||||
apiName: 'WKNavigationType.linkActivated',
|
||||
apiUrl:
|
||||
'https://developer.apple.com/documentation/webkit/wknavigationtype/linkactivated',
|
||||
value: 0),
|
||||
EnumMacOSPlatform(
|
||||
apiName: 'WKNavigationType.linkActivated',
|
||||
apiUrl:
|
||||
'https://developer.apple.com/documentation/webkit/wknavigationtype/linkactivated',
|
||||
value: 0),
|
||||
EnumWindowsPlatform(
|
||||
value: 0
|
||||
),
|
||||
])
|
||||
static const LINK_ACTIVATED = const NavigationType_._internal('LINK_ACTIVATED');
|
||||
|
||||
///A form was submitted.
|
||||
static const FORM_SUBMITTED = const NavigationType_._internal(1);
|
||||
@EnumSupportedPlatforms(platforms: [
|
||||
EnumIOSPlatform(
|
||||
apiName: 'WKNavigationType.formSubmitted',
|
||||
apiUrl:
|
||||
'https://developer.apple.com/documentation/webkit/wknavigationtype/formsubmitted',
|
||||
value: 1),
|
||||
EnumMacOSPlatform(
|
||||
apiName: 'WKNavigationType.formSubmitted',
|
||||
apiUrl:
|
||||
'https://developer.apple.com/documentation/webkit/wknavigationtype/formsubmitted',
|
||||
value: 1),
|
||||
])
|
||||
static const FORM_SUBMITTED = const NavigationType_._internal('FORM_SUBMITTED');
|
||||
|
||||
///An item from the back-forward list was requested.
|
||||
static const BACK_FORWARD = const NavigationType_._internal(2);
|
||||
@EnumSupportedPlatforms(platforms: [
|
||||
EnumIOSPlatform(
|
||||
apiName: 'WKNavigationType.formSubmitted',
|
||||
apiUrl:
|
||||
'https://developer.apple.com/documentation/webkit/wknavigationtype/formsubmitted',
|
||||
value: 2),
|
||||
EnumMacOSPlatform(
|
||||
apiName: 'WKNavigationType.formSubmitted',
|
||||
apiUrl:
|
||||
'https://developer.apple.com/documentation/webkit/wknavigationtype/formsubmitted',
|
||||
value: 2),
|
||||
EnumWindowsPlatform(
|
||||
apiName: 'COREWEBVIEW2_NAVIGATION_KIND_BACK_OR_FORWARD',
|
||||
apiUrl:
|
||||
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_navigation_kind',
|
||||
value: 1
|
||||
),
|
||||
])
|
||||
static const BACK_FORWARD = const NavigationType_._internal('BACK_FORWARD');
|
||||
|
||||
///The webpage was reloaded.
|
||||
static const RELOAD = const NavigationType_._internal(3);
|
||||
@EnumSupportedPlatforms(platforms: [
|
||||
EnumIOSPlatform(
|
||||
apiName: 'WKNavigationType.reload',
|
||||
apiUrl:
|
||||
'https://developer.apple.com/documentation/webkit/wknavigationtype/reload',
|
||||
value: 3),
|
||||
EnumMacOSPlatform(
|
||||
apiName: 'WKNavigationType.reload',
|
||||
apiUrl:
|
||||
'https://developer.apple.com/documentation/webkit/wknavigationtype/reload',
|
||||
value: 3),
|
||||
EnumWindowsPlatform(
|
||||
apiName: 'COREWEBVIEW2_NAVIGATION_KIND_RELOAD',
|
||||
apiUrl:
|
||||
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_navigation_kind',
|
||||
value: 2
|
||||
),
|
||||
])
|
||||
static const RELOAD = const NavigationType_._internal('RELOAD');
|
||||
|
||||
///A form was resubmitted (for example by going back, going forward, or reloading).
|
||||
static const FORM_RESUBMITTED = const NavigationType_._internal(4);
|
||||
@EnumSupportedPlatforms(platforms: [
|
||||
EnumIOSPlatform(
|
||||
apiName: 'WKNavigationType.formSubmitted',
|
||||
apiUrl:
|
||||
'https://developer.apple.com/documentation/webkit/wknavigationtype/formresubmitted',
|
||||
value: 4),
|
||||
EnumMacOSPlatform(
|
||||
apiName: 'WKNavigationType.formSubmitted',
|
||||
apiUrl:
|
||||
'https://developer.apple.com/documentation/webkit/wknavigationtype/formresubmitted',
|
||||
value: 4),
|
||||
])
|
||||
static const FORM_RESUBMITTED = const NavigationType_._internal('FORM_RESUBMITTED');
|
||||
|
||||
///Navigation is taking place for some other reason.
|
||||
static const OTHER = const NavigationType_._internal(-1);
|
||||
@EnumSupportedPlatforms(platforms: [
|
||||
EnumIOSPlatform(
|
||||
apiName: 'WKNavigationType.other',
|
||||
apiUrl:
|
||||
'https://developer.apple.com/documentation/webkit/wknavigationtype/other',
|
||||
value: -1),
|
||||
EnumMacOSPlatform(
|
||||
apiName: 'WKNavigationType.other',
|
||||
apiUrl:
|
||||
'https://developer.apple.com/documentation/webkit/wknavigationtype/other',
|
||||
value: -1),
|
||||
EnumWindowsPlatform(
|
||||
value: 3
|
||||
),
|
||||
])
|
||||
static const OTHER = const NavigationType_._internal('OTHER');
|
||||
}
|
||||
|
||||
///Class that represents the type of action triggering a navigation on iOS for the [PlatformWebViewCreationParams.shouldOverrideUrlLoading] event.
|
||||
|
@ -8,31 +8,131 @@ part of 'navigation_type.dart';
|
||||
|
||||
///Class that represents the type of action triggering a navigation for the [PlatformWebViewCreationParams.shouldOverrideUrlLoading] event.
|
||||
class NavigationType {
|
||||
final int _value;
|
||||
final int _nativeValue;
|
||||
final String _value;
|
||||
final int? _nativeValue;
|
||||
const NavigationType._internal(this._value, this._nativeValue);
|
||||
// ignore: unused_element
|
||||
factory NavigationType._internalMultiPlatform(
|
||||
int value, Function nativeValue) =>
|
||||
String value, Function nativeValue) =>
|
||||
NavigationType._internal(value, nativeValue());
|
||||
|
||||
///An item from the back-forward list was requested.
|
||||
static const BACK_FORWARD = NavigationType._internal(2, 2);
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS ([Official API - WKNavigationType.formSubmitted](https://developer.apple.com/documentation/webkit/wknavigationtype/formsubmitted))
|
||||
///- MacOS ([Official API - WKNavigationType.formSubmitted](https://developer.apple.com/documentation/webkit/wknavigationtype/formsubmitted))
|
||||
///- Windows ([Official API - COREWEBVIEW2_NAVIGATION_KIND_BACK_OR_FORWARD](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_navigation_kind))
|
||||
static final BACK_FORWARD =
|
||||
NavigationType._internalMultiPlatform('BACK_FORWARD', () {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
return 2;
|
||||
case TargetPlatform.macOS:
|
||||
return 2;
|
||||
case TargetPlatform.windows:
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
///A form was resubmitted (for example by going back, going forward, or reloading).
|
||||
static const FORM_RESUBMITTED = NavigationType._internal(4, 4);
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS ([Official API - WKNavigationType.formSubmitted](https://developer.apple.com/documentation/webkit/wknavigationtype/formresubmitted))
|
||||
///- MacOS ([Official API - WKNavigationType.formSubmitted](https://developer.apple.com/documentation/webkit/wknavigationtype/formresubmitted))
|
||||
static final FORM_RESUBMITTED =
|
||||
NavigationType._internalMultiPlatform('FORM_RESUBMITTED', () {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
return 4;
|
||||
case TargetPlatform.macOS:
|
||||
return 4;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
///A form was submitted.
|
||||
static const FORM_SUBMITTED = NavigationType._internal(1, 1);
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS ([Official API - WKNavigationType.formSubmitted](https://developer.apple.com/documentation/webkit/wknavigationtype/formsubmitted))
|
||||
///- MacOS ([Official API - WKNavigationType.formSubmitted](https://developer.apple.com/documentation/webkit/wknavigationtype/formsubmitted))
|
||||
static final FORM_SUBMITTED =
|
||||
NavigationType._internalMultiPlatform('FORM_SUBMITTED', () {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
return 1;
|
||||
case TargetPlatform.macOS:
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
///A link with an href attribute was activated by the user.
|
||||
static const LINK_ACTIVATED = NavigationType._internal(0, 0);
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS ([Official API - WKNavigationType.linkActivated](https://developer.apple.com/documentation/webkit/wknavigationtype/linkactivated))
|
||||
///- MacOS ([Official API - WKNavigationType.linkActivated](https://developer.apple.com/documentation/webkit/wknavigationtype/linkactivated))
|
||||
///- Windows
|
||||
static final LINK_ACTIVATED =
|
||||
NavigationType._internalMultiPlatform('LINK_ACTIVATED', () {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
return 0;
|
||||
case TargetPlatform.macOS:
|
||||
return 0;
|
||||
case TargetPlatform.windows:
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
///Navigation is taking place for some other reason.
|
||||
static const OTHER = NavigationType._internal(-1, -1);
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS ([Official API - WKNavigationType.other](https://developer.apple.com/documentation/webkit/wknavigationtype/other))
|
||||
///- MacOS ([Official API - WKNavigationType.other](https://developer.apple.com/documentation/webkit/wknavigationtype/other))
|
||||
///- Windows
|
||||
static final OTHER = NavigationType._internalMultiPlatform('OTHER', () {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
return -1;
|
||||
case TargetPlatform.macOS:
|
||||
return -1;
|
||||
case TargetPlatform.windows:
|
||||
return 3;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
///The webpage was reloaded.
|
||||
static const RELOAD = NavigationType._internal(3, 3);
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- iOS ([Official API - WKNavigationType.reload](https://developer.apple.com/documentation/webkit/wknavigationtype/reload))
|
||||
///- MacOS ([Official API - WKNavigationType.reload](https://developer.apple.com/documentation/webkit/wknavigationtype/reload))
|
||||
///- Windows ([Official API - COREWEBVIEW2_NAVIGATION_KIND_RELOAD](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_navigation_kind))
|
||||
static final RELOAD = NavigationType._internalMultiPlatform('RELOAD', () {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
return 3;
|
||||
case TargetPlatform.macOS:
|
||||
return 3;
|
||||
case TargetPlatform.windows:
|
||||
return 2;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
///Set of all values of [NavigationType].
|
||||
static final Set<NavigationType> values = [
|
||||
@ -44,8 +144,8 @@ class NavigationType {
|
||||
NavigationType.RELOAD,
|
||||
].toSet();
|
||||
|
||||
///Gets a possible [NavigationType] instance from [int] value.
|
||||
static NavigationType? fromValue(int? value) {
|
||||
///Gets a possible [NavigationType] instance from [String] value.
|
||||
static NavigationType? fromValue(String? value) {
|
||||
if (value != null) {
|
||||
try {
|
||||
return NavigationType.values
|
||||
@ -70,11 +170,11 @@ class NavigationType {
|
||||
return null;
|
||||
}
|
||||
|
||||
///Gets [int] value.
|
||||
int toValue() => _value;
|
||||
///Gets [String] value.
|
||||
String toValue() => _value;
|
||||
|
||||
///Gets [int] native value.
|
||||
int toNativeValue() => _nativeValue;
|
||||
///Gets [int?] native value.
|
||||
int? toNativeValue() => _nativeValue;
|
||||
|
||||
@override
|
||||
int get hashCode => _value.hashCode;
|
||||
@ -84,21 +184,7 @@ class NavigationType {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
switch (_value) {
|
||||
case 2:
|
||||
return 'BACK_FORWARD';
|
||||
case 4:
|
||||
return 'FORM_RESUBMITTED';
|
||||
case 1:
|
||||
return 'FORM_SUBMITTED';
|
||||
case 0:
|
||||
return 'LINK_ACTIVATED';
|
||||
case -1:
|
||||
return 'OTHER';
|
||||
case 3:
|
||||
return 'RELOAD';
|
||||
}
|
||||
return _value.toString();
|
||||
return _value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,12 @@ class WebHistoryItem_ {
|
||||
///Position offset respect to the currentIndex of the back-forward [WebHistory.list].
|
||||
int? offset;
|
||||
|
||||
///Unique id of the navigation history entry.
|
||||
@SupportedPlatforms(platforms: [
|
||||
WindowsPlatform()
|
||||
])
|
||||
int? entryId;
|
||||
|
||||
WebHistoryItem_(
|
||||
{this.originalUrl, this.title, this.url, this.index, this.offset});
|
||||
{this.originalUrl, this.title, this.url, this.index, this.offset, this.entryId});
|
||||
}
|
||||
|
@ -9,6 +9,12 @@ part of 'web_history_item.dart';
|
||||
///A convenience class for accessing fields in an entry in the back/forward list of a `WebView`.
|
||||
///Each [WebHistoryItem] is a snapshot of the requested history item.
|
||||
class WebHistoryItem {
|
||||
///Unique id of the navigation history entry.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Windows
|
||||
int? entryId;
|
||||
|
||||
///0-based position index in the back-forward [WebHistory.list].
|
||||
int? index;
|
||||
|
||||
@ -24,7 +30,12 @@ class WebHistoryItem {
|
||||
///Url of this history item.
|
||||
WebUri? url;
|
||||
WebHistoryItem(
|
||||
{this.index, this.offset, this.originalUrl, this.title, this.url});
|
||||
{this.entryId,
|
||||
this.index,
|
||||
this.offset,
|
||||
this.originalUrl,
|
||||
this.title,
|
||||
this.url});
|
||||
|
||||
///Gets a possible [WebHistoryItem] instance from a [Map] value.
|
||||
static WebHistoryItem? fromMap(Map<String, dynamic>? map) {
|
||||
@ -32,6 +43,7 @@ class WebHistoryItem {
|
||||
return null;
|
||||
}
|
||||
final instance = WebHistoryItem(
|
||||
entryId: map['entryId'],
|
||||
index: map['index'],
|
||||
offset: map['offset'],
|
||||
originalUrl:
|
||||
@ -45,6 +57,7 @@ class WebHistoryItem {
|
||||
///Converts instance to a map.
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
"entryId": entryId,
|
||||
"index": index,
|
||||
"offset": offset,
|
||||
"originalUrl": originalUrl?.toString(),
|
||||
@ -60,6 +73,6 @@ class WebHistoryItem {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'WebHistoryItem{index: $index, offset: $offset, originalUrl: $originalUrl, title: $title, url: $url}';
|
||||
return 'WebHistoryItem{entryId: $entryId, index: $index, offset: $offset, originalUrl: $originalUrl, title: $title, url: $url}';
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,10 @@ add_custom_command(
|
||||
list(APPEND PLUGIN_SOURCES
|
||||
"flutter_inappwebview_windows_plugin.cpp"
|
||||
"flutter_inappwebview_windows_plugin.h"
|
||||
"utils/log.h"
|
||||
"utils/strconv.h"
|
||||
"utils/map.h"
|
||||
"utils/vector.h"
|
||||
"utils/util.h"
|
||||
"utils/flutter.h"
|
||||
"types/channel_delegate.cpp"
|
||||
@ -60,6 +63,10 @@ list(APPEND PLUGIN_SOURCES
|
||||
"types/web_history.h"
|
||||
"types/web_history_item.cpp"
|
||||
"types/web_history_item.h"
|
||||
"types/user_script.cpp"
|
||||
"types/user_script.h"
|
||||
"types/plugin_script.cpp"
|
||||
"types/plugin_script.h"
|
||||
"custom_platform_view/custom_platform_view.cc"
|
||||
"custom_platform_view/custom_platform_view.h"
|
||||
"custom_platform_view/texture_bridge.cc"
|
||||
@ -73,6 +80,10 @@ list(APPEND PLUGIN_SOURCES
|
||||
"custom_platform_view/util/string_converter.cc"
|
||||
"custom_platform_view/util/string_converter.h"
|
||||
"custom_platform_view/util/swizzle.h"
|
||||
"plugin_scripts_js/javascript_bridge_js.cpp"
|
||||
"plugin_scripts_js/javascript_bridge_js.h"
|
||||
"in_app_webview/user_content_controller.cpp"
|
||||
"in_app_webview/user_content_controller.h"
|
||||
"in_app_webview/in_app_webview_settings.cpp"
|
||||
"in_app_webview/in_app_webview_settings.h"
|
||||
"in_app_webview/in_app_webview.cpp"
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "../utils/log.h"
|
||||
#include "custom_platform_view.h"
|
||||
|
||||
#include <flutter/event_stream_handler_functions.h>
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <Windows.h>
|
||||
|
||||
#include "../utils/util.h"
|
||||
#include "../utils/log.h"
|
||||
#include "../utils/strconv.h"
|
||||
#include "in_app_browser.h"
|
||||
#include "in_app_browser_manager.h"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "../utils/util.h"
|
||||
#include "../utils/log.h"
|
||||
#include "in_app_browser.h"
|
||||
#include "in_app_browser_channel_delegate.h"
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "../in_app_webview/in_app_webview_settings.h"
|
||||
#include "../types/url_request.h"
|
||||
#include "../utils/flutter.h"
|
||||
#include "../utils/log.h"
|
||||
#include "in_app_browser_manager.h"
|
||||
#include "in_app_browser_settings.h"
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "../utils/flutter.h"
|
||||
#include "../utils/log.h"
|
||||
#include "in_app_browser_settings.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
|
@ -5,10 +5,11 @@
|
||||
#include <wil/wrl.h>
|
||||
|
||||
#include "../custom_platform_view/util/composition.desktop.interop.h"
|
||||
#include "../plugin_scripts_js/javascript_bridge_js.h"
|
||||
#include "../types/web_resource_error.h"
|
||||
#include "../types/web_resource_request.h"
|
||||
#include "../utils/log.h"
|
||||
#include "../utils/strconv.h"
|
||||
#include "../utils/util.h"
|
||||
#include "in_app_webview.h"
|
||||
#include "in_app_webview_manager.h"
|
||||
|
||||
@ -19,13 +20,12 @@ namespace flutter_inappwebview_plugin
|
||||
InAppWebView::InAppWebView(const FlutterInappwebviewWindowsPlugin* plugin, const InAppWebViewCreationParams& params, const HWND parentWindow, wil::com_ptr<ICoreWebView2Environment> webViewEnv,
|
||||
wil::com_ptr<ICoreWebView2Controller> webViewController,
|
||||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)
|
||||
: plugin(plugin), id(params.id), webViewEnv(std::move(webViewEnv)), webViewController(std::move(webViewController)), webViewCompositionController(std::move(webViewCompositionController)),
|
||||
settings(params.initialSettings)
|
||||
: plugin(plugin), id(params.id),
|
||||
webViewEnv(std::move(webViewEnv)), webViewController(std::move(webViewController)), webViewCompositionController(std::move(webViewCompositionController)),
|
||||
settings(params.initialSettings), userContentController(std::make_unique<UserContentController>(this))
|
||||
{
|
||||
auto hrWebView2 = this->webViewController->get_CoreWebView2(webView.put());
|
||||
if (FAILED(hrWebView2)) {
|
||||
if (failedAndLog(this->webViewController->get_CoreWebView2(webView.put()))) {
|
||||
std::cerr << "Cannot create CoreWebView2." << std::endl;
|
||||
debugLog(getErrorMessage(hrWebView2));
|
||||
}
|
||||
|
||||
if (this->webViewCompositionController) {
|
||||
@ -41,24 +41,7 @@ namespace flutter_inappwebview_plugin
|
||||
this->webViewController->put_Bounds(bounds);
|
||||
}
|
||||
|
||||
wil::com_ptr<ICoreWebView2Settings> webView2Settings;
|
||||
auto hrWebView2Settings = webView->get_Settings(&webView2Settings);
|
||||
if (SUCCEEDED(hrWebView2Settings)) {
|
||||
webView2Settings->put_IsScriptEnabled(settings->javaScriptEnabled);
|
||||
webView2Settings->put_IsZoomControlEnabled(settings->supportZoom);
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
debugLog(getErrorMessage(hrWebView2Settings));
|
||||
}
|
||||
|
||||
registerEventHandlers();
|
||||
prepare();
|
||||
}
|
||||
|
||||
InAppWebView::InAppWebView(InAppBrowser* inAppBrowser, const FlutterInappwebviewWindowsPlugin* plugin, const InAppWebViewCreationParams& params, const HWND parentWindow, wil::com_ptr<ICoreWebView2Environment> webViewEnv,
|
||||
@ -73,61 +56,54 @@ namespace flutter_inappwebview_plugin
|
||||
wil::com_ptr<ICoreWebView2Controller> webViewController,
|
||||
wil::com_ptr<ICoreWebView2CompositionController> webViewCompositionController)> completionHandler)
|
||||
{
|
||||
CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,
|
||||
failedLog(CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,
|
||||
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
|
||||
[parentWindow, completionHandler, willBeSurface](HRESULT result, wil::com_ptr<ICoreWebView2Environment> env) -> HRESULT
|
||||
{
|
||||
if (FAILED(result) || !env) {
|
||||
if (failedAndLog(result) || !env) {
|
||||
completionHandler(nullptr, nullptr, nullptr);
|
||||
debugLog(getErrorMessage(result));
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
wil::com_ptr<ICoreWebView2Environment3> webViewEnv3;
|
||||
if (willBeSurface && SUCCEEDED(env->QueryInterface(IID_PPV_ARGS(&webViewEnv3)))) {
|
||||
webViewEnv3->CreateCoreWebView2CompositionController(parentWindow, Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(
|
||||
if (willBeSurface && succeededOrLog(env->QueryInterface(IID_PPV_ARGS(&webViewEnv3)))) {
|
||||
failedLog(webViewEnv3->CreateCoreWebView2CompositionController(parentWindow, Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(
|
||||
[completionHandler, env](HRESULT result, wil::com_ptr<ICoreWebView2CompositionController> compositionController) -> HRESULT
|
||||
{
|
||||
wil::com_ptr<ICoreWebView2Controller3> webViewController = compositionController.try_query<ICoreWebView2Controller3>();
|
||||
|
||||
if (FAILED(result) || !webViewController) {
|
||||
if (failedAndLog(result) || !webViewController) {
|
||||
completionHandler(nullptr, nullptr, nullptr);
|
||||
debugLog(getErrorMessage(result));
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
ICoreWebView2Controller3* webViewController3;
|
||||
HRESULT hr = webViewController->QueryInterface(IID_PPV_ARGS(&webViewController3));
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (succeededOrLog(webViewController->QueryInterface(IID_PPV_ARGS(&webViewController3)))) {
|
||||
webViewController3->put_BoundsMode(COREWEBVIEW2_BOUNDS_MODE_USE_RAW_PIXELS);
|
||||
webViewController3->put_ShouldDetectMonitorScaleChanges(FALSE);
|
||||
webViewController3->put_RasterizationScale(1.0);
|
||||
}
|
||||
else {
|
||||
debugLog(getErrorMessage(hr));
|
||||
}
|
||||
|
||||
completionHandler(std::move(env), std::move(webViewController), std::move(compositionController));
|
||||
return S_OK;
|
||||
}
|
||||
).Get());
|
||||
).Get()));
|
||||
}
|
||||
else {
|
||||
env->CreateCoreWebView2Controller(parentWindow, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
|
||||
failedLog(env->CreateCoreWebView2Controller(parentWindow, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
|
||||
[completionHandler, env](HRESULT result, wil::com_ptr<ICoreWebView2Controller> controller) -> HRESULT
|
||||
{
|
||||
if (FAILED(result) || !controller) {
|
||||
if (failedAndLog(result) || !controller) {
|
||||
completionHandler(nullptr, nullptr, nullptr);
|
||||
debugLog(getErrorMessage(result));
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
completionHandler(std::move(env), std::move(controller), nullptr);
|
||||
return S_OK;
|
||||
}).Get());
|
||||
}).Get()));
|
||||
}
|
||||
return S_OK;
|
||||
}).Get());
|
||||
}).Get()));
|
||||
}
|
||||
|
||||
void InAppWebView::initChannel(const std::optional<std::variant<std::string, int64_t>> viewId, const std::optional<std::string> channelName)
|
||||
@ -139,16 +115,43 @@ namespace flutter_inappwebview_plugin
|
||||
std::make_unique<WebViewChannelDelegate>(this, plugin->registrar->messenger());
|
||||
}
|
||||
|
||||
void InAppWebView::prepare()
|
||||
{
|
||||
if (!webView) {
|
||||
return;
|
||||
}
|
||||
|
||||
wil::com_ptr<ICoreWebView2Settings> webView2Settings;
|
||||
auto hrWebView2Settings = webView->get_Settings(&webView2Settings);
|
||||
if (succeededOrLog(hrWebView2Settings)) {
|
||||
webView2Settings->put_IsScriptEnabled(settings->javaScriptEnabled);
|
||||
webView2Settings->put_IsZoomControlEnabled(settings->supportZoom);
|
||||
|
||||
wil::com_ptr<ICoreWebView2Settings2> webView2Settings2;
|
||||
if (succeededOrLog(webView2Settings->QueryInterface(IID_PPV_ARGS(&webView2Settings2)))) {
|
||||
if (!settings->userAgent.empty()) {
|
||||
webView2Settings2->put_UserAgent(ansi_to_wide(settings->userAgent).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
userContentController->addPluginScript(std::move(createJavaScriptBridgePluginScript()));
|
||||
|
||||
registerEventHandlers();
|
||||
}
|
||||
|
||||
void InAppWebView::registerEventHandlers()
|
||||
{
|
||||
if (!webView) {
|
||||
return;
|
||||
}
|
||||
|
||||
webView->add_NavigationStarting(
|
||||
failedLog(webView->add_NavigationStarting(
|
||||
Callback<ICoreWebView2NavigationStartingEventHandler>(
|
||||
[this](ICoreWebView2* sender, ICoreWebView2NavigationStartingEventArgs* args)
|
||||
{
|
||||
isLoading_ = true;
|
||||
|
||||
if (!channelDelegate) {
|
||||
args->put_Cancel(false);
|
||||
return S_OK;
|
||||
@ -183,12 +186,52 @@ namespace flutter_inappwebview_plugin
|
||||
|
||||
std::optional<std::string> method = requestMethod ? wide_to_utf8(requestMethod.get()) : std::optional<std::string>{};
|
||||
|
||||
BOOL isUserInitiated;
|
||||
if (FAILED(args->get_IsUserInitiated(&isUserInitiated))) {
|
||||
isUserInitiated = FALSE;
|
||||
}
|
||||
|
||||
BOOL isRedirect;
|
||||
if (FAILED(args->get_IsRedirected(&isRedirect))) {
|
||||
isRedirect = FALSE;
|
||||
}
|
||||
|
||||
std::optional<NavigationActionType> navigationType = std::nullopt;
|
||||
wil::com_ptr<ICoreWebView2NavigationStartingEventArgs3> args3;
|
||||
if (SUCCEEDED(args->QueryInterface(IID_PPV_ARGS(&args3)))) {
|
||||
COREWEBVIEW2_NAVIGATION_KIND navigationKind;
|
||||
if (SUCCEEDED(args3->get_NavigationKind(&navigationKind))) {
|
||||
switch (navigationKind) {
|
||||
case COREWEBVIEW2_NAVIGATION_KIND_RELOAD:
|
||||
navigationType = NavigationActionType::reload;
|
||||
break;
|
||||
case COREWEBVIEW2_NAVIGATION_KIND_BACK_OR_FORWARD:
|
||||
navigationType = NavigationActionType::backForward;
|
||||
break;
|
||||
case COREWEBVIEW2_NAVIGATION_KIND_NEW_DOCUMENT:
|
||||
if (isUserInitiated && !isRedirect) {
|
||||
navigationType = NavigationActionType::linkActivated;
|
||||
}
|
||||
else {
|
||||
navigationType = NavigationActionType::other;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
navigationType = NavigationActionType::other;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto urlRequest = std::make_shared<URLRequest>(url, method, headers, std::nullopt);
|
||||
auto navigationAction = std::make_shared<NavigationAction>(
|
||||
urlRequest,
|
||||
true
|
||||
true,
|
||||
isRedirect,
|
||||
navigationType
|
||||
);
|
||||
|
||||
lastNavigationAction_ = navigationAction;
|
||||
|
||||
UINT64 navigationId;
|
||||
if (SUCCEEDED(args->get_NavigationId(&navigationId))) {
|
||||
navigationActions.insert({ navigationId, navigationAction });
|
||||
@ -202,7 +245,7 @@ namespace flutter_inappwebview_plugin
|
||||
callback->nonNullSuccess = [this, urlRequest](const NavigationActionPolicy actionPolicy)
|
||||
{
|
||||
callShouldOverrideUrlLoading_ = false;
|
||||
if (actionPolicy == allow) {
|
||||
if (actionPolicy == NavigationActionPolicy::allow) {
|
||||
loadUrl(*urlRequest);
|
||||
}
|
||||
return false;
|
||||
@ -229,12 +272,14 @@ namespace flutter_inappwebview_plugin
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
).Get(), nullptr);
|
||||
).Get(), nullptr));
|
||||
|
||||
webView->add_NavigationCompleted(
|
||||
failedLog(webView->add_NavigationCompleted(
|
||||
Callback<ICoreWebView2NavigationCompletedEventHandler>(
|
||||
[this](ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args)
|
||||
{
|
||||
isLoading_ = false;
|
||||
|
||||
std::shared_ptr<NavigationAction> navigationAction;
|
||||
UINT64 navigationId;
|
||||
if (SUCCEEDED(args->get_NavigationId(&navigationId))) {
|
||||
@ -251,8 +296,8 @@ namespace flutter_inappwebview_plugin
|
||||
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>{};
|
||||
wil::unique_cotaskmem_string uri;
|
||||
std::optional<std::string> url = SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(uri.get()) : std::optional<std::string>{};
|
||||
if (isSuccess) {
|
||||
channelDelegate->onLoadStop(url);
|
||||
}
|
||||
@ -273,9 +318,9 @@ namespace flutter_inappwebview_plugin
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
).Get(), nullptr);
|
||||
).Get(), nullptr));
|
||||
|
||||
webView->add_DocumentTitleChanged(Callback<ICoreWebView2DocumentTitleChangedEventHandler>(
|
||||
failedLog(webView->add_DocumentTitleChanged(Callback<ICoreWebView2DocumentTitleChangedEventHandler>(
|
||||
[this](ICoreWebView2* sender, IUnknown* args)
|
||||
{
|
||||
if (channelDelegate) {
|
||||
@ -285,7 +330,36 @@ namespace flutter_inappwebview_plugin
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
).Get(), nullptr);
|
||||
).Get(), nullptr));
|
||||
|
||||
failedLog(webView->add_HistoryChanged(Callback<ICoreWebView2HistoryChangedEventHandler>(
|
||||
[this](ICoreWebView2* sender, IUnknown* args)
|
||||
{
|
||||
if (channelDelegate) {
|
||||
std::optional<bool> isReload = std::nullopt;
|
||||
if (lastNavigationAction_ && lastNavigationAction_->navigationType.has_value()) {
|
||||
isReload = lastNavigationAction_->navigationType.value() == NavigationActionType::reload;
|
||||
}
|
||||
channelDelegate->onUpdateVisitedHistory(getUrl(), isReload);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
).Get(), nullptr));
|
||||
|
||||
failedLog(webView->add_WebMessageReceived(Callback<ICoreWebView2WebMessageReceivedEventHandler>(
|
||||
[this](ICoreWebView2* sender, ICoreWebView2WebMessageReceivedEventArgs* args)
|
||||
{
|
||||
wil::unique_cotaskmem_string uri;
|
||||
args->get_Source(&uri);
|
||||
|
||||
wil::unique_cotaskmem_string json;
|
||||
if (succeededOrLog(args->get_WebMessageAsJson(&json))) {
|
||||
debugLog(json.get());
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
).Get(), nullptr));
|
||||
}
|
||||
|
||||
void InAppWebView::registerSurfaceEventHandlers()
|
||||
@ -294,7 +368,7 @@ namespace flutter_inappwebview_plugin
|
||||
return;
|
||||
}
|
||||
|
||||
webViewCompositionController->add_CursorChanged(
|
||||
failedLog(webViewCompositionController->add_CursorChanged(
|
||||
Callback<ICoreWebView2CursorChangedEventHandler>(
|
||||
[this](ICoreWebView2CompositionController* sender,
|
||||
IUnknown* args) -> HRESULT
|
||||
@ -306,19 +380,19 @@ namespace flutter_inappwebview_plugin
|
||||
}
|
||||
return S_OK;
|
||||
})
|
||||
.Get(), nullptr);
|
||||
.Get(), nullptr));
|
||||
}
|
||||
|
||||
std::optional<std::string> InAppWebView::getUrl() const
|
||||
{
|
||||
LPWSTR uri;
|
||||
return SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(uri) : std::optional<std::string>{};
|
||||
wil::unique_cotaskmem_string uri;
|
||||
return webView && succeededOrLog(webView->get_Source(&uri)) ? wide_to_utf8(uri.get()) : std::optional<std::string>{};
|
||||
}
|
||||
|
||||
std::optional<std::string> InAppWebView::getTitle() const
|
||||
{
|
||||
LPWSTR title;
|
||||
return SUCCEEDED(webView->get_DocumentTitle(&title)) ? wide_to_utf8(title) : std::optional<std::string>{};
|
||||
wil::unique_cotaskmem_string title;
|
||||
return webView && succeededOrLog(webView->get_DocumentTitle(&title)) ? wide_to_utf8(title.get()) : std::optional<std::string>{};
|
||||
}
|
||||
|
||||
void InAppWebView::loadUrl(const URLRequest& urlRequest) const
|
||||
@ -341,59 +415,147 @@ namespace flutter_inappwebview_plugin
|
||||
postDataStream = SHCreateMemStream(
|
||||
reinterpret_cast<const BYTE*>(postData.data()), static_cast<UINT>(postData.length()));
|
||||
}
|
||||
webViewEnv2->CreateWebResourceRequest(
|
||||
if (succeededOrLog(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());
|
||||
))) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
failedLog(webView2->NavigateWithWebResourceRequest(webResourceRequest.get()));
|
||||
}
|
||||
webView2->NavigateWithWebResourceRequest(webResourceRequest.get());
|
||||
}
|
||||
else {
|
||||
webView->Navigate(url.c_str());
|
||||
return;
|
||||
}
|
||||
failedLog(webView->Navigate(url.c_str()));
|
||||
}
|
||||
|
||||
void InAppWebView::reload() const
|
||||
{
|
||||
webView->Reload();
|
||||
if (!webView) {
|
||||
return;
|
||||
}
|
||||
|
||||
failedLog(webView->Reload());
|
||||
}
|
||||
|
||||
void InAppWebView::goBack()
|
||||
{
|
||||
if (!webView) {
|
||||
return;
|
||||
}
|
||||
|
||||
callShouldOverrideUrlLoading_ = false;
|
||||
webView->GoBack();
|
||||
failedLog(webView->GoBack());
|
||||
}
|
||||
|
||||
bool InAppWebView::canGoBack() const
|
||||
{
|
||||
BOOL canGoBack_;
|
||||
return webView && succeededOrLog(webView->get_CanGoBack(&canGoBack_)) ? canGoBack_ : false;
|
||||
}
|
||||
|
||||
void InAppWebView::goForward()
|
||||
{
|
||||
if (!webView) {
|
||||
return;
|
||||
}
|
||||
|
||||
callShouldOverrideUrlLoading_ = false;
|
||||
webView->GoForward();
|
||||
failedLog(webView->GoForward());
|
||||
}
|
||||
|
||||
bool InAppWebView::canGoForward() const
|
||||
{
|
||||
BOOL canGoForward_;
|
||||
return webView && succeededOrLog(webView->get_CanGoForward(&canGoForward_)) ? canGoForward_ : false;
|
||||
}
|
||||
|
||||
void InAppWebView::goBackOrForward(const int& steps)
|
||||
{
|
||||
getCopyBackForwardList(
|
||||
[this, steps](std::unique_ptr<WebHistory> webHistory)
|
||||
{
|
||||
if (webHistory && webHistory->currentIndex.has_value() && webHistory->list.has_value()) {
|
||||
auto currentIndex = webHistory->currentIndex.value();
|
||||
auto items = &webHistory->list.value();
|
||||
auto nextIndex = currentIndex + steps;
|
||||
int64_t size = items->size();
|
||||
if (nextIndex >= 0 && nextIndex < size) {
|
||||
auto entryId = items->at(nextIndex)->entryId;
|
||||
std::cout << "entryId: " + std::to_string(entryId.value()) << "\n";
|
||||
if (entryId.has_value()) {
|
||||
auto oldCallShouldOverrideUrlLoading_ = callShouldOverrideUrlLoading_;
|
||||
callShouldOverrideUrlLoading_ = false;
|
||||
if (failedAndLog(webView->CallDevToolsProtocolMethod(L"Page.navigateToHistoryEntry", ansi_to_wide("{\"entryId\": " + std::to_string(entryId.value()) + "}").c_str(), Callback<ICoreWebView2CallDevToolsProtocolMethodCompletedHandler>(
|
||||
[this](HRESULT errorCode, LPCWSTR returnObjectAsJson)
|
||||
{
|
||||
failedLog(errorCode);
|
||||
return S_OK;
|
||||
}
|
||||
).Get()))) {
|
||||
callShouldOverrideUrlLoading_ = oldCallShouldOverrideUrlLoading_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void InAppWebView::canGoBackOrForward(const int& steps, std::function<void(bool)> completionHandler) const
|
||||
{
|
||||
getCopyBackForwardList(
|
||||
[steps, completionHandler](std::unique_ptr<WebHistory> webHistory)
|
||||
{
|
||||
auto canGoBackOrForward_ = false;
|
||||
if (webHistory && webHistory->currentIndex.has_value() && webHistory->list.has_value()) {
|
||||
auto currentIndex = webHistory->currentIndex.value();
|
||||
auto items = &webHistory->list.value();
|
||||
auto nextIndex = currentIndex + steps;
|
||||
int64_t size = items->size();
|
||||
canGoBackOrForward_ = nextIndex >= 0 && nextIndex < size;
|
||||
}
|
||||
completionHandler(canGoBackOrForward_);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void InAppWebView::stopLoading() const
|
||||
{
|
||||
if (!webView) {
|
||||
return;
|
||||
}
|
||||
|
||||
failedLog(webView->Stop());
|
||||
}
|
||||
|
||||
void InAppWebView::getCopyBackForwardList(const std::function<void(std::unique_ptr<WebHistory>)> completionHandler) const
|
||||
{
|
||||
webView->CallDevToolsProtocolMethod(L"Page.getNavigationHistory", L"{}", Callback<ICoreWebView2CallDevToolsProtocolMethodCompletedHandler>(
|
||||
if (!webView) {
|
||||
completionHandler(std::make_unique<WebHistory>(std::nullopt, std::nullopt));
|
||||
return;
|
||||
}
|
||||
|
||||
failedLog(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<nlohmann::json> 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());
|
||||
@ -401,6 +563,7 @@ namespace flutter_inappwebview_plugin
|
||||
for (auto const& entry : entries) {
|
||||
int64_t offset = i - currentIndex;
|
||||
webHistoryItems.push_back(std::make_shared<WebHistoryItem>(
|
||||
entry.at("id").is_number_integer() ? entry.at("id").get<int64_t>() : std::optional<int64_t>{},
|
||||
i,
|
||||
offset,
|
||||
entry.at("userTypedURL").is_string() ? entry.at("userTypedURL").get<std::string>() : std::optional<std::string>{},
|
||||
@ -413,26 +576,27 @@ namespace flutter_inappwebview_plugin
|
||||
completionHandler(std::make_unique<WebHistory>(currentIndex, webHistoryItems));
|
||||
}
|
||||
else {
|
||||
debugLog(getErrorMessage(errorCode));
|
||||
debugLog(errorCode);
|
||||
completionHandler(std::make_unique<WebHistory>(std::nullopt, std::nullopt));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
).Get());
|
||||
).Get()));
|
||||
}
|
||||
|
||||
void InAppWebView::evaluateJavascript(const std::string& source, std::function<void(std::string)> completionHanlder) const
|
||||
{
|
||||
webView->ExecuteScript(ansi_to_wide(source).c_str(),
|
||||
failedLog(webView->ExecuteScript(ansi_to_wide(source).c_str(),
|
||||
Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
|
||||
[completionHanlder = std::move(completionHanlder)](HRESULT error, PCWSTR result) -> HRESULT
|
||||
{
|
||||
if (error != S_OK) {
|
||||
debugLog(getErrorMessage(error));
|
||||
debugLog(error);
|
||||
}
|
||||
completionHanlder(wide_to_ansi(result));
|
||||
return S_OK;
|
||||
}).Get());
|
||||
}).Get()));
|
||||
}
|
||||
|
||||
// flutter_view
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "../types/url_request.h"
|
||||
#include "../types/web_history.h"
|
||||
#include "in_app_webview_settings.h"
|
||||
#include "user_content_controller.h"
|
||||
#include "webview_channel_delegate.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
@ -88,6 +89,7 @@ namespace flutter_inappwebview_plugin
|
||||
std::map<UINT64, std::shared_ptr<NavigationAction>> navigationActions = {};
|
||||
const std::shared_ptr<InAppWebViewSettings> settings;
|
||||
InAppBrowser* inAppBrowser = nullptr;
|
||||
std::unique_ptr<UserContentController> userContentController;
|
||||
|
||||
InAppWebView(const FlutterInappwebviewWindowsPlugin* plugin, const InAppWebViewCreationParams& params, const HWND parentWindow,
|
||||
wil::com_ptr<ICoreWebView2Environment> webViewEnv,
|
||||
@ -127,12 +129,22 @@ namespace flutter_inappwebview_plugin
|
||||
winrt::com_ptr<ABI::Windows::UI::Composition::ICompositor> compositor);
|
||||
|
||||
void initChannel(const std::optional<std::variant<std::string, int64_t>> viewId, const std::optional<std::string> channelName);
|
||||
void prepare();
|
||||
std::optional<std::string> getUrl() const;
|
||||
std::optional<std::string> getTitle() const;
|
||||
void loadUrl(const URLRequest& urlRequest) const;
|
||||
void reload() const;
|
||||
void goBack();
|
||||
bool canGoBack() const;
|
||||
void goForward();
|
||||
bool canGoForward() const;
|
||||
void goBackOrForward(const int& steps);
|
||||
void canGoBackOrForward(const int& steps, std::function<void(bool)> completionHandler) const;
|
||||
bool isLoading() const
|
||||
{
|
||||
return isLoading_;
|
||||
}
|
||||
void stopLoading() const;
|
||||
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;
|
||||
|
||||
@ -147,6 +159,9 @@ namespace flutter_inappwebview_plugin
|
||||
VirtualKeyState virtualKeys_;
|
||||
|
||||
bool callShouldOverrideUrlLoading_ = true;
|
||||
std::shared_ptr<NavigationAction> lastNavigationAction_;
|
||||
bool isLoading_ = false;
|
||||
|
||||
void InAppWebView::registerEventHandlers();
|
||||
void InAppWebView::registerSurfaceEventHandlers();
|
||||
};
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "../in_app_webview/in_app_webview_settings.h"
|
||||
#include "../types/url_request.h"
|
||||
#include "../utils/flutter.h"
|
||||
#include "../utils/log.h"
|
||||
#include "in_app_webview_manager.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "../utils/flutter.h"
|
||||
#include "../utils/log.h"
|
||||
#include "in_app_webview_settings.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
|
@ -0,0 +1,121 @@
|
||||
#include <wil/wrl.h>
|
||||
|
||||
#include "../utils/log.h"
|
||||
#include "../utils/strconv.h"
|
||||
#include "../utils/vector.h"
|
||||
#include "in_app_webview.h"
|
||||
#include "user_content_controller.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
using namespace Microsoft::WRL;
|
||||
|
||||
UserContentController::UserContentController(InAppWebView* webView)
|
||||
: webView_(webView)
|
||||
{}
|
||||
|
||||
std::vector<std::shared_ptr<UserScript>> UserContentController::getUserOnlyScriptsAt(const UserScriptInjectionTime& injectionTime) const
|
||||
{
|
||||
return userOnlyScripts_.at(injectionTime);
|
||||
}
|
||||
|
||||
void UserContentController::addUserOnlyScript(std::shared_ptr<UserScript> userScript)
|
||||
{
|
||||
if (!userScript) {
|
||||
return;
|
||||
}
|
||||
|
||||
userOnlyScripts_.at(userScript->injectionTime).push_back(std::move(userScript));
|
||||
}
|
||||
|
||||
void UserContentController::addUserOnlyScripts(std::vector<std::shared_ptr<UserScript>> userScripts)
|
||||
{
|
||||
for (auto& userScript : userScripts) {
|
||||
addUserOnlyScript(std::move(userScript));
|
||||
}
|
||||
}
|
||||
|
||||
void UserContentController::removeUserOnlyScript(std::shared_ptr<UserScript> userScript)
|
||||
{
|
||||
if (!userScript) {
|
||||
return;
|
||||
}
|
||||
|
||||
vector_remove_erase_el(userOnlyScripts_.at(userScript->injectionTime), std::move(userScript));
|
||||
}
|
||||
|
||||
void UserContentController::removeUserOnlyScriptAt(const int64_t& index, const UserScriptInjectionTime& injectionTime)
|
||||
{
|
||||
auto& vec = userOnlyScripts_.at(injectionTime);
|
||||
int64_t size = vec.size();
|
||||
if (index >= size) {
|
||||
return;
|
||||
}
|
||||
|
||||
vec.erase(vec.begin() + index);
|
||||
}
|
||||
|
||||
void UserContentController::removeAllUserOnlyScripts()
|
||||
{
|
||||
userOnlyScripts_.at(UserScriptInjectionTime::atDocumentStart).clear();
|
||||
userOnlyScripts_.at(UserScriptInjectionTime::atDocumentEnd).clear();
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<PluginScript>> UserContentController::getPluginScriptsAt(const UserScriptInjectionTime& injectionTime) const
|
||||
{
|
||||
return pluginScripts_.at(injectionTime);
|
||||
}
|
||||
|
||||
void UserContentController::addPluginScript(std::shared_ptr<PluginScript> pluginScript)
|
||||
{
|
||||
if (!pluginScript || !webView_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pluginScript->injectionTime == UserScriptInjectionTime::atDocumentStart) {
|
||||
failedLog(webView_->webView->AddScriptToExecuteOnDocumentCreated(ansi_to_wide(pluginScript->source).c_str(),
|
||||
Callback<ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler>(
|
||||
[pluginScript](HRESULT error, PCWSTR id) -> HRESULT
|
||||
{
|
||||
if (succeededOrLog(error)) {
|
||||
pluginScript->id = id;
|
||||
}
|
||||
return S_OK;
|
||||
}).Get()));
|
||||
}
|
||||
|
||||
pluginScripts_.at(pluginScript->injectionTime).push_back(std::move(pluginScript));
|
||||
}
|
||||
|
||||
void UserContentController::addPluginScripts(std::vector<std::shared_ptr<PluginScript>> pluginScripts)
|
||||
{
|
||||
for (auto& pluginScript : pluginScripts) {
|
||||
addPluginScript(std::move(pluginScript));
|
||||
}
|
||||
}
|
||||
|
||||
void UserContentController::removePluginScript(std::shared_ptr<PluginScript> pluginScript)
|
||||
{
|
||||
if (!pluginScript || !webView_) {
|
||||
return;
|
||||
}
|
||||
|
||||
failedLog(webView_->webView->RemoveScriptToExecuteOnDocumentCreated(pluginScript->id.c_str()));
|
||||
|
||||
vector_remove_erase_el(pluginScripts_.at(pluginScript->injectionTime), std::move(pluginScript));
|
||||
}
|
||||
|
||||
void UserContentController::removeAllPluginScripts()
|
||||
{
|
||||
pluginScripts_.at(UserScriptInjectionTime::atDocumentStart).clear();
|
||||
pluginScripts_.at(UserScriptInjectionTime::atDocumentEnd).clear();
|
||||
}
|
||||
|
||||
UserContentController::~UserContentController()
|
||||
{
|
||||
debugLog("dealloc UserContentController");
|
||||
removeAllUserOnlyScripts();
|
||||
removeAllPluginScripts();
|
||||
webView_ = nullptr;
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_USER_CONTENT_CONTROLLER_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_USER_CONTENT_CONTROLLER_H_
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "../types/plugin_script.h"
|
||||
#include "../types/user_script.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
class InAppWebView;
|
||||
|
||||
class UserContentController
|
||||
{
|
||||
public:
|
||||
UserContentController(InAppWebView* webView);
|
||||
~UserContentController();
|
||||
|
||||
std::vector<std::shared_ptr<UserScript>> getUserOnlyScriptsAt(const UserScriptInjectionTime& injectionTime) const;
|
||||
void addUserOnlyScript(std::shared_ptr<UserScript> userScript);
|
||||
void addUserOnlyScripts(std::vector<std::shared_ptr<UserScript>> userScripts);
|
||||
void removeUserOnlyScript(std::shared_ptr<UserScript> userScript);
|
||||
void removeUserOnlyScriptAt(const int64_t& index, const UserScriptInjectionTime& injectionTime);
|
||||
void removeAllUserOnlyScripts();
|
||||
std::vector<std::shared_ptr<PluginScript>> getPluginScriptsAt(const UserScriptInjectionTime& injectionTime) const;
|
||||
void addPluginScript(std::shared_ptr<PluginScript> pluginScript);
|
||||
void addPluginScripts(std::vector<std::shared_ptr<PluginScript>> pluginScripts);
|
||||
void removePluginScript(std::shared_ptr<PluginScript> pluginScript);
|
||||
void removeAllPluginScripts();
|
||||
private:
|
||||
InAppWebView* webView_;
|
||||
|
||||
std::map<UserScriptInjectionTime, std::vector<std::shared_ptr<PluginScript>>> pluginScripts_ = {
|
||||
{UserScriptInjectionTime::atDocumentStart, {}},
|
||||
{UserScriptInjectionTime::atDocumentEnd, {}}
|
||||
};
|
||||
|
||||
std::map<UserScriptInjectionTime, std::vector<std::shared_ptr<UserScript>>> userOnlyScripts_ = {
|
||||
{UserScriptInjectionTime::atDocumentStart, {}},
|
||||
{UserScriptInjectionTime::atDocumentEnd, {}}
|
||||
};
|
||||
};
|
||||
}
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_USER_CONTENT_CONTROLLER_H_
|
@ -1,6 +1,7 @@
|
||||
#include "../in_app_browser/in_app_browser.h"
|
||||
#include "../types/base_callback_result.h"
|
||||
#include "../utils/flutter.h"
|
||||
#include "../utils/log.h"
|
||||
#include "../utils/strconv.h"
|
||||
#include "in_app_webview.h"
|
||||
#include "webview_channel_delegate.h"
|
||||
@ -20,7 +21,7 @@ namespace flutter_inappwebview_plugin
|
||||
decodeResult = [](const flutter::EncodableValue* value)
|
||||
{
|
||||
if (value->IsNull()) {
|
||||
return cancel;
|
||||
return NavigationActionPolicy::cancel;
|
||||
}
|
||||
auto navigationPolicy = std::get<int>(*value);
|
||||
return static_cast<NavigationActionPolicy>(navigationPolicy);
|
||||
@ -56,10 +57,37 @@ namespace flutter_inappwebview_plugin
|
||||
webView->goBack();
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("canGoBack") == 0) {
|
||||
result->Success(webView->canGoBack());
|
||||
}
|
||||
else if (method_call.method_name().compare("goForward") == 0) {
|
||||
webView->goForward();
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("canGoForward") == 0) {
|
||||
result->Success(webView->canGoForward());
|
||||
}
|
||||
else if (method_call.method_name().compare("goBackOrForward") == 0) {
|
||||
auto steps = get_fl_map_value<int>(arguments, "steps");
|
||||
webView->goBackOrForward(steps);
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("canGoBackOrForward") == 0) {
|
||||
auto result_ = std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result));
|
||||
|
||||
auto steps = get_fl_map_value<int>(arguments, "steps");
|
||||
webView->canGoBackOrForward(steps, [result_ = std::move(result_)](const bool& value)
|
||||
{
|
||||
result_->Success(value);
|
||||
});
|
||||
}
|
||||
else if (method_call.method_name().compare("isLoading") == 0) {
|
||||
result->Success(webView->isLoading());
|
||||
}
|
||||
else if (method_call.method_name().compare("stopLoading") == 0) {
|
||||
webView->stopLoading();
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("evaluateJavascript") == 0) {
|
||||
auto result_ = std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result));
|
||||
|
||||
@ -170,6 +198,19 @@ namespace flutter_inappwebview_plugin
|
||||
}
|
||||
}
|
||||
|
||||
void WebViewChannelDelegate::onUpdateVisitedHistory(const std::optional<std::string>& url, const std::optional<bool>& isReload) const
|
||||
{
|
||||
if (!channel) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
|
||||
{"url", make_fl_value(url)},
|
||||
{"isReload", make_fl_value(isReload)}
|
||||
});
|
||||
channel->InvokeMethod("onUpdateVisitedHistory", std::move(arguments));
|
||||
}
|
||||
|
||||
WebViewChannelDelegate::~WebViewChannelDelegate()
|
||||
{
|
||||
debugLog("dealloc WebViewChannelDelegate");
|
||||
|
@ -42,6 +42,7 @@ namespace flutter_inappwebview_plugin
|
||||
void onReceivedError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceError> error) const;
|
||||
void onReceivedHttpError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceResponse> error) const;
|
||||
void onTitleChanged(const std::optional<std::string>& title) const;
|
||||
void onUpdateVisitedHistory(const std::optional<std::string>& url, const std::optional<bool>& isReload) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,26 @@
|
||||
#include <set>
|
||||
|
||||
#include "javascript_bridge_js.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
const std::string JAVASCRIPT_BRIDGE_JS_SOURCE = "window." + JAVASCRIPT_BRIDGE_NAME + " = {}; \
|
||||
window." + JAVASCRIPT_BRIDGE_NAME + ".callHandler = function() { \
|
||||
var _callHandlerID = setTimeout(function() {}); \
|
||||
window.chrome.webview.postMessage({ 'internalHandlerName': 'callHandler', 'handlerName': arguments[0], '_callHandlerID' : _callHandlerID, 'args' : JSON.stringify(Array.prototype.slice.call(arguments, 1)) }); \
|
||||
return new Promise(function(resolve, reject) { \
|
||||
window." + JAVASCRIPT_BRIDGE_NAME + "[_callHandlerID] = { resolve: resolve, reject : reject };\
|
||||
});\
|
||||
};";
|
||||
|
||||
std::unique_ptr<PluginScript> createJavaScriptBridgePluginScript()
|
||||
{
|
||||
const std::set<std::string> allowedOriginRules = { "*" };
|
||||
return std::make_unique<PluginScript>(
|
||||
JAVASCRIPT_BRIDGE_JS_PLUGIN_SCRIPT_GROUP_NAME,
|
||||
JAVASCRIPT_BRIDGE_JS_SOURCE,
|
||||
UserScriptInjectionTime::atDocumentStart,
|
||||
allowedOriginRules
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_JAVASCRIPT_BRIDGE_JS_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_JAVASCRIPT_BRIDGE_JS_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "../types/plugin_script.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
const std::string JAVASCRIPT_BRIDGE_NAME = "flutter_inappwebview";
|
||||
const std::string JAVASCRIPT_BRIDGE_JS_PLUGIN_SCRIPT_GROUP_NAME = "IN_APP_WEBVIEW_JAVASCRIPT_BRIDGE_JS_PLUGIN_SCRIPT";
|
||||
|
||||
std::unique_ptr<PluginScript> createJavaScriptBridgePluginScript();
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_JAVASCRIPT_BRIDGE_JS_H_
|
@ -3,15 +3,19 @@
|
||||
|
||||
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,
|
||||
const std::optional<bool>& isRedirect, const std::optional<NavigationActionType>& navigationType)
|
||||
: request(std::move(request)), isForMainFrame(isForMainFrame),
|
||||
isRedirect(isRedirect), navigationType(navigationType)
|
||||
{}
|
||||
|
||||
flutter::EncodableMap NavigationAction::toEncodableMap() const
|
||||
{
|
||||
return flutter::EncodableMap{
|
||||
{"request", request->toEncodableMap()},
|
||||
{"isForMainFrame", make_fl_value(isForMainFrame)}
|
||||
{"isForMainFrame", isForMainFrame},
|
||||
{"isRedirect", make_fl_value(isRedirect)},
|
||||
{"navigationType", make_fl_value(navigationType)}
|
||||
};
|
||||
}
|
||||
}
|
@ -8,13 +8,22 @@
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
enum NavigationActionType {
|
||||
linkActivated = 0,
|
||||
backForward,
|
||||
reload,
|
||||
other
|
||||
};
|
||||
|
||||
class NavigationAction
|
||||
{
|
||||
public:
|
||||
const std::shared_ptr<URLRequest> request;
|
||||
const bool isForMainFrame;
|
||||
const std::optional<bool> isRedirect;
|
||||
const std::optional<NavigationActionType> navigationType;
|
||||
|
||||
NavigationAction(std::shared_ptr<URLRequest> request, const bool& isForMainFrame);
|
||||
NavigationAction(std::shared_ptr<URLRequest> request, const bool& isForMainFrame, const std::optional<bool>& isRedirect, const std::optional<NavigationActionType>& navigationType);
|
||||
~NavigationAction() = default;
|
||||
|
||||
flutter::EncodableMap toEncodableMap() const;
|
||||
|
14
flutter_inappwebview_windows/windows/types/plugin_script.cpp
Normal file
14
flutter_inappwebview_windows/windows/types/plugin_script.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "plugin_script.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
PluginScript::PluginScript(
|
||||
const std::optional<std::string>& groupName,
|
||||
const std::string& source,
|
||||
const UserScriptInjectionTime& injectionTime,
|
||||
const std::set<std::string>& allowedOriginRules
|
||||
) : UserScript(groupName, source, injectionTime, allowedOriginRules)
|
||||
{}
|
||||
|
||||
PluginScript::~PluginScript() {}
|
||||
}
|
21
flutter_inappwebview_windows/windows/types/plugin_script.h
Normal file
21
flutter_inappwebview_windows/windows/types/plugin_script.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_PLUGIN_SCRIPT_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_PLUGIN_SCRIPT_H_
|
||||
|
||||
#include "user_script.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
class PluginScript : public UserScript
|
||||
{
|
||||
public:
|
||||
|
||||
PluginScript(
|
||||
const std::optional<std::string>& groupName,
|
||||
const std::string& source,
|
||||
const UserScriptInjectionTime& injectionTime,
|
||||
const std::set<std::string>& allowedOriginRules
|
||||
);
|
||||
~PluginScript();
|
||||
};
|
||||
}
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_PLUGIN_SCRIPT_H_
|
15
flutter_inappwebview_windows/windows/types/user_script.cpp
Normal file
15
flutter_inappwebview_windows/windows/types/user_script.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "user_script.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
UserScript::UserScript(
|
||||
const std::optional<std::string>& groupName,
|
||||
const std::string& source,
|
||||
const UserScriptInjectionTime& injectionTime,
|
||||
const std::set<std::string>& allowedOriginRules
|
||||
) : groupName(groupName), source(source), injectionTime(injectionTime), allowedOriginRules(allowedOriginRules)
|
||||
{}
|
||||
|
||||
UserScript::~UserScript()
|
||||
{}
|
||||
}
|
33
flutter_inappwebview_windows/windows/types/user_script.h
Normal file
33
flutter_inappwebview_windows/windows/types/user_script.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_USER_SCRIPT_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_USER_SCRIPT_H_
|
||||
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
enum UserScriptInjectionTime {
|
||||
atDocumentStart,
|
||||
atDocumentEnd
|
||||
};
|
||||
|
||||
class UserScript
|
||||
{
|
||||
public:
|
||||
std::wstring id;
|
||||
const std::optional<std::string> groupName;
|
||||
const std::string source;
|
||||
const UserScriptInjectionTime injectionTime;
|
||||
const std::set<std::string> allowedOriginRules;
|
||||
|
||||
UserScript(
|
||||
const std::optional<std::string>& groupName,
|
||||
const std::string& source,
|
||||
const UserScriptInjectionTime& injectionTime,
|
||||
const std::set<std::string>& allowedOriginRules
|
||||
);
|
||||
~UserScript();
|
||||
};
|
||||
}
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_USER_SCRIPT_H_
|
@ -2,14 +2,15 @@
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
WebHistoryItem::WebHistoryItem(const std::optional<int64_t>& index, const std::optional<int64_t>& offset,
|
||||
WebHistoryItem::WebHistoryItem(const std::optional<int64_t>& entryId, 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)
|
||||
: entryId(entryId), 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")),
|
||||
: entryId(get_optional_fl_map_value<int64_t>(map, "entryId")),
|
||||
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")),
|
||||
@ -19,6 +20,7 @@ namespace flutter_inappwebview_plugin
|
||||
flutter::EncodableMap WebHistoryItem::toEncodableMap() const
|
||||
{
|
||||
return flutter::EncodableMap{
|
||||
{"entryId", make_fl_value(entryId)},
|
||||
{"index", make_fl_value(index)},
|
||||
{"offset", make_fl_value(offset)},
|
||||
{"originalUrl", make_fl_value(originalUrl)},
|
||||
|
@ -11,13 +11,14 @@ namespace flutter_inappwebview_plugin
|
||||
class WebHistoryItem
|
||||
{
|
||||
public:
|
||||
const std::optional<int64_t> entryId;
|
||||
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,
|
||||
WebHistoryItem(const std::optional<int64_t>& entryId, 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);
|
||||
|
@ -3,7 +3,9 @@
|
||||
|
||||
#include <flutter/encodable_value.h>
|
||||
|
||||
#include "map.h"
|
||||
#include "util.h"
|
||||
#include "vector.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
|
67
flutter_inappwebview_windows/windows/utils/log.h
Normal file
67
flutter_inappwebview_windows/windows/utils/log.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_UTIL_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_UTIL_H_
|
||||
|
||||
#include <comdef.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "strconv.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
static inline void debugLog(const std::string& msg, const bool& isError = false)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (isError) {
|
||||
std::cerr << msg << std::endl;
|
||||
}
|
||||
else {
|
||||
std::cout << msg << std::endl;
|
||||
}
|
||||
OutputDebugString(ansi_to_wide(msg + "\n").c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void debugLog(const std::wstring& msg, const bool& isError = false)
|
||||
{
|
||||
debugLog(wide_to_ansi(msg), isError);
|
||||
}
|
||||
|
||||
static inline std::string getHRMessage(const HRESULT& error)
|
||||
{
|
||||
return wide_to_ansi(_com_error(error).ErrorMessage());
|
||||
}
|
||||
|
||||
static inline void debugLog(const HRESULT& hr)
|
||||
{
|
||||
auto isError = hr != S_OK;
|
||||
debugLog((isError ? "Error: " : "Message: ") + getHRMessage(hr), isError);
|
||||
}
|
||||
|
||||
static inline bool succeededOrLog(const HRESULT& hr)
|
||||
{
|
||||
if (SUCCEEDED(hr)) {
|
||||
return true;
|
||||
}
|
||||
debugLog(hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool failedAndLog(const HRESULT& hr)
|
||||
{
|
||||
if (FAILED(hr)) {
|
||||
debugLog(hr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void failedLog(const HRESULT& hr)
|
||||
{
|
||||
if (FAILED(hr)) {
|
||||
debugLog(hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_UTIL_H_
|
71
flutter_inappwebview_windows/windows/utils/map.h
Normal file
71
flutter_inappwebview_windows/windows/utils/map.h
Normal file
@ -0,0 +1,71 @@
|
||||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_MAP_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_MAP_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
template<typename T, typename U = void>
|
||||
struct is_mappish_impl : std::false_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 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 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_LOG_MAP_H_
|
@ -1,60 +1,12 @@
|
||||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <comdef.h>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
#include "strconv.h"
|
||||
|
||||
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
|
||||
std::cout << msg << std::endl;
|
||||
OutputDebugString(ansi_to_wide(msg + "\n").c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline std::string getErrorMessage(const HRESULT& error)
|
||||
{
|
||||
_com_error err(error);
|
||||
return wide_to_ansi(err.ErrorMessage());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline std::optional<T> make_pointer_optional(const T* value)
|
||||
{
|
||||
@ -74,52 +26,6 @@ namespace flutter_inappwebview_plugin
|
||||
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 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 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_
|
41
flutter_inappwebview_windows/windows/utils/vector.h
Normal file
41
flutter_inappwebview_windows/windows/utils/vector.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_VECTOR_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_VECTOR_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
template<typename T = void, typename = void>
|
||||
struct is_vector_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_vector : is_vector_impl<T>::type { };
|
||||
|
||||
template <typename T>
|
||||
static inline void vector_remove_el(std::vector<T>& vec, const T& el)
|
||||
{
|
||||
std::remove(vec.begin(), vec.end(), el);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline void vector_remove_erase_el(std::vector<T>& vec, const T& el)
|
||||
{
|
||||
vec.erase(std::remove(vec.begin(), vec.end(), el), vec.end());
|
||||
}
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_VECTOR_H_
|
Loading…
x
Reference in New Issue
Block a user