windows: fixed in app browser dealloc, fixed on load stop event, implemented onReceivedError and onReceivedHttpError events

This commit is contained in:
unknown 2024-01-07 23:28:46 +01:00
parent 43aa01d944
commit dcfeeb7497
35 changed files with 681 additions and 200 deletions

View File

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

View File

@ -64,6 +64,7 @@ class PlatformInAppBrowserCreationParams {
///- Android native WebView ///- Android native WebView
///- iOS ///- iOS
///- MacOS ///- MacOS
///- Windows
///{@endtemplate} ///{@endtemplate}
abstract class PlatformInAppBrowser extends PlatformInterface abstract class PlatformInAppBrowser extends PlatformInterface
implements Disposable { implements Disposable {
@ -172,6 +173,7 @@ abstract class PlatformInAppBrowser extends PlatformInterface
///- Android native WebView ///- Android native WebView
///- iOS ///- iOS
///- MacOS ///- MacOS
///- Windows
///{@endtemplate} ///{@endtemplate}
Future<void> openUrlRequest( Future<void> openUrlRequest(
{required URLRequest urlRequest, {required URLRequest urlRequest,
@ -464,6 +466,7 @@ abstract class PlatformInAppBrowser extends PlatformInterface
///- Android native WebView ///- Android native WebView
///- iOS ///- iOS
///- MacOS ///- MacOS
///- Windows
///{@endtemplate} ///{@endtemplate}
bool isOpened() { bool isOpened() {
throw UnimplementedError( throw UnimplementedError(
@ -487,6 +490,7 @@ abstract class PlatformInAppBrowserEvents {
///- Android native WebView ///- Android native WebView
///- iOS ///- iOS
///- MacOS ///- MacOS
///- Windows
void onBrowserCreated() {} void onBrowserCreated() {}
///Event fired when the [PlatformInAppBrowser] window is closed. ///Event fired when the [PlatformInAppBrowser] window is closed.
@ -495,6 +499,7 @@ abstract class PlatformInAppBrowserEvents {
///- Android native WebView ///- Android native WebView
///- iOS ///- iOS
///- MacOS ///- MacOS
///- Windows
void onExit() {} void onExit() {}
///Event fired when the main window is about to close. ///Event fired when the main window is about to close.
@ -509,6 +514,7 @@ abstract class PlatformInAppBrowserEvents {
///- Android native WebView ([Official API - WebViewClient.onPageStarted](https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap))) ///- Android native WebView ([Official API - WebViewClient.onPageStarted](https://developer.android.com/reference/android/webkit/WebViewClient#onPageStarted(android.webkit.WebView,%20java.lang.String,%20android.graphics.Bitmap)))
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview)) ///- 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)) ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview))
///- 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))
void onLoadStart(WebUri? url) {} void onLoadStart(WebUri? url) {}
///Event fired when the [PlatformInAppBrowser] finishes loading an [url]. ///Event fired when the [PlatformInAppBrowser] finishes loading an [url].
@ -517,6 +523,7 @@ abstract class PlatformInAppBrowserEvents {
///- Android native WebView ([Official API - WebViewClient.onPageFinished](https://developer.android.com/reference/android/webkit/WebViewClient#onPageFinished(android.webkit.WebView,%20java.lang.String))) ///- Android native WebView ([Official API - WebViewClient.onPageFinished](https://developer.android.com/reference/android/webkit/WebViewClient#onPageFinished(android.webkit.WebView,%20java.lang.String)))
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview)) ///- 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)) ///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-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))
void onLoadStop(WebUri? url) {} void onLoadStop(WebUri? url) {}
///Use [onReceivedError] instead. ///Use [onReceivedError] instead.
@ -529,6 +536,7 @@ abstract class PlatformInAppBrowserEvents {
///- 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))) ///- 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)) ///- 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)) ///- 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))
void onReceivedError(WebResourceRequest request, WebResourceError error) {} void onReceivedError(WebResourceRequest request, WebResourceError error) {}
///Use [onReceivedHttpError] instead. ///Use [onReceivedHttpError] instead.
@ -547,6 +555,7 @@ abstract class PlatformInAppBrowserEvents {
///- 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))) ///- 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)) ///- 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)) ///- 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))
void onReceivedHttpError( void onReceivedHttpError(
WebResourceRequest request, WebResourceResponse errorResponse) {} WebResourceRequest request, WebResourceResponse errorResponse) {}

View File

@ -134,6 +134,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
///- iOS ([Official API - WKWebView.url](https://developer.apple.com/documentation/webkit/wkwebview/1415005-url)) ///- iOS ([Official API - WKWebView.url](https://developer.apple.com/documentation/webkit/wkwebview/1415005-url))
///- MacOS ([Official API - WKWebView.url](https://developer.apple.com/documentation/webkit/wkwebview/1415005-url)) ///- MacOS ([Official API - WKWebView.url](https://developer.apple.com/documentation/webkit/wkwebview/1415005-url))
///- Web ///- Web
///- Windows ([Official API - IWebView2WebView.get_Source](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/iwebview2webview?view=webview2-0.8.355#get_source))
///{@endtemplate} ///{@endtemplate}
Future<WebUri?> getUrl() { Future<WebUri?> getUrl() {
throw UnimplementedError( throw UnimplementedError(
@ -224,6 +225,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
///- iOS ([Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1414954-load). If [allowingReadAccessTo] is used, [Official API - WKWebView.loadFileURL](https://developer.apple.com/documentation/webkit/wkwebview/1414973-loadfileurl)) ///- iOS ([Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1414954-load). If [allowingReadAccessTo] is used, [Official API - WKWebView.loadFileURL](https://developer.apple.com/documentation/webkit/wkwebview/1414973-loadfileurl))
///- MacOS ([Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1414954-load). If [allowingReadAccessTo] is used, [Official API - WKWebView.loadFileURL](https://developer.apple.com/documentation/webkit/wkwebview/1414973-loadfileurl)) ///- MacOS ([Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1414954-load). If [allowingReadAccessTo] is used, [Official API - WKWebView.loadFileURL](https://developer.apple.com/documentation/webkit/wkwebview/1414973-loadfileurl))
///- Web ///- Web
///- Windows ([Official API - ICoreWebView2_2.NavigateWithWebResourceRequest](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2_2?view=webview2-1.0.2210.55#navigatewithwebresourcerequest))
///{@endtemplate} ///{@endtemplate}
Future<void> loadUrl( Future<void> loadUrl(
{required URLRequest urlRequest, {required URLRequest urlRequest,

View File

@ -60,7 +60,12 @@ class WebResourceErrorType_ {
apiName: 'URLError.cannotConnectToHost', apiName: 'URLError.cannotConnectToHost',
apiUrl: apiUrl:
'https://developer.apple.com/documentation/foundation/urlerror/code/2883001-cannotconnecttohost', 'https://developer.apple.com/documentation/foundation/urlerror/code/2883001-cannotconnecttohost',
value: -1004) value: -1004),
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_CANNOT_CONNECT',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 12)
]) ])
static const CANNOT_CONNECT_TO_HOST = static const CANNOT_CONNECT_TO_HOST =
WebResourceErrorType_._internal("CANNOT_CONNECT_TO_HOST"); WebResourceErrorType_._internal("CANNOT_CONNECT_TO_HOST");
@ -124,7 +129,12 @@ class WebResourceErrorType_ {
apiName: 'URLError.cannotFindHost', apiName: 'URLError.cannotFindHost',
apiUrl: apiUrl:
'https://developer.apple.com/documentation/foundation/urlerror/code/2883157-cannotfindhost', 'https://developer.apple.com/documentation/foundation/urlerror/code/2883157-cannotfindhost',
value: -1003) value: -1003),
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_HOST_NAME_NOT_RESOLVED',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 13)
]) ])
static const HOST_LOOKUP = WebResourceErrorType_._internal("HOST_LOOKUP"); static const HOST_LOOKUP = WebResourceErrorType_._internal("HOST_LOOKUP");
@ -186,7 +196,12 @@ class WebResourceErrorType_ {
apiName: 'URLError.timedOut', apiName: 'URLError.timedOut',
apiUrl: apiUrl:
'https://developer.apple.com/documentation/foundation/urlerror/code/2883027-timedout', 'https://developer.apple.com/documentation/foundation/urlerror/code/2883027-timedout',
value: -1001) value: -1001),
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_TIMEOUT',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 7)
]) ])
static const TIMEOUT = WebResourceErrorType_._internal("TIMEOUT"); static const TIMEOUT = WebResourceErrorType_._internal("TIMEOUT");
@ -217,7 +232,12 @@ class WebResourceErrorType_ {
apiName: 'URLError.unknown', apiName: 'URLError.unknown',
apiUrl: apiUrl:
'https://developer.apple.com/documentation/foundation/urlerror/2293357-unknown', 'https://developer.apple.com/documentation/foundation/urlerror/2293357-unknown',
value: -1) value: -1),
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_UNKNOWN',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 0)
]) ])
static const UNKNOWN = WebResourceErrorType_._internal("UNKNOWN"); static const UNKNOWN = WebResourceErrorType_._internal("UNKNOWN");
@ -276,7 +296,12 @@ class WebResourceErrorType_ {
apiName: 'URLError.cancelled', apiName: 'URLError.cancelled',
apiUrl: apiUrl:
'https://developer.apple.com/documentation/foundation/urlerror/code/2883178-cancelled', 'https://developer.apple.com/documentation/foundation/urlerror/code/2883178-cancelled',
value: -999) value: -999),
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_OPERATION_CANCELED',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 14)
]) ])
static const CANCELLED = WebResourceErrorType_._internal("CANCELLED"); static const CANCELLED = WebResourceErrorType_._internal("CANCELLED");
@ -291,7 +316,12 @@ class WebResourceErrorType_ {
apiName: 'URLError.networkConnectionLost', apiName: 'URLError.networkConnectionLost',
apiUrl: apiUrl:
'https://developer.apple.com/documentation/foundation/urlerror/2293759-networkconnectionlost', 'https://developer.apple.com/documentation/foundation/urlerror/2293759-networkconnectionlost',
value: -1005) value: -1005),
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_DISCONNECTED',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 11)
]) ])
static const NETWORK_CONNECTION_LOST = static const NETWORK_CONNECTION_LOST =
WebResourceErrorType_._internal("NETWORK_CONNECTION_LOST"); WebResourceErrorType_._internal("NETWORK_CONNECTION_LOST");
@ -356,7 +386,12 @@ class WebResourceErrorType_ {
apiName: 'URLError.badServerResponse', apiName: 'URLError.badServerResponse',
apiUrl: apiUrl:
'https://developer.apple.com/documentation/foundation/urlerror/2293606-badserverresponse', 'https://developer.apple.com/documentation/foundation/urlerror/2293606-badserverresponse',
value: -1011) value: -1011),
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_ERROR_HTTP_INVALID_SERVER_RESPONSE',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 8)
]) ])
static const BAD_SERVER_RESPONSE = static const BAD_SERVER_RESPONSE =
WebResourceErrorType_._internal("BAD_SERVER_RESPONSE"); WebResourceErrorType_._internal("BAD_SERVER_RESPONSE");
@ -389,7 +424,12 @@ class WebResourceErrorType_ {
apiName: 'URLError.userAuthenticationRequired', apiName: 'URLError.userAuthenticationRequired',
apiUrl: apiUrl:
'https://developer.apple.com/documentation/foundation/urlerror/2293560-userauthenticationrequired', 'https://developer.apple.com/documentation/foundation/urlerror/2293560-userauthenticationrequired',
value: -1013) value: -1013),
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_VALID_AUTHENTICATION_CREDENTIALS_REQUIRED',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 17),
]) ])
static const USER_AUTHENTICATION_REQUIRED = static const USER_AUTHENTICATION_REQUIRED =
WebResourceErrorType_._internal("USER_AUTHENTICATION_REQUIRED"); WebResourceErrorType_._internal("USER_AUTHENTICATION_REQUIRED");
@ -892,4 +932,64 @@ class WebResourceErrorType_ {
]) ])
static const BACKGROUND_SESSION_WAS_DISCONNECTED = static const BACKGROUND_SESSION_WAS_DISCONNECTED =
WebResourceErrorType_._internal("BACKGROUND_SESSION_WAS_DISCONNECTED"); WebResourceErrorType_._internal("BACKGROUND_SESSION_WAS_DISCONNECTED");
///Indicates that the host is unreachable.
@EnumSupportedPlatforms(platforms: [
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_SERVER_UNREACHABLE',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 6),
])
static const SERVER_UNREACHABLE = WebResourceErrorType_._internal("SERVER_UNREACHABLE");
///Indicates that the connection was stopped.
@EnumSupportedPlatforms(platforms: [
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_CONNECTION_ABORTED',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 9)
])
static const CONNECTION_ABORTED = WebResourceErrorType_._internal("CONNECTION_ABORTED");
///Indicates that the connection was reset.
@EnumSupportedPlatforms(platforms: [
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_CONNECTION_RESET',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 10),
])
static const RESET = WebResourceErrorType_._internal("RESET");
///Indicates that the request redirect failed.
@EnumSupportedPlatforms(platforms: [
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_REDIRECT_FAILED',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 15),
])
static const REDIRECT_FAILED = WebResourceErrorType_._internal("REDIRECT_FAILED");
///Indicates that an unexpected error occurred.
@EnumSupportedPlatforms(platforms: [
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_UNEXPECTED_ERROR',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 16),
])
static const UNEXPECTED_ERROR = WebResourceErrorType_._internal("UNEXPECTED_ERROR");
///Indicates that user lacks proper authentication credentials for a proxy server.
@EnumSupportedPlatforms(platforms: [
EnumWindowsPlatform(
apiName: 'COREWEBVIEW2_WEB_ERROR_STATUS_VALID_PROXY_AUTHENTICATION_REQUIRED',
apiUrl:
'https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status',
value: 18),
])
static const VALID_PROXY_AUTHENTICATION_REQUIRED = WebResourceErrorType_._internal("VALID_PROXY_AUTHENTICATION_REQUIRED");
} }

View File

@ -97,6 +97,7 @@ class WebResourceErrorType {
///**Officially Supported Platforms/Implementations**: ///**Officially Supported Platforms/Implementations**:
///- iOS ([Official API - URLError.badServerResponse](https://developer.apple.com/documentation/foundation/urlerror/2293606-badserverresponse)) ///- iOS ([Official API - URLError.badServerResponse](https://developer.apple.com/documentation/foundation/urlerror/2293606-badserverresponse))
///- MacOS ([Official API - URLError.badServerResponse](https://developer.apple.com/documentation/foundation/urlerror/2293606-badserverresponse)) ///- MacOS ([Official API - URLError.badServerResponse](https://developer.apple.com/documentation/foundation/urlerror/2293606-badserverresponse))
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_ERROR_HTTP_INVALID_SERVER_RESPONSE](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final BAD_SERVER_RESPONSE = static final BAD_SERVER_RESPONSE =
WebResourceErrorType._internalMultiPlatform('BAD_SERVER_RESPONSE', () { WebResourceErrorType._internalMultiPlatform('BAD_SERVER_RESPONSE', () {
switch (defaultTargetPlatform) { switch (defaultTargetPlatform) {
@ -104,6 +105,8 @@ class WebResourceErrorType {
return -1011; return -1011;
case TargetPlatform.macOS: case TargetPlatform.macOS:
return -1011; return -1011;
case TargetPlatform.windows:
return 8;
default: default:
break; break;
} }
@ -154,6 +157,7 @@ class WebResourceErrorType {
///**Officially Supported Platforms/Implementations**: ///**Officially Supported Platforms/Implementations**:
///- iOS ([Official API - URLError.cancelled](https://developer.apple.com/documentation/foundation/urlerror/code/2883178-cancelled)) ///- iOS ([Official API - URLError.cancelled](https://developer.apple.com/documentation/foundation/urlerror/code/2883178-cancelled))
///- MacOS ([Official API - URLError.cancelled](https://developer.apple.com/documentation/foundation/urlerror/code/2883178-cancelled)) ///- MacOS ([Official API - URLError.cancelled](https://developer.apple.com/documentation/foundation/urlerror/code/2883178-cancelled))
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_OPERATION_CANCELED](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final CANCELLED = static final CANCELLED =
WebResourceErrorType._internalMultiPlatform('CANCELLED', () { WebResourceErrorType._internalMultiPlatform('CANCELLED', () {
switch (defaultTargetPlatform) { switch (defaultTargetPlatform) {
@ -161,6 +165,8 @@ class WebResourceErrorType {
return -999; return -999;
case TargetPlatform.macOS: case TargetPlatform.macOS:
return -999; return -999;
case TargetPlatform.windows:
return 14;
default: default:
break; break;
} }
@ -191,6 +197,7 @@ class WebResourceErrorType {
///- Android native WebView ([Official API - WebViewClient.ERROR_CONNECT](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_CONNECT)) ///- Android native WebView ([Official API - WebViewClient.ERROR_CONNECT](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_CONNECT))
///- iOS ([Official API - URLError.cannotConnectToHost](https://developer.apple.com/documentation/foundation/urlerror/code/2883001-cannotconnecttohost)) ///- iOS ([Official API - URLError.cannotConnectToHost](https://developer.apple.com/documentation/foundation/urlerror/code/2883001-cannotconnecttohost))
///- MacOS ([Official API - URLError.cannotConnectToHost](https://developer.apple.com/documentation/foundation/urlerror/code/2883001-cannotconnecttohost)) ///- MacOS ([Official API - URLError.cannotConnectToHost](https://developer.apple.com/documentation/foundation/urlerror/code/2883001-cannotconnecttohost))
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_CANNOT_CONNECT](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final CANNOT_CONNECT_TO_HOST = static final CANNOT_CONNECT_TO_HOST =
WebResourceErrorType._internalMultiPlatform('CANNOT_CONNECT_TO_HOST', () { WebResourceErrorType._internalMultiPlatform('CANNOT_CONNECT_TO_HOST', () {
switch (defaultTargetPlatform) { switch (defaultTargetPlatform) {
@ -200,6 +207,8 @@ class WebResourceErrorType {
return -1004; return -1004;
case TargetPlatform.macOS: case TargetPlatform.macOS:
return -1004; return -1004;
case TargetPlatform.windows:
return 12;
default: default:
break; break;
} }
@ -408,6 +417,21 @@ class WebResourceErrorType {
return null; return null;
}); });
///Indicates that the connection was stopped.
///
///**Officially Supported Platforms/Implementations**:
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_CONNECTION_ABORTED](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final CONNECTION_ABORTED =
WebResourceErrorType._internalMultiPlatform('CONNECTION_ABORTED', () {
switch (defaultTargetPlatform) {
case TargetPlatform.windows:
return 9;
default:
break;
}
return null;
});
///The length of the resource data exceeds the maximum allowed. ///The length of the resource data exceeds the maximum allowed.
/// ///
///**Officially Supported Platforms/Implementations**: ///**Officially Supported Platforms/Implementations**:
@ -558,6 +582,7 @@ class WebResourceErrorType {
///- Android native WebView ([Official API - WebViewClient.ERROR_HOST_LOOKUP](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_HOST_LOOKUP)) ///- Android native WebView ([Official API - WebViewClient.ERROR_HOST_LOOKUP](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_HOST_LOOKUP))
///- iOS ([Official API - URLError.cannotFindHost](https://developer.apple.com/documentation/foundation/urlerror/code/2883157-cannotfindhost)) ///- iOS ([Official API - URLError.cannotFindHost](https://developer.apple.com/documentation/foundation/urlerror/code/2883157-cannotfindhost))
///- MacOS ([Official API - URLError.cannotFindHost](https://developer.apple.com/documentation/foundation/urlerror/code/2883157-cannotfindhost)) ///- MacOS ([Official API - URLError.cannotFindHost](https://developer.apple.com/documentation/foundation/urlerror/code/2883157-cannotfindhost))
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_HOST_NAME_NOT_RESOLVED](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final HOST_LOOKUP = static final HOST_LOOKUP =
WebResourceErrorType._internalMultiPlatform('HOST_LOOKUP', () { WebResourceErrorType._internalMultiPlatform('HOST_LOOKUP', () {
switch (defaultTargetPlatform) { switch (defaultTargetPlatform) {
@ -567,6 +592,8 @@ class WebResourceErrorType {
return -1003; return -1003;
case TargetPlatform.macOS: case TargetPlatform.macOS:
return -1003; return -1003;
case TargetPlatform.windows:
return 13;
default: default:
break; break;
} }
@ -611,6 +638,7 @@ class WebResourceErrorType {
///**Officially Supported Platforms/Implementations**: ///**Officially Supported Platforms/Implementations**:
///- iOS ([Official API - URLError.networkConnectionLost](https://developer.apple.com/documentation/foundation/urlerror/2293759-networkconnectionlost)) ///- iOS ([Official API - URLError.networkConnectionLost](https://developer.apple.com/documentation/foundation/urlerror/2293759-networkconnectionlost))
///- MacOS ([Official API - URLError.networkConnectionLost](https://developer.apple.com/documentation/foundation/urlerror/2293759-networkconnectionlost)) ///- MacOS ([Official API - URLError.networkConnectionLost](https://developer.apple.com/documentation/foundation/urlerror/2293759-networkconnectionlost))
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_DISCONNECTED](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final NETWORK_CONNECTION_LOST = static final NETWORK_CONNECTION_LOST =
WebResourceErrorType._internalMultiPlatform('NETWORK_CONNECTION_LOST', WebResourceErrorType._internalMultiPlatform('NETWORK_CONNECTION_LOST',
() { () {
@ -619,6 +647,8 @@ class WebResourceErrorType {
return -1005; return -1005;
case TargetPlatform.macOS: case TargetPlatform.macOS:
return -1005; return -1005;
case TargetPlatform.windows:
return 11;
default: default:
break; break;
} }
@ -678,6 +708,21 @@ class WebResourceErrorType {
return null; return null;
}); });
///Indicates that the request redirect failed.
///
///**Officially Supported Platforms/Implementations**:
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_REDIRECT_FAILED](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final REDIRECT_FAILED =
WebResourceErrorType._internalMultiPlatform('REDIRECT_FAILED', () {
switch (defaultTargetPlatform) {
case TargetPlatform.windows:
return 15;
default:
break;
}
return null;
});
///A redirect was specified by way of server response code, but the server didnt accompany this code with a redirect URL. ///A redirect was specified by way of server response code, but the server didnt accompany this code with a redirect URL.
/// ///
///**Officially Supported Platforms/Implementations**: ///**Officially Supported Platforms/Implementations**:
@ -716,6 +761,20 @@ class WebResourceErrorType {
return null; return null;
}); });
///Indicates that the connection was reset.
///
///**Officially Supported Platforms/Implementations**:
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_CONNECTION_RESET](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final RESET = WebResourceErrorType._internalMultiPlatform('RESET', () {
switch (defaultTargetPlatform) {
case TargetPlatform.windows:
return 10;
default:
break;
}
return null;
});
///A requested resource couldn't be retrieved. ///A requested resource couldn't be retrieved.
///This error can indicate a file-not-found situation, or decoding problems that prevent data from being processed correctly. ///This error can indicate a file-not-found situation, or decoding problems that prevent data from being processed correctly.
/// ///
@ -830,12 +889,28 @@ class WebResourceErrorType {
return null; return null;
}); });
///Indicates that the host is unreachable.
///
///**Officially Supported Platforms/Implementations**:
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_SERVER_UNREACHABLE](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final SERVER_UNREACHABLE =
WebResourceErrorType._internalMultiPlatform('SERVER_UNREACHABLE', () {
switch (defaultTargetPlatform) {
case TargetPlatform.windows:
return 6;
default:
break;
}
return null;
});
///Connection timed out. ///Connection timed out.
/// ///
///**Officially Supported Platforms/Implementations**: ///**Officially Supported Platforms/Implementations**:
///- Android native WebView ([Official API - WebViewClient.ERROR_TIMEOUT](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_TIMEOUT)) ///- Android native WebView ([Official API - WebViewClient.ERROR_TIMEOUT](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_TIMEOUT))
///- iOS ([Official API - URLError.timedOut](https://developer.apple.com/documentation/foundation/urlerror/code/2883027-timedout)) ///- iOS ([Official API - URLError.timedOut](https://developer.apple.com/documentation/foundation/urlerror/code/2883027-timedout))
///- MacOS ([Official API - URLError.timedOut](https://developer.apple.com/documentation/foundation/urlerror/code/2883027-timedout)) ///- MacOS ([Official API - URLError.timedOut](https://developer.apple.com/documentation/foundation/urlerror/code/2883027-timedout))
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_TIMEOUT](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final TIMEOUT = static final TIMEOUT =
WebResourceErrorType._internalMultiPlatform('TIMEOUT', () { WebResourceErrorType._internalMultiPlatform('TIMEOUT', () {
switch (defaultTargetPlatform) { switch (defaultTargetPlatform) {
@ -845,6 +920,8 @@ class WebResourceErrorType {
return -1001; return -1001;
case TargetPlatform.macOS: case TargetPlatform.macOS:
return -1001; return -1001;
case TargetPlatform.windows:
return 7;
default: default:
break; break;
} }
@ -887,12 +964,28 @@ class WebResourceErrorType {
return null; return null;
}); });
///Indicates that an unexpected error occurred.
///
///**Officially Supported Platforms/Implementations**:
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_UNEXPECTED_ERROR](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final UNEXPECTED_ERROR =
WebResourceErrorType._internalMultiPlatform('UNEXPECTED_ERROR', () {
switch (defaultTargetPlatform) {
case TargetPlatform.windows:
return 16;
default:
break;
}
return null;
});
///The URL Loading System encountered an error that it cant interpret. ///The URL Loading System encountered an error that it cant interpret.
/// ///
///**Officially Supported Platforms/Implementations**: ///**Officially Supported Platforms/Implementations**:
///- Android native WebView ([Official API - WebViewClient.ERROR_UNKNOWN](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_UNKNOWN)) ///- Android native WebView ([Official API - WebViewClient.ERROR_UNKNOWN](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_UNKNOWN))
///- iOS ([Official API - URLError.unknown](https://developer.apple.com/documentation/foundation/urlerror/2293357-unknown)) ///- iOS ([Official API - URLError.unknown](https://developer.apple.com/documentation/foundation/urlerror/2293357-unknown))
///- MacOS ([Official API - URLError.unknown](https://developer.apple.com/documentation/foundation/urlerror/2293357-unknown)) ///- MacOS ([Official API - URLError.unknown](https://developer.apple.com/documentation/foundation/urlerror/2293357-unknown))
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_UNKNOWN](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final UNKNOWN = static final UNKNOWN =
WebResourceErrorType._internalMultiPlatform('UNKNOWN', () { WebResourceErrorType._internalMultiPlatform('UNKNOWN', () {
switch (defaultTargetPlatform) { switch (defaultTargetPlatform) {
@ -902,6 +995,8 @@ class WebResourceErrorType {
return -1; return -1;
case TargetPlatform.macOS: case TargetPlatform.macOS:
return -1; return -1;
case TargetPlatform.windows:
return 0;
default: default:
break; break;
} }
@ -982,6 +1077,7 @@ class WebResourceErrorType {
///**Officially Supported Platforms/Implementations**: ///**Officially Supported Platforms/Implementations**:
///- iOS ([Official API - URLError.userAuthenticationRequired](https://developer.apple.com/documentation/foundation/urlerror/2293560-userauthenticationrequired)) ///- iOS ([Official API - URLError.userAuthenticationRequired](https://developer.apple.com/documentation/foundation/urlerror/2293560-userauthenticationrequired))
///- MacOS ([Official API - URLError.userAuthenticationRequired](https://developer.apple.com/documentation/foundation/urlerror/2293560-userauthenticationrequired)) ///- MacOS ([Official API - URLError.userAuthenticationRequired](https://developer.apple.com/documentation/foundation/urlerror/2293560-userauthenticationrequired))
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_VALID_AUTHENTICATION_CREDENTIALS_REQUIRED](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final USER_AUTHENTICATION_REQUIRED = static final USER_AUTHENTICATION_REQUIRED =
WebResourceErrorType._internalMultiPlatform( WebResourceErrorType._internalMultiPlatform(
'USER_AUTHENTICATION_REQUIRED', () { 'USER_AUTHENTICATION_REQUIRED', () {
@ -990,6 +1086,8 @@ class WebResourceErrorType {
return -1013; return -1013;
case TargetPlatform.macOS: case TargetPlatform.macOS:
return -1013; return -1013;
case TargetPlatform.windows:
return 17;
default: default:
break; break;
} }
@ -1016,6 +1114,22 @@ class WebResourceErrorType {
return null; return null;
}); });
///Indicates that user lacks proper authentication credentials for a proxy server.
///
///**Officially Supported Platforms/Implementations**:
///- Windows ([Official API - COREWEBVIEW2_WEB_ERROR_STATUS_VALID_PROXY_AUTHENTICATION_REQUIRED](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?view=webview2-1.0.2210.55#corewebview2_web_error_status))
static final VALID_PROXY_AUTHENTICATION_REQUIRED =
WebResourceErrorType._internalMultiPlatform(
'VALID_PROXY_AUTHENTICATION_REQUIRED', () {
switch (defaultTargetPlatform) {
case TargetPlatform.windows:
return 18;
default:
break;
}
return null;
});
///A server reported that a URL has a non-zero content length, but terminated the network connection gracefully without sending any data. ///A server reported that a URL has a non-zero content length, but terminated the network connection gracefully without sending any data.
/// ///
///**Officially Supported Platforms/Implementations**: ///**Officially Supported Platforms/Implementations**:
@ -1057,6 +1171,7 @@ class WebResourceErrorType {
WebResourceErrorType.CANNOT_WRITE_TO_FILE, WebResourceErrorType.CANNOT_WRITE_TO_FILE,
WebResourceErrorType.CLIENT_CERTIFICATE_REJECTED, WebResourceErrorType.CLIENT_CERTIFICATE_REJECTED,
WebResourceErrorType.CLIENT_CERTIFICATE_REQUIRED, WebResourceErrorType.CLIENT_CERTIFICATE_REQUIRED,
WebResourceErrorType.CONNECTION_ABORTED,
WebResourceErrorType.DATA_LENGTH_EXCEEDS_MAXIMUM, WebResourceErrorType.DATA_LENGTH_EXCEEDS_MAXIMUM,
WebResourceErrorType.DATA_NOT_ALLOWED, WebResourceErrorType.DATA_NOT_ALLOWED,
WebResourceErrorType.DOWNLOAD_DECODING_FAILED_MID_STREAM, WebResourceErrorType.DOWNLOAD_DECODING_FAILED_MID_STREAM,
@ -1072,17 +1187,21 @@ class WebResourceErrorType {
WebResourceErrorType.NOT_CONNECTED_TO_INTERNET, WebResourceErrorType.NOT_CONNECTED_TO_INTERNET,
WebResourceErrorType.NO_PERMISSIONS_TO_READ_FILE, WebResourceErrorType.NO_PERMISSIONS_TO_READ_FILE,
WebResourceErrorType.PROXY_AUTHENTICATION, WebResourceErrorType.PROXY_AUTHENTICATION,
WebResourceErrorType.REDIRECT_FAILED,
WebResourceErrorType.REDIRECT_TO_NON_EXISTENT_LOCATION, WebResourceErrorType.REDIRECT_TO_NON_EXISTENT_LOCATION,
WebResourceErrorType.REQUEST_BODY_STREAM_EXHAUSTED, WebResourceErrorType.REQUEST_BODY_STREAM_EXHAUSTED,
WebResourceErrorType.RESET,
WebResourceErrorType.RESOURCE_UNAVAILABLE, WebResourceErrorType.RESOURCE_UNAVAILABLE,
WebResourceErrorType.SECURE_CONNECTION_FAILED, WebResourceErrorType.SECURE_CONNECTION_FAILED,
WebResourceErrorType.SERVER_CERTIFICATE_HAS_BAD_DATE, WebResourceErrorType.SERVER_CERTIFICATE_HAS_BAD_DATE,
WebResourceErrorType.SERVER_CERTIFICATE_HAS_UNKNOWN_ROOT, WebResourceErrorType.SERVER_CERTIFICATE_HAS_UNKNOWN_ROOT,
WebResourceErrorType.SERVER_CERTIFICATE_NOT_YET_VALID, WebResourceErrorType.SERVER_CERTIFICATE_NOT_YET_VALID,
WebResourceErrorType.SERVER_CERTIFICATE_UNTRUSTED, WebResourceErrorType.SERVER_CERTIFICATE_UNTRUSTED,
WebResourceErrorType.SERVER_UNREACHABLE,
WebResourceErrorType.TIMEOUT, WebResourceErrorType.TIMEOUT,
WebResourceErrorType.TOO_MANY_REDIRECTS, WebResourceErrorType.TOO_MANY_REDIRECTS,
WebResourceErrorType.TOO_MANY_REQUESTS, WebResourceErrorType.TOO_MANY_REQUESTS,
WebResourceErrorType.UNEXPECTED_ERROR,
WebResourceErrorType.UNKNOWN, WebResourceErrorType.UNKNOWN,
WebResourceErrorType.UNSAFE_RESOURCE, WebResourceErrorType.UNSAFE_RESOURCE,
WebResourceErrorType.UNSUPPORTED_AUTH_SCHEME, WebResourceErrorType.UNSUPPORTED_AUTH_SCHEME,
@ -1090,6 +1209,7 @@ class WebResourceErrorType {
WebResourceErrorType.USER_AUTHENTICATION_FAILED, WebResourceErrorType.USER_AUTHENTICATION_FAILED,
WebResourceErrorType.USER_AUTHENTICATION_REQUIRED, WebResourceErrorType.USER_AUTHENTICATION_REQUIRED,
WebResourceErrorType.USER_CANCELLED_AUTHENTICATION, WebResourceErrorType.USER_CANCELLED_AUTHENTICATION,
WebResourceErrorType.VALID_PROXY_AUTHENTICATION_REQUIRED,
WebResourceErrorType.ZERO_BYTE_RESOURCE, WebResourceErrorType.ZERO_BYTE_RESOURCE,
].toSet(); ].toSet();

View File

@ -65,7 +65,7 @@ class WindowsInAppBrowser extends PlatformInAppBrowser with ChannelController {
return _staticValue; return _staticValue;
} }
WindowsInAppBrowserCreationParams get _macosParams => WindowsInAppBrowserCreationParams get _windowsParams =>
params as WindowsInAppBrowserCreationParams; params as WindowsInAppBrowserCreationParams;
static const MethodChannel _staticChannel = static const MethodChannel _staticChannel =
@ -95,7 +95,7 @@ class WindowsInAppBrowser extends PlatformInAppBrowser with ChannelController {
channel!, channel!,
this, this,
this.initialUserScripts); this.initialUserScripts);
_macosParams.findInteractionController?.init(id); _windowsParams.findInteractionController?.init(id);
} }
_debugLog(String method, dynamic args) { _debugLog(String method, dynamic args) {

View File

@ -49,12 +49,11 @@ add_custom_command(
# Any new source files that you add to the plugin should be added here. # Any new source files that you add to the plugin should be added here.
list(APPEND PLUGIN_SOURCES list(APPEND PLUGIN_SOURCES
"flutter_inappwebview_windows_base_plugin.h"
"flutter_inappwebview_windows_base_plugin.cpp"
"flutter_inappwebview_windows_plugin.cpp" "flutter_inappwebview_windows_plugin.cpp"
"flutter_inappwebview_windows_plugin.h" "flutter_inappwebview_windows_plugin.h"
"utils/strconv.h" "utils/strconv.h"
"utils/util.h" "utils/util.h"
"utils/flutter.h"
"types/channel_delegate.cpp" "types/channel_delegate.cpp"
"types/channel_delegate.h" "types/channel_delegate.h"
"types/base_callback_result.h" "types/base_callback_result.h"
@ -62,6 +61,12 @@ list(APPEND PLUGIN_SOURCES
"types/url_request.h" "types/url_request.h"
"types/navigation_action.cpp" "types/navigation_action.cpp"
"types/navigation_action.h" "types/navigation_action.h"
"types/web_resource_error.cpp"
"types/web_resource_error.h"
"types/web_resource_request.cpp"
"types/web_resource_request.h"
"types/web_resource_response.cpp"
"types/web_resource_response.h"
"in_app_webview/in_app_webview.cpp" "in_app_webview/in_app_webview.cpp"
"in_app_webview/in_app_webview.h" "in_app_webview/in_app_webview.h"
"in_app_webview/webview_channel_delegate.cpp" "in_app_webview/webview_channel_delegate.cpp"

View File

@ -1,14 +0,0 @@
#include "flutter_inappwebview_windows_base_plugin.h"
namespace flutter_inappwebview_plugin
{
FlutterInappwebviewWindowsBasePlugin::FlutterInappwebviewWindowsBasePlugin(flutter::PluginRegistrarWindows* registrar) : registrar(registrar)
{
}
FlutterInappwebviewWindowsBasePlugin::~FlutterInappwebviewWindowsBasePlugin()
{
}
}

View File

@ -1,18 +0,0 @@
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_BASE_PLUGIN_H_
#define FLUTTER_INAPPWEBVIEW_PLUGIN_BASE_PLUGIN_H_
#include <flutter/plugin_registrar_windows.h>
namespace flutter_inappwebview_plugin
{
class FlutterInappwebviewWindowsBasePlugin : public flutter::Plugin, public std::enable_shared_from_this<FlutterInappwebviewWindowsBasePlugin> {
public:
flutter::PluginRegistrarWindows* registrar;
FlutterInappwebviewWindowsBasePlugin(flutter::PluginRegistrarWindows* registrar);
virtual ~FlutterInappwebviewWindowsBasePlugin();
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_BASE_PLUGIN_H_

View File

@ -3,6 +3,8 @@
#include <flutter/method_channel.h> #include <flutter/method_channel.h>
#include <flutter/plugin_registrar_windows.h> #include <flutter/plugin_registrar_windows.h>
#include "in_app_browser/in_app_browser_manager.h"
namespace flutter_inappwebview_plugin namespace flutter_inappwebview_plugin
{ {
// static // static
@ -13,7 +15,7 @@ namespace flutter_inappwebview_plugin
} }
FlutterInappwebviewWindowsPlugin::FlutterInappwebviewWindowsPlugin(flutter::PluginRegistrarWindows* registrar) FlutterInappwebviewWindowsPlugin::FlutterInappwebviewWindowsPlugin(flutter::PluginRegistrarWindows* registrar)
: FlutterInappwebviewWindowsBasePlugin(registrar) : registrar(registrar)
{ {
inAppBrowserManager = std::make_unique<InAppBrowserManager>(this); inAppBrowserManager = std::make_unique<InAppBrowserManager>(this);
} }

View File

@ -4,16 +4,13 @@
#include <flutter/method_channel.h> #include <flutter/method_channel.h>
#include <flutter/plugin_registrar_windows.h> #include <flutter/plugin_registrar_windows.h>
#include <memory>
#include "flutter_inappwebview_windows_base_plugin.h"
#include "in_app_browser/in_app_browser_manager.h"
namespace flutter_inappwebview_plugin namespace flutter_inappwebview_plugin
{ {
class FlutterInappwebviewWindowsPlugin : public FlutterInappwebviewWindowsBasePlugin { class InAppBrowserManager;
class FlutterInappwebviewWindowsPlugin : public flutter::Plugin {
public: public:
flutter::PluginRegistrarWindows* registrar;
std::unique_ptr<InAppBrowserManager> inAppBrowserManager; std::unique_ptr<InAppBrowserManager> inAppBrowserManager;
static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar); static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar);

View File

@ -1,33 +1,11 @@
#include <Windows.h> #include <Windows.h>
#include "in_app_browser.h" #include "in_app_browser.h"
#include <cstdint>
#include <memory>
#include "flutter/event_channel.h"
#include "flutter/plugin_registrar.h"
#include "flutter/plugin_registrar_windows.h"
#include "flutter/method_channel.h"
#include "flutter/encodable_value.h"
#include <stdlib.h>
#include <string>
#include <tchar.h>
#include <wil/wrl.h>
#include <wil/com.h>
#include "../utils/strconv.h"
#include "../utils/util.h" #include "../utils/util.h"
#include "in_app_browser_manager.h"
#include <WebView2.h>
#include <WebView2EnvironmentOptions.h>
namespace flutter_inappwebview_plugin namespace flutter_inappwebview_plugin
{ {
using namespace Microsoft::WRL; InAppBrowser::InAppBrowser(FlutterInappwebviewWindowsPlugin* plugin, const InAppBrowserCreationParams& params)
const wchar_t* CLASS_NAME = L"InAppBrowser";
InAppBrowser::InAppBrowser(FlutterInappwebviewWindowsBasePlugin* plugin, const InAppBrowserCreationParams& params)
: plugin(plugin), : plugin(plugin),
m_hInstance(GetModuleHandle(nullptr)), m_hInstance(GetModuleHandle(nullptr)),
id(params.id), id(params.id),
@ -35,7 +13,7 @@ namespace flutter_inappwebview_plugin
channelDelegate(std::make_unique<InAppBrowserChannelDelegate>(id, plugin->registrar->messenger())) channelDelegate(std::make_unique<InAppBrowserChannelDelegate>(id, plugin->registrar->messenger()))
{ {
WNDCLASS wndClass = {}; WNDCLASS wndClass = {};
wndClass.lpszClassName = CLASS_NAME; wndClass.lpszClassName = InAppBrowser::CLASS_NAME;
wndClass.hInstance = m_hInstance; wndClass.hInstance = m_hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
@ -45,8 +23,8 @@ namespace flutter_inappwebview_plugin
m_hWnd = CreateWindowEx( m_hWnd = CreateWindowEx(
0, // Optional window styles. 0, // Optional window styles.
CLASS_NAME, // Window class InAppBrowser::CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text L"", // Window text
WS_OVERLAPPEDWINDOW, // Window style WS_OVERLAPPEDWINDOW, // Window style
// Size and position // Size and position
@ -186,15 +164,19 @@ namespace flutter_inappwebview_plugin
) noexcept { ) noexcept {
switch (message) { switch (message) {
case WM_DESTROY: { case WM_DESTROY: {
webView.reset();
// might receive multiple WM_DESTROY messages. // might receive multiple WM_DESTROY messages.
if (!destroyed_) { if (!destroyed_) {
destroyed_ = true; destroyed_ = true;
webView.reset();
if (channelDelegate) { if (channelDelegate) {
channelDelegate->onExit(); channelDelegate->onExit();
} }
if (plugin && plugin->inAppBrowserManager) {
plugin->inAppBrowserManager->browsers.erase(id);
}
} }
return 0; return 0;
} }

View File

@ -6,7 +6,7 @@
#include <optional> #include <optional>
#include <wil/com.h> #include <wil/com.h>
#include "../flutter_inappwebview_windows_base_plugin.h" #include "../flutter_inappwebview_windows_plugin.h"
#include "../in_app_webview/in_app_webview.h" #include "../in_app_webview/in_app_webview.h"
#include "../types/url_request.h" #include "../types/url_request.h"
#include "in_app_browser_channel_delegate.h" #include "in_app_browser_channel_delegate.h"
@ -22,19 +22,20 @@ namespace flutter_inappwebview_plugin
class InAppBrowser { class InAppBrowser {
public: public:
static inline const std::string METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappbrowser_"; static inline const std::string METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappbrowser_";
static inline const wchar_t* CLASS_NAME = L"InAppBrowser";
static LRESULT CALLBACK WndProc(HWND window, static LRESULT CALLBACK WndProc(HWND window,
UINT message, UINT message,
WPARAM wparam, WPARAM wparam,
LPARAM lparam) noexcept; LPARAM lparam) noexcept;
FlutterInappwebviewWindowsBasePlugin* plugin; FlutterInappwebviewWindowsPlugin* plugin;
std::string id; std::string id;
std::optional<URLRequest> initialUrlRequest; std::optional<URLRequest> initialUrlRequest;
std::unique_ptr<InAppWebView> webView; std::unique_ptr<InAppWebView> webView;
std::unique_ptr<InAppBrowserChannelDelegate> channelDelegate; std::unique_ptr<InAppBrowserChannelDelegate> channelDelegate;
InAppBrowser(FlutterInappwebviewWindowsBasePlugin* plugin, const InAppBrowserCreationParams& params); InAppBrowser(FlutterInappwebviewWindowsPlugin* plugin, const InAppBrowserCreationParams& params);
~InAppBrowser(); ~InAppBrowser();
private: private:

View File

@ -5,7 +5,7 @@
namespace flutter_inappwebview_plugin namespace flutter_inappwebview_plugin
{ {
InAppBrowserChannelDelegate::InAppBrowserChannelDelegate(const std::string id, flutter::BinaryMessenger* messenger) InAppBrowserChannelDelegate::InAppBrowserChannelDelegate(const std::string& id, flutter::BinaryMessenger* messenger)
: ChannelDelegate(messenger, InAppBrowser::METHOD_CHANNEL_NAME_PREFIX + id) : ChannelDelegate(messenger, InAppBrowser::METHOD_CHANNEL_NAME_PREFIX + id)
{ {

View File

@ -11,7 +11,7 @@ namespace flutter_inappwebview_plugin
class InAppBrowserChannelDelegate : public ChannelDelegate class InAppBrowserChannelDelegate : public ChannelDelegate
{ {
public: public:
InAppBrowserChannelDelegate(const std::string id, flutter::BinaryMessenger* messenger); InAppBrowserChannelDelegate(const std::string& id, flutter::BinaryMessenger* messenger);
~InAppBrowserChannelDelegate(); ~InAppBrowserChannelDelegate();
void HandleMethodCall( void HandleMethodCall(

View File

@ -1,16 +1,17 @@
#include <memory> #include <memory>
#include <flutter/method_channel.h> #include <flutter/method_channel.h>
#include <flutter/standard_method_codec.h> #include <flutter/standard_method_codec.h>
#include <optional>
#include "in_app_browser_manager.h" #include "in_app_browser_manager.h"
#include "../types/url_request.h" #include "../types/url_request.h"
#include "../utils/util.h" #include "../utils/flutter.h"
namespace flutter_inappwebview_plugin namespace flutter_inappwebview_plugin
{ {
InAppBrowserManager::InAppBrowserManager(FlutterInappwebviewWindowsBasePlugin* plugin) InAppBrowserManager::InAppBrowserManager(FlutterInappwebviewWindowsPlugin* plugin)
: plugin(plugin), ChannelDelegate(plugin->registrar->messenger(), InAppBrowserManager::METHOD_CHANNEL_NAME) : plugin(plugin), ChannelDelegate(plugin->registrar->messenger(), InAppBrowserManager::METHOD_CHANNEL_NAME)
{ {
@ -31,16 +32,16 @@ namespace flutter_inappwebview_plugin
void InAppBrowserManager::open(const flutter::EncodableMap* arguments) void InAppBrowserManager::open(const flutter::EncodableMap* arguments)
{ {
auto id = std::get<std::string>(arguments->at(flutter::EncodableValue("id"))); auto id = get_fl_map_value<std::string>(*arguments, "id");
auto urlRequestMap = std::get_if<flutter::EncodableMap>(&arguments->at(flutter::EncodableValue("urlRequest"))); auto urlRequestMap = get_optional_fl_map_value<flutter::EncodableMap>(*arguments, "urlRequest");
auto urlRequest = make_pointer_optional<URLRequest>(new URLRequest(*urlRequestMap)); std::optional<URLRequest> urlRequest = urlRequestMap.has_value() ? std::make_optional<URLRequest>(urlRequestMap.value()) : std::optional<URLRequest>{};
InAppBrowserCreationParams params = { InAppBrowserCreationParams params = {
id, id,
urlRequest urlRequest
}; };
auto inAppBrowser = std::make_unique<InAppBrowser>(plugin, params); auto inAppBrowser = std::make_unique<InAppBrowser>(plugin, params);
browsers[id] = std::move(inAppBrowser); browsers.insert({ id, std::move(inAppBrowser) });
} }
InAppBrowserManager::~InAppBrowserManager() InAppBrowserManager::~InAppBrowserManager()

View File

@ -6,7 +6,7 @@
#include <flutter/method_channel.h> #include <flutter/method_channel.h>
#include <flutter/standard_message_codec.h> #include <flutter/standard_message_codec.h>
#include "../flutter_inappwebview_windows_base_plugin.h" #include "../flutter_inappwebview_windows_plugin.h"
#include "in_app_browser.h" #include "in_app_browser.h"
@ -19,10 +19,10 @@ namespace flutter_inappwebview_plugin
public: public:
static inline const std::string METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappbrowser"; static inline const std::string METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappbrowser";
FlutterInappwebviewWindowsBasePlugin* plugin; FlutterInappwebviewWindowsPlugin* plugin;
std::map<std::string, std::unique_ptr<InAppBrowser>> browsers; std::map<std::string, std::unique_ptr<InAppBrowser>> browsers;
InAppBrowserManager(FlutterInappwebviewWindowsBasePlugin* plugin); InAppBrowserManager(FlutterInappwebviewWindowsPlugin* plugin);
~InAppBrowserManager(); ~InAppBrowserManager();
void HandleMethodCall( void HandleMethodCall(

View File

@ -6,18 +6,20 @@
#include <Shlwapi.h> #include <Shlwapi.h>
#include "../utils/strconv.h" #include "../utils/strconv.h"
#include "../utils/util.h" #include "../utils/util.h"
#include "../types/web_resource_request.h"
#include "../types/web_resource_error.h"
namespace flutter_inappwebview_plugin namespace flutter_inappwebview_plugin
{ {
using namespace Microsoft::WRL; using namespace Microsoft::WRL;
InAppWebView::InAppWebView(FlutterInappwebviewWindowsBasePlugin* plugin, std::variant<std::string, int> id, const HWND parentWindow, const std::function<void()> completionHandler) InAppWebView::InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant<std::string, int>& id, const HWND parentWindow, const std::function<void()> completionHandler)
: plugin(plugin), id(id), channelDelegate(std::make_unique<WebViewChannelDelegate>(this, plugin->registrar->messenger())) : plugin(plugin), id(id), channelDelegate(std::make_unique<WebViewChannelDelegate>(this, plugin->registrar->messenger()))
{ {
createWebView(parentWindow, completionHandler); createWebView(parentWindow, completionHandler);
} }
InAppWebView::InAppWebView(FlutterInappwebviewWindowsBasePlugin* plugin, std::variant<std::string, int> id, const HWND parentWindow, const std::string& channelName, const std::function<void()> completionHandler) InAppWebView::InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant<std::string, int>& id, const HWND parentWindow, const std::string& channelName, const std::function<void()> completionHandler)
: plugin(plugin), id(id), channelDelegate(std::make_unique<WebViewChannelDelegate>(this, plugin->registrar->messenger(), channelName)) : plugin(plugin), id(id), channelDelegate(std::make_unique<WebViewChannelDelegate>(this, plugin->registrar->messenger(), channelName))
{ {
createWebView(parentWindow, completionHandler); createWebView(parentWindow, completionHandler);
@ -29,7 +31,7 @@ namespace flutter_inappwebview_plugin
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>( Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
[parentWindow, completionHandler, this](HRESULT result, ICoreWebView2Environment* env) -> HRESULT { [parentWindow, completionHandler, this](HRESULT result, ICoreWebView2Environment* env) -> HRESULT {
webViewEnv = env; webViewEnv = env;
// Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd // Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window HWND
env->CreateCoreWebView2Controller(parentWindow, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>( env->CreateCoreWebView2Controller(parentWindow, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
[parentWindow, completionHandler, this](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT { [parentWindow, completionHandler, this](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT {
if (controller != nullptr) { if (controller != nullptr) {
@ -67,9 +69,9 @@ namespace flutter_inappwebview_plugin
} }
wil::unique_cotaskmem_string uri = nullptr; wil::unique_cotaskmem_string uri = nullptr;
std::optional<std::string> url = SUCCEEDED(args->get_Uri(&uri)) ? wide_to_utf8(std::wstring(uri.get())) : std::optional<std::string>{}; std::optional<std::string> url = SUCCEEDED(args->get_Uri(&uri)) ? wide_to_utf8(uri.get()) : std::optional<std::string>{};
wil::unique_cotaskmem_string method = nullptr; wil::unique_cotaskmem_string requestMethod = nullptr;
wil::com_ptr<ICoreWebView2HttpRequestHeaders> requestHeaders = nullptr; wil::com_ptr<ICoreWebView2HttpRequestHeaders> requestHeaders = nullptr;
std::optional<std::map<std::string, std::string>> headers = std::optional<std::map<std::string, std::string>>{}; std::optional<std::map<std::string, std::string>> headers = std::optional<std::map<std::string, std::string>>{};
if (SUCCEEDED(args->get_RequestHeaders(&requestHeaders))) { if (SUCCEEDED(args->get_RequestHeaders(&requestHeaders))) {
@ -83,27 +85,34 @@ namespace flutter_inappwebview_plugin
wil::unique_cotaskmem_string value; wil::unique_cotaskmem_string value;
if (SUCCEEDED(iterator->GetCurrentHeader(&name, &value))) { if (SUCCEEDED(iterator->GetCurrentHeader(&name, &value))) {
headers->insert({ wide_to_utf8(std::wstring(name.get())), wide_to_utf8(std::wstring(value.get())) }); headers->insert({ wide_to_utf8(name.get()), wide_to_utf8(value.get()) });
} }
BOOL hasNext = FALSE; BOOL hasNext = FALSE;
iterator->MoveNext(&hasNext); iterator->MoveNext(&hasNext);
} }
requestHeaders->GetHeader(L"Flutter-InAppWebView-Request-Method", &method); requestHeaders->GetHeader(L"Flutter-InAppWebView-Request-Method", &requestMethod);
requestHeaders->RemoveHeader(L"Flutter-InAppWebView-Request-Method"); requestHeaders->RemoveHeader(L"Flutter-InAppWebView-Request-Method");
} }
if (callShouldOverrideUrlLoading && method == nullptr) { std::optional<std::string> method = requestMethod ? wide_to_utf8(requestMethod.get()) : std::optional<std::string>{};
// for some reason, we can't cancel and load an URL with other HTTP methods other than GET,
// so ignore the shouldOverrideUrlLoading event.
auto urlRequest = std::make_shared<URLRequest>(url, std::nullopt, headers, std::nullopt); auto urlRequest = std::make_shared<URLRequest>(url, method, headers, std::nullopt);
auto navigationAction = std::make_unique<NavigationAction>( auto navigationAction = std::make_shared<NavigationAction>(
urlRequest, urlRequest,
true true
); );
UINT64 navigationId;
if (SUCCEEDED(args->get_NavigationId(&navigationId))) {
navigationActions.insert({navigationId, navigationAction});
}
if (callShouldOverrideUrlLoading && requestMethod == nullptr) {
// for some reason, we can't cancel and load an URL with other HTTP methods than GET,
// so ignore the shouldOverrideUrlLoading event.
auto callback = std::make_unique<WebViewChannelDelegate::ShouldOverrideUrlLoadingCallback>(); auto callback = std::make_unique<WebViewChannelDelegate::ShouldOverrideUrlLoadingCallback>();
callback->nonNullSuccess = [this, urlRequest](const NavigationActionPolicy actionPolicy) { callback->nonNullSuccess = [this, urlRequest](const NavigationActionPolicy actionPolicy) {
callShouldOverrideUrlLoading = false; callShouldOverrideUrlLoading = false;
@ -137,9 +146,17 @@ namespace flutter_inappwebview_plugin
webView->add_NavigationCompleted( webView->add_NavigationCompleted(
Callback<ICoreWebView2NavigationCompletedEventHandler>( Callback<ICoreWebView2NavigationCompletedEventHandler>(
[this](ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args) { [this](ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args) {
COREWEBVIEW2_WEB_ERROR_STATUS web_error_status; std::shared_ptr<NavigationAction> navigationAction;
args->get_WebErrorStatus(&web_error_status); UINT64 navigationId;
debugLog("WebErrorStatus " + std::to_string(web_error_status) + "\n"); if (SUCCEEDED(args->get_NavigationId(&navigationId))) {
navigationAction = map_at_or_null(navigationActions, navigationId);
if (navigationAction) {
navigationActions.erase(navigationId);
}
}
COREWEBVIEW2_WEB_ERROR_STATUS webErrorType = COREWEBVIEW2_WEB_ERROR_STATUS_UNKNOWN;
args->get_WebErrorStatus(&webErrorType);
BOOL isSuccess; BOOL isSuccess;
args->get_IsSuccess(&isSuccess); args->get_IsSuccess(&isSuccess);
@ -150,7 +167,21 @@ namespace flutter_inappwebview_plugin
if (isSuccess) { if (isSuccess) {
channelDelegate->onLoadStop(url); channelDelegate->onLoadStop(url);
} }
else if (!InAppWebView::isSslError(webErrorType) && navigationAction) {
auto webResourceRequest = std::make_unique<WebResourceRequest>(url, navigationAction->request->method, navigationAction->request->headers, navigationAction->isForMainFrame);
int httpStatusCode = 0;
wil::com_ptr<ICoreWebView2NavigationCompletedEventArgs2> args2;
if (SUCCEEDED(args->QueryInterface(IID_PPV_ARGS(&args2))) && SUCCEEDED(args2->get_HttpStatusCode(&httpStatusCode)) && httpStatusCode >= 400) {
auto webResourceResponse = std::make_unique<WebResourceResponse>(httpStatusCode);
channelDelegate->onReceivedHttpError(std::move(webResourceRequest), std::move(webResourceResponse));
} }
else if (httpStatusCode < 400) {
auto webResourceError = std::make_unique<WebResourceError>(WebErrorStatusDescription[webErrorType], webErrorType);
channelDelegate->onReceivedError(std::move(webResourceRequest), std::move(webResourceError));
}
}
}
return S_OK; return S_OK;
} }
).Get(), nullptr); ).Get(), nullptr);
@ -159,10 +190,10 @@ namespace flutter_inappwebview_plugin
std::optional<std::string> InAppWebView::getUrl() const std::optional<std::string> InAppWebView::getUrl() const
{ {
LPWSTR uri = nullptr; LPWSTR uri = nullptr;
return SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(std::wstring(uri)) : std::optional<std::string>{}; return SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(uri) : std::optional<std::string>{};
} }
void InAppWebView::loadUrl(const URLRequest urlRequest) const void InAppWebView::loadUrl(const URLRequest& urlRequest) const
{ {
if (!webView || !urlRequest.url.has_value()) { if (!webView || !urlRequest.url.has_value()) {
return; return;
@ -191,7 +222,7 @@ namespace flutter_inappwebview_plugin
); );
wil::com_ptr<ICoreWebView2HttpRequestHeaders> requestHeaders; wil::com_ptr<ICoreWebView2HttpRequestHeaders> requestHeaders;
if (SUCCEEDED(webResourceRequest->get_Headers(&requestHeaders))) { if (SUCCEEDED(webResourceRequest->get_Headers(&requestHeaders))) {
if (urlRequest.method.has_value() && urlRequest.method.value().compare("GET") != 0) { if (method.compare(L"GET") != 0) {
requestHeaders->SetHeader(L"Flutter-InAppWebView-Request-Method", method.c_str()); requestHeaders->SetHeader(L"Flutter-InAppWebView-Request-Method", method.c_str());
} }
if (urlRequest.headers.has_value()) { if (urlRequest.headers.has_value()) {
@ -208,6 +239,10 @@ namespace flutter_inappwebview_plugin
} }
} }
bool InAppWebView::isSslError(const COREWEBVIEW2_WEB_ERROR_STATUS& webErrorStatus) {
return webErrorStatus >= COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_COMMON_NAME_IS_INCORRECT && webErrorStatus <= COREWEBVIEW2_WEB_ERROR_STATUS_CERTIFICATE_IS_INVALID;
}
InAppWebView::~InAppWebView() InAppWebView::~InAppWebView()
{ {
debugLog("dealloc InAppWebView"); debugLog("dealloc InAppWebView");
@ -217,6 +252,7 @@ namespace flutter_inappwebview_plugin
if (webViewController) { if (webViewController) {
webViewController->Close(); webViewController->Close();
} }
navigationActions.clear();
plugin = nullptr; plugin = nullptr;
} }
} }

View File

@ -6,8 +6,9 @@
#include <WebView2.h> #include <WebView2.h>
#include <wil/com.h> #include <wil/com.h>
#include "../types/url_request.h" #include "../types/url_request.h"
#include "../types/navigation_action.h"
#include "webview_channel_delegate.h" #include "webview_channel_delegate.h"
#include "../flutter_inappwebview_windows_base_plugin.h" #include "../flutter_inappwebview_windows_plugin.h"
namespace flutter_inappwebview_plugin namespace flutter_inappwebview_plugin
{ {
@ -18,20 +19,22 @@ namespace flutter_inappwebview_plugin
public: public:
static inline const std::string METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_"; static inline const std::string METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_";
FlutterInappwebviewWindowsBasePlugin* plugin; const FlutterInappwebviewWindowsPlugin* plugin;
std::variant<std::string, int> id; const std::variant<std::string, int> id;
wil::com_ptr<ICoreWebView2Environment> webViewEnv; wil::com_ptr<ICoreWebView2Environment> webViewEnv;
wil::com_ptr<ICoreWebView2Controller> webViewController; wil::com_ptr<ICoreWebView2Controller> webViewController;
wil::com_ptr<ICoreWebView2> webView; wil::com_ptr<ICoreWebView2> webView;
std::unique_ptr<WebViewChannelDelegate> channelDelegate; const std::unique_ptr<WebViewChannelDelegate> channelDelegate;
std::map<UINT64, std::shared_ptr<NavigationAction>> navigationActions = {};
InAppWebView(FlutterInappwebviewWindowsBasePlugin* plugin, std::variant<std::string, int> id, const HWND parentWindow, const std::function<void()> completionHandler); InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant<std::string, int>& id, const HWND parentWindow, const std::function<void()> completionHandler);
InAppWebView(FlutterInappwebviewWindowsBasePlugin* plugin, std::variant<std::string, int> id, const HWND parentWindow, const std::string& channelName, const std::function<void()> completionHandler); InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant<std::string, int>& id, const HWND parentWindow, const std::string& channelName, const std::function<void()> completionHandler);
~InAppWebView(); ~InAppWebView();
std::optional<std::string> getUrl() const; std::optional<std::string> getUrl() const;
void loadUrl(const URLRequest urlRequest) const; void loadUrl(const URLRequest& urlRequest) const;
static bool isSslError(const COREWEBVIEW2_WEB_ERROR_STATUS& webErrorStatus);
private: private:
bool callShouldOverrideUrlLoading = true; bool callShouldOverrideUrlLoading = true;
void createWebView(const HWND parentWindow, const std::function<void()> completionHandler); void createWebView(const HWND parentWindow, const std::function<void()> completionHandler);

View File

@ -1,7 +1,7 @@
#include "in_app_webview.h" #include "in_app_webview.h"
#include "webview_channel_delegate.h" #include "webview_channel_delegate.h"
#include "../utils/util.h" #include "../utils/flutter.h"
#include "../utils/strconv.h" #include "../utils/strconv.h"
#include "../types/base_callback_result.h" #include "../types/base_callback_result.h"
@ -38,43 +38,44 @@ namespace flutter_inappwebview_plugin
} }
if (method_call.method_name().compare("getUrl") == 0) { if (method_call.method_name().compare("getUrl") == 0) {
result->Success(optional_to_fl_value(webView->getUrl())); result->Success(make_fl_value(webView->getUrl()));
} else if (method_call.method_name().compare("loadUrl") == 0) { }
else if (method_call.method_name().compare("loadUrl") == 0) {
auto& arguments = std::get<flutter::EncodableMap>(*method_call.arguments()); auto& arguments = std::get<flutter::EncodableMap>(*method_call.arguments());
auto urlRequest = std::make_unique<URLRequest>(get_fl_map_value<flutter::EncodableMap>(arguments, "urlRequest")); auto urlRequest = std::make_unique<URLRequest>(get_fl_map_value<flutter::EncodableMap>(arguments, "urlRequest"));
webView->loadUrl(*urlRequest); webView->loadUrl(*urlRequest);
result->Success(flutter::EncodableValue(true)); result->Success(make_fl_value(true));
} }
else { else {
result->NotImplemented(); result->NotImplemented();
} }
} }
void WebViewChannelDelegate::onLoadStart(const std::optional<std::string> url) const void WebViewChannelDelegate::onLoadStart(const std::optional<std::string>& url) const
{ {
if (!channel) { if (!channel) {
return; return;
} }
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap { auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap {
{flutter::EncodableValue("url"), optional_to_fl_value(url)}, {flutter::EncodableValue("url"), make_fl_value(url)},
}); });
channel->InvokeMethod("onLoadStart", std::move(arguments)); channel->InvokeMethod("onLoadStart", std::move(arguments));
} }
void WebViewChannelDelegate::onLoadStop(const std::optional<std::string> url) const void WebViewChannelDelegate::onLoadStop(const std::optional<std::string>& url) const
{ {
if (!channel) { if (!channel) {
return; return;
} }
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{ auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("url"), optional_to_fl_value(url)}, {flutter::EncodableValue("url"), make_fl_value(url)},
}); });
channel->InvokeMethod("onLoadStop", std::move(arguments)); channel->InvokeMethod("onLoadStop", std::move(arguments));
} }
void WebViewChannelDelegate::shouldOverrideUrlLoading(std::shared_ptr<NavigationAction> navigationAction, std::unique_ptr<ShouldOverrideUrlLoadingCallback> callback) void WebViewChannelDelegate::shouldOverrideUrlLoading(std::shared_ptr<NavigationAction> navigationAction, std::unique_ptr<ShouldOverrideUrlLoadingCallback> callback) const
{ {
if (!channel) { if (!channel) {
return; return;
@ -84,6 +85,32 @@ namespace flutter_inappwebview_plugin
channel->InvokeMethod("shouldOverrideUrlLoading", std::move(arguments), std::move(callback)); channel->InvokeMethod("shouldOverrideUrlLoading", std::move(arguments), std::move(callback));
} }
void WebViewChannelDelegate::onReceivedError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceError> error) const
{
if (!channel) {
return;
}
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("request"), request->toEncodableMap()},
{flutter::EncodableValue("error"), error->toEncodableMap()},
});
channel->InvokeMethod("onReceivedError", std::move(arguments));
}
void WebViewChannelDelegate::onReceivedHttpError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceResponse> errorResponse) const
{
if (!channel) {
return;
}
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
{flutter::EncodableValue("request"), request->toEncodableMap()},
{flutter::EncodableValue("errorResponse"), errorResponse->toEncodableMap()},
});
channel->InvokeMethod("onReceivedHttpError", std::move(arguments));
}
WebViewChannelDelegate::~WebViewChannelDelegate() WebViewChannelDelegate::~WebViewChannelDelegate()
{ {
debugLog("dealloc WebViewChannelDelegate"); debugLog("dealloc WebViewChannelDelegate");

View File

@ -7,6 +7,9 @@
#include "../types/channel_delegate.h" #include "../types/channel_delegate.h"
#include "../types/base_callback_result.h" #include "../types/base_callback_result.h"
#include "../types/navigation_action.h" #include "../types/navigation_action.h"
#include "../types/web_resource_request.h"
#include "../types/web_resource_error.h"
#include "../types/web_resource_response.h"
namespace flutter_inappwebview_plugin namespace flutter_inappwebview_plugin
{ {
@ -33,9 +36,11 @@ namespace flutter_inappwebview_plugin
const flutter::MethodCall<flutter::EncodableValue>& method_call, const flutter::MethodCall<flutter::EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result); std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void onLoadStart(const std::optional<std::string> url) const; void onLoadStart(const std::optional<std::string>& url) const;
void onLoadStop(const std::optional<std::string> url) const; void onLoadStop(const std::optional<std::string>& url) const;
void shouldOverrideUrlLoading(std::shared_ptr<NavigationAction> navigationAction, std::unique_ptr<ShouldOverrideUrlLoadingCallback> callback); void shouldOverrideUrlLoading(std::shared_ptr<NavigationAction> navigationAction, std::unique_ptr<ShouldOverrideUrlLoadingCallback> callback) const;
void WebViewChannelDelegate::onReceivedError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceError> error) const;
void WebViewChannelDelegate::onReceivedHttpError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceResponse> error) const;
}; };
} }

View File

@ -3,6 +3,8 @@
#include "channel_delegate.h" #include "channel_delegate.h"
#include "../utils/util.h"
namespace flutter_inappwebview_plugin namespace flutter_inappwebview_plugin
{ {
ChannelDelegate::ChannelDelegate(flutter::BinaryMessenger* messenger, const std::string& name) : messenger(messenger) ChannelDelegate::ChannelDelegate(flutter::BinaryMessenger* messenger, const std::string& name) : messenger(messenger)

View File

@ -3,11 +3,6 @@
#include <flutter/method_channel.h> #include <flutter/method_channel.h>
#include <memory>
#include <set>
#include "../flutter_inappwebview_windows_base_plugin.h"
namespace flutter_inappwebview_plugin namespace flutter_inappwebview_plugin
{ {
class ChannelDelegate class ChannelDelegate

View File

@ -4,7 +4,7 @@
namespace flutter_inappwebview_plugin namespace flutter_inappwebview_plugin
{ {
NavigationAction::NavigationAction(std::shared_ptr<URLRequest> request, bool isForMainFrame) NavigationAction::NavigationAction(std::shared_ptr<URLRequest> request, const bool& isForMainFrame)
: request(std::move(request)), isForMainFrame(isForMainFrame) : request(std::move(request)), isForMainFrame(isForMainFrame)
{ {

View File

@ -13,7 +13,7 @@ namespace flutter_inappwebview_plugin
const std::shared_ptr<URLRequest> request; const std::shared_ptr<URLRequest> request;
const bool isForMainFrame; const bool isForMainFrame;
NavigationAction(std::shared_ptr<URLRequest> request, bool isForMainFrame); NavigationAction(std::shared_ptr<URLRequest> request, const bool& isForMainFrame);
~NavigationAction() = default; ~NavigationAction() = default;
flutter::EncodableMap toEncodableMap(); flutter::EncodableMap toEncodableMap();
}; };

View File

@ -1,19 +1,20 @@
#include "url_request.h" #include "url_request.h"
#include "../utils/util.h" #include "../utils/flutter.h"
namespace flutter_inappwebview_plugin namespace flutter_inappwebview_plugin
{ {
URLRequest::URLRequest(std::optional<std::string> url, std::optional<std::string> method, std::optional<std::map<std::string, std::string>> headers, std::optional<std::vector<uint8_t>> body) URLRequest::URLRequest(const std::optional<std::string>& url, const std::optional<std::string>& method,
const std::optional<std::map<std::string, std::string>>& headers, const std::optional<std::vector<uint8_t>>& body)
: url(url), method(method), headers(headers), body(body) : url(url), method(method), headers(headers), body(body)
{ {
} }
URLRequest::URLRequest(const flutter::EncodableMap map) URLRequest::URLRequest(const flutter::EncodableMap& map)
: url(get_optional_fl_map_value<std::string>(map, "url")), : url(get_optional_fl_map_value<std::string>(map, "url")),
method(get_optional_fl_map_value<std::string>(map, "method")), method(get_optional_fl_map_value<std::string>(map, "method")),
headers(get_optional_fl_map_value(map, "headers")), headers(get_optional_fl_map_value<std::string, std::string>(map, "headers")),
body(get_optional_fl_map_value<std::vector<uint8_t>>(map, "body")) body(get_optional_fl_map_value<std::vector<uint8_t>>(map, "body"))
{ {
@ -22,10 +23,10 @@ namespace flutter_inappwebview_plugin
flutter::EncodableMap URLRequest::toEncodableMap() flutter::EncodableMap URLRequest::toEncodableMap()
{ {
return flutter::EncodableMap{ return flutter::EncodableMap{
{flutter::EncodableValue("url"), optional_to_fl_value(url)}, {make_fl_value("url"), make_fl_value(url)},
{flutter::EncodableValue("method"), optional_to_fl_value(method)}, {make_fl_value("method"), make_fl_value(method)},
{flutter::EncodableValue("headers"), optional_to_fl_value(headers)}, {make_fl_value("headers"), make_fl_value(headers)},
{flutter::EncodableValue("body"), optional_to_fl_value(body)} {make_fl_value("body"), make_fl_value(body)}
}; };
} }
} }

View File

@ -15,8 +15,9 @@ namespace flutter_inappwebview_plugin
const std::optional<std::map<std::string, std::string>> headers; const std::optional<std::map<std::string, std::string>> headers;
const std::optional<std::vector<uint8_t>> body; const std::optional<std::vector<uint8_t>> body;
URLRequest(std::optional<std::string> url, std::optional<std::string> method, std::optional<std::map<std::string, std::string>> headers, std::optional<std::vector<uint8_t>> body); URLRequest(const std::optional<std::string>& url, const std::optional<std::string>& method,
URLRequest(const flutter::EncodableMap map); const std::optional<std::map<std::string, std::string>>& headers, const std::optional<std::vector<uint8_t>>& body);
URLRequest(const flutter::EncodableMap& map);
~URLRequest() = default; ~URLRequest() = default;
flutter::EncodableMap toEncodableMap(); flutter::EncodableMap toEncodableMap();
}; };

View File

@ -0,0 +1,27 @@
#include "web_resource_error.h"
#include "../utils/flutter.h"
namespace flutter_inappwebview_plugin
{
WebResourceError::WebResourceError(const std::string& description, const int type)
: description(description), type(type)
{
}
WebResourceError::WebResourceError(const flutter::EncodableMap& map)
: description(get_fl_map_value<std::string>(map, "description")),
type(get_fl_map_value<int>(map, "type"))
{
}
flutter::EncodableMap WebResourceError::toEncodableMap()
{
return flutter::EncodableMap{
{make_fl_value("description"), make_fl_value(description)},
{make_fl_value("type"), make_fl_value(type)}
};
}
}

View File

@ -0,0 +1,46 @@
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_ERROR_H_
#define FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_ERROR_H_
#include <flutter/standard_method_codec.h>
#include <optional>
namespace flutter_inappwebview_plugin
{
static const std::string WebErrorStatusDescription[] =
{
"Indicates that an unknown error occurred.",
"Indicates that the SSL certificate common name does not match the web address.",
"Indicates that the SSL certificate has expired.",
"Indicates that the SSL client certificate contains errors.",
"Indicates that the SSL certificate has been revoked.",
"Indicates that the SSL certificate is not valid.",
"Indicates that the host is unreachable.",
"Indicates that the connection has timed out.",
"Indicates that the server returned an invalid or unrecognized response.",
"Indicates that the connection was stopped.",
"Indicates that the connection was reset.",
"Indicates that the Internet connection has been lost.",
"Indicates that a connection to the destination was not established.",
"Indicates that the provided host name was not able to be resolved.",
"Indicates that the operation was canceled.",
"Indicates that the request redirect failed.",
"Indicates that an unexpected error occurred.",
"Indicates that user is prompted with a login, waiting on user action.",
"Indicates that user lacks proper authentication credentials for a proxy server.",
};
class WebResourceError
{
public:
const std::string description;
const int type;
WebResourceError(const std::string& description, const int type);
WebResourceError(const flutter::EncodableMap& map);
~WebResourceError() = default;
flutter::EncodableMap toEncodableMap();
};
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_ERROR_H_

View File

@ -0,0 +1,32 @@
#include "web_resource_request.h"
#include "../utils/flutter.h"
namespace flutter_inappwebview_plugin
{
WebResourceRequest::WebResourceRequest(const std::optional<std::string>& url, const std::optional<std::string>& method,
const std::optional<std::map<std::string, std::string>>& headers, const std::optional<bool>& isForMainFrame)
: url(url), method(method), headers(headers), isForMainFrame(isForMainFrame)
{
}
WebResourceRequest::WebResourceRequest(const flutter::EncodableMap& map)
: url(get_optional_fl_map_value<std::string>(map, "url")),
method(get_optional_fl_map_value<std::string>(map, "method")),
headers(get_optional_fl_map_value<std::string, std::string>(map, "headers")),
isForMainFrame(get_optional_fl_map_value<bool>(map, "isForMainFrame"))
{
}
flutter::EncodableMap WebResourceRequest::toEncodableMap()
{
return flutter::EncodableMap{
{make_fl_value("url"), make_fl_value(url)},
{make_fl_value("method"), make_fl_value(method)},
{make_fl_value("headers"), make_fl_value(headers)},
{make_fl_value("isForMainFrame"), make_fl_value(isForMainFrame)}
};
}
}

View File

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

View File

@ -0,0 +1,25 @@
#include "web_resource_response.h"
#include "../utils/flutter.h"
namespace flutter_inappwebview_plugin
{
WebResourceResponse::WebResourceResponse(const std::optional<int>& statusCode)
: statusCode(statusCode)
{
}
WebResourceResponse::WebResourceResponse(const flutter::EncodableMap& map)
: statusCode(get_optional_fl_map_value<int>(map, "statusCode"))
{
}
flutter::EncodableMap WebResourceResponse::toEncodableMap()
{
return flutter::EncodableMap{
{make_fl_value("statusCode"), make_fl_value(statusCode)}
};
}
}

View File

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

View File

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

View File

@ -22,52 +22,7 @@ namespace flutter_inappwebview_plugin
return value == nullptr ? std::nullopt : std::make_optional<T>(*value); return value == nullptr ? std::nullopt : std::make_optional<T>(*value);
} }
template<typename T> static inline std::string variant_to_string(const std::variant<std::string, int>& var)
static inline T get_fl_map_value(const flutter::EncodableMap map, const char* string)
{
return std::get<T>(map.at(flutter::EncodableValue(string)));
}
template<typename T>
static inline std::optional<T> get_optional_fl_map_value(const flutter::EncodableMap map, const char* string)
{
return make_pointer_optional<T>(std::get_if<T>(&map.at(flutter::EncodableValue(string))));
}
static inline std::optional<std::map<std::string, std::string>> get_optional_fl_map_value(const flutter::EncodableMap map, const char* string)
{
auto mapValue = std::map<std::string, std::string>{};
auto flMap = std::get_if<flutter::EncodableMap>(&map.at(flutter::EncodableValue(string)));
if (flMap) {
for (auto itr = flMap->begin(); itr != flMap->end(); itr++)
{
mapValue.insert({ std::get<std::string>(itr->first), std::get<std::string>(itr->second) });
}
}
return make_pointer_optional<std::map<std::string, std::string>>(&mapValue);
}
template<typename T>
static inline flutter::EncodableValue optional_to_fl_value(const std::optional<T> optional)
{
return optional.has_value() ? flutter::EncodableValue(optional.value()) : flutter::EncodableValue();
}
static inline flutter::EncodableValue optional_to_fl_value(const std::optional<std::map<std::string, std::string>> optional)
{
if (!optional.has_value()) {
return flutter::EncodableValue();
}
auto& mapValue = optional.value();
auto encodableMap = flutter::EncodableMap{};
for (auto const& [key, val] : mapValue)
{
encodableMap.insert({ flutter::EncodableValue(key), flutter::EncodableValue(val) });
}
return encodableMap;
}
static inline std::string variant_to_string(std::variant<std::string, int> var)
{ {
return std::visit([](auto&& arg) { return std::visit([](auto&& arg) {
using T = std::decay_t<decltype(arg)>; using T = std::decay_t<decltype(arg)>;
@ -79,6 +34,19 @@ namespace flutter_inappwebview_plugin
static_assert(always_false_v<T>, "non-exhaustive visitor!"); static_assert(always_false_v<T>, "non-exhaustive visitor!");
}, var); }, 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;
}
} }
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_ #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_