diff --git a/flutter_inappwebview/example/lib/in_app_browser_example.screen.dart b/flutter_inappwebview/example/lib/in_app_browser_example.screen.dart index 15f2bd7b..6d307cb8 100755 --- a/flutter_inappwebview/example/lib/in_app_browser_example.screen.dart +++ b/flutter_inappwebview/example/lib/in_app_browser_example.screen.dart @@ -30,6 +30,7 @@ class MyInAppBrowser extends InAppBrowser { @override Future onLoadStop(url) async { pullToRefreshController?.endRefreshing(); + print(await webViewController?.getUrl()); } @override diff --git a/flutter_inappwebview_platform_interface/lib/src/in_app_browser/platform_in_app_browser.dart b/flutter_inappwebview_platform_interface/lib/src/in_app_browser/platform_in_app_browser.dart index 999b92a3..aa9b525b 100755 --- a/flutter_inappwebview_platform_interface/lib/src/in_app_browser/platform_in_app_browser.dart +++ b/flutter_inappwebview_platform_interface/lib/src/in_app_browser/platform_in_app_browser.dart @@ -64,6 +64,7 @@ class PlatformInAppBrowserCreationParams { ///- Android native WebView ///- iOS ///- MacOS +///- Windows ///{@endtemplate} abstract class PlatformInAppBrowser extends PlatformInterface implements Disposable { @@ -172,6 +173,7 @@ abstract class PlatformInAppBrowser extends PlatformInterface ///- Android native WebView ///- iOS ///- MacOS + ///- Windows ///{@endtemplate} Future openUrlRequest( {required URLRequest urlRequest, @@ -464,6 +466,7 @@ abstract class PlatformInAppBrowser extends PlatformInterface ///- Android native WebView ///- iOS ///- MacOS + ///- Windows ///{@endtemplate} bool isOpened() { throw UnimplementedError( @@ -487,6 +490,7 @@ abstract class PlatformInAppBrowserEvents { ///- Android native WebView ///- iOS ///- MacOS + ///- Windows void onBrowserCreated() {} ///Event fired when the [PlatformInAppBrowser] window is closed. @@ -495,6 +499,7 @@ abstract class PlatformInAppBrowserEvents { ///- Android native WebView ///- iOS ///- MacOS + ///- Windows void onExit() {} ///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))) ///- 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)) + ///- 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) {} ///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))) ///- 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)) + ///- 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) {} ///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))) ///- 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)) void onReceivedError(WebResourceRequest request, WebResourceError error) {} ///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))) ///- 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)) void onReceivedHttpError( WebResourceRequest request, WebResourceResponse errorResponse) {} diff --git a/flutter_inappwebview_platform_interface/lib/src/in_app_webview/platform_inappwebview_controller.dart b/flutter_inappwebview_platform_interface/lib/src/in_app_webview/platform_inappwebview_controller.dart index 952ab49d..f9ce118b 100644 --- a/flutter_inappwebview_platform_interface/lib/src/in_app_webview/platform_inappwebview_controller.dart +++ b/flutter_inappwebview_platform_interface/lib/src/in_app_webview/platform_inappwebview_controller.dart @@ -134,6 +134,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface ///- 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)) ///- 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} Future getUrl() { 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)) ///- 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 + ///- 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} Future loadUrl( {required URLRequest urlRequest, diff --git a/flutter_inappwebview_platform_interface/lib/src/types/web_resource_error_type.dart b/flutter_inappwebview_platform_interface/lib/src/types/web_resource_error_type.dart index 822de4cb..49b91fa8 100644 --- a/flutter_inappwebview_platform_interface/lib/src/types/web_resource_error_type.dart +++ b/flutter_inappwebview_platform_interface/lib/src/types/web_resource_error_type.dart @@ -60,7 +60,12 @@ class WebResourceErrorType_ { apiName: 'URLError.cannotConnectToHost', apiUrl: '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 = WebResourceErrorType_._internal("CANNOT_CONNECT_TO_HOST"); @@ -124,7 +129,12 @@ class WebResourceErrorType_ { apiName: 'URLError.cannotFindHost', apiUrl: '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"); @@ -186,7 +196,12 @@ class WebResourceErrorType_ { apiName: 'URLError.timedOut', apiUrl: '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"); @@ -217,7 +232,12 @@ class WebResourceErrorType_ { apiName: 'URLError.unknown', apiUrl: '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"); @@ -276,7 +296,12 @@ class WebResourceErrorType_ { apiName: 'URLError.cancelled', apiUrl: '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"); @@ -291,7 +316,12 @@ class WebResourceErrorType_ { apiName: 'URLError.networkConnectionLost', apiUrl: '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 = WebResourceErrorType_._internal("NETWORK_CONNECTION_LOST"); @@ -356,7 +386,12 @@ class WebResourceErrorType_ { apiName: 'URLError.badServerResponse', apiUrl: '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 = WebResourceErrorType_._internal("BAD_SERVER_RESPONSE"); @@ -389,7 +424,12 @@ class WebResourceErrorType_ { apiName: 'URLError.userAuthenticationRequired', apiUrl: '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 = WebResourceErrorType_._internal("USER_AUTHENTICATION_REQUIRED"); @@ -892,4 +932,64 @@ class WebResourceErrorType_ { ]) static const 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"); } diff --git a/flutter_inappwebview_platform_interface/lib/src/types/web_resource_error_type.g.dart b/flutter_inappwebview_platform_interface/lib/src/types/web_resource_error_type.g.dart index 4a4f905d..bbf3f6d8 100644 --- a/flutter_inappwebview_platform_interface/lib/src/types/web_resource_error_type.g.dart +++ b/flutter_inappwebview_platform_interface/lib/src/types/web_resource_error_type.g.dart @@ -97,6 +97,7 @@ class WebResourceErrorType { ///**Officially Supported Platforms/Implementations**: ///- 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)) + ///- 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 = WebResourceErrorType._internalMultiPlatform('BAD_SERVER_RESPONSE', () { switch (defaultTargetPlatform) { @@ -104,6 +105,8 @@ class WebResourceErrorType { return -1011; case TargetPlatform.macOS: return -1011; + case TargetPlatform.windows: + return 8; default: break; } @@ -154,6 +157,7 @@ class WebResourceErrorType { ///**Officially Supported Platforms/Implementations**: ///- 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)) + ///- 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 = WebResourceErrorType._internalMultiPlatform('CANCELLED', () { switch (defaultTargetPlatform) { @@ -161,6 +165,8 @@ class WebResourceErrorType { return -999; case TargetPlatform.macOS: return -999; + case TargetPlatform.windows: + return 14; default: 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)) ///- 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)) + ///- 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 = WebResourceErrorType._internalMultiPlatform('CANNOT_CONNECT_TO_HOST', () { switch (defaultTargetPlatform) { @@ -200,6 +207,8 @@ class WebResourceErrorType { return -1004; case TargetPlatform.macOS: return -1004; + case TargetPlatform.windows: + return 12; default: break; } @@ -408,6 +417,21 @@ class WebResourceErrorType { 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. /// ///**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)) ///- 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)) + ///- 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 = WebResourceErrorType._internalMultiPlatform('HOST_LOOKUP', () { switch (defaultTargetPlatform) { @@ -567,6 +592,8 @@ class WebResourceErrorType { return -1003; case TargetPlatform.macOS: return -1003; + case TargetPlatform.windows: + return 13; default: break; } @@ -611,6 +638,7 @@ class WebResourceErrorType { ///**Officially Supported Platforms/Implementations**: ///- 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)) + ///- 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 = WebResourceErrorType._internalMultiPlatform('NETWORK_CONNECTION_LOST', () { @@ -619,6 +647,8 @@ class WebResourceErrorType { return -1005; case TargetPlatform.macOS: return -1005; + case TargetPlatform.windows: + return 11; default: break; } @@ -678,6 +708,21 @@ class WebResourceErrorType { 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 didn’t accompany this code with a redirect URL. /// ///**Officially Supported Platforms/Implementations**: @@ -716,6 +761,20 @@ class WebResourceErrorType { 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. ///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; }); + ///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. /// ///**Officially Supported Platforms/Implementations**: ///- 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)) ///- 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 = WebResourceErrorType._internalMultiPlatform('TIMEOUT', () { switch (defaultTargetPlatform) { @@ -845,6 +920,8 @@ class WebResourceErrorType { return -1001; case TargetPlatform.macOS: return -1001; + case TargetPlatform.windows: + return 7; default: break; } @@ -887,12 +964,28 @@ class WebResourceErrorType { 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 can’t interpret. /// ///**Officially Supported Platforms/Implementations**: ///- 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)) ///- 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 = WebResourceErrorType._internalMultiPlatform('UNKNOWN', () { switch (defaultTargetPlatform) { @@ -902,6 +995,8 @@ class WebResourceErrorType { return -1; case TargetPlatform.macOS: return -1; + case TargetPlatform.windows: + return 0; default: break; } @@ -982,6 +1077,7 @@ class WebResourceErrorType { ///**Officially Supported Platforms/Implementations**: ///- 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)) + ///- 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 = WebResourceErrorType._internalMultiPlatform( 'USER_AUTHENTICATION_REQUIRED', () { @@ -990,6 +1086,8 @@ class WebResourceErrorType { return -1013; case TargetPlatform.macOS: return -1013; + case TargetPlatform.windows: + return 17; default: break; } @@ -1016,6 +1114,22 @@ class WebResourceErrorType { 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. /// ///**Officially Supported Platforms/Implementations**: @@ -1057,6 +1171,7 @@ class WebResourceErrorType { WebResourceErrorType.CANNOT_WRITE_TO_FILE, WebResourceErrorType.CLIENT_CERTIFICATE_REJECTED, WebResourceErrorType.CLIENT_CERTIFICATE_REQUIRED, + WebResourceErrorType.CONNECTION_ABORTED, WebResourceErrorType.DATA_LENGTH_EXCEEDS_MAXIMUM, WebResourceErrorType.DATA_NOT_ALLOWED, WebResourceErrorType.DOWNLOAD_DECODING_FAILED_MID_STREAM, @@ -1072,17 +1187,21 @@ class WebResourceErrorType { WebResourceErrorType.NOT_CONNECTED_TO_INTERNET, WebResourceErrorType.NO_PERMISSIONS_TO_READ_FILE, WebResourceErrorType.PROXY_AUTHENTICATION, + WebResourceErrorType.REDIRECT_FAILED, WebResourceErrorType.REDIRECT_TO_NON_EXISTENT_LOCATION, WebResourceErrorType.REQUEST_BODY_STREAM_EXHAUSTED, + WebResourceErrorType.RESET, WebResourceErrorType.RESOURCE_UNAVAILABLE, WebResourceErrorType.SECURE_CONNECTION_FAILED, WebResourceErrorType.SERVER_CERTIFICATE_HAS_BAD_DATE, WebResourceErrorType.SERVER_CERTIFICATE_HAS_UNKNOWN_ROOT, WebResourceErrorType.SERVER_CERTIFICATE_NOT_YET_VALID, WebResourceErrorType.SERVER_CERTIFICATE_UNTRUSTED, + WebResourceErrorType.SERVER_UNREACHABLE, WebResourceErrorType.TIMEOUT, WebResourceErrorType.TOO_MANY_REDIRECTS, WebResourceErrorType.TOO_MANY_REQUESTS, + WebResourceErrorType.UNEXPECTED_ERROR, WebResourceErrorType.UNKNOWN, WebResourceErrorType.UNSAFE_RESOURCE, WebResourceErrorType.UNSUPPORTED_AUTH_SCHEME, @@ -1090,6 +1209,7 @@ class WebResourceErrorType { WebResourceErrorType.USER_AUTHENTICATION_FAILED, WebResourceErrorType.USER_AUTHENTICATION_REQUIRED, WebResourceErrorType.USER_CANCELLED_AUTHENTICATION, + WebResourceErrorType.VALID_PROXY_AUTHENTICATION_REQUIRED, WebResourceErrorType.ZERO_BYTE_RESOURCE, ].toSet(); diff --git a/flutter_inappwebview_windows/lib/src/in_app_browser/in_app_browser.dart b/flutter_inappwebview_windows/lib/src/in_app_browser/in_app_browser.dart index 1bf9a54b..e37a3068 100644 --- a/flutter_inappwebview_windows/lib/src/in_app_browser/in_app_browser.dart +++ b/flutter_inappwebview_windows/lib/src/in_app_browser/in_app_browser.dart @@ -65,7 +65,7 @@ class WindowsInAppBrowser extends PlatformInAppBrowser with ChannelController { return _staticValue; } - WindowsInAppBrowserCreationParams get _macosParams => + WindowsInAppBrowserCreationParams get _windowsParams => params as WindowsInAppBrowserCreationParams; static const MethodChannel _staticChannel = @@ -95,7 +95,7 @@ class WindowsInAppBrowser extends PlatformInAppBrowser with ChannelController { channel!, this, this.initialUserScripts); - _macosParams.findInteractionController?.init(id); + _windowsParams.findInteractionController?.init(id); } _debugLog(String method, dynamic args) { diff --git a/flutter_inappwebview_windows/windows/CMakeLists.txt b/flutter_inappwebview_windows/windows/CMakeLists.txt index a2088f2f..475fb4eb 100644 --- a/flutter_inappwebview_windows/windows/CMakeLists.txt +++ b/flutter_inappwebview_windows/windows/CMakeLists.txt @@ -49,12 +49,11 @@ add_custom_command( # Any new source files that you add to the plugin should be added here. 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.h" "utils/strconv.h" "utils/util.h" + "utils/flutter.h" "types/channel_delegate.cpp" "types/channel_delegate.h" "types/base_callback_result.h" @@ -62,6 +61,12 @@ list(APPEND PLUGIN_SOURCES "types/url_request.h" "types/navigation_action.cpp" "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.h" "in_app_webview/webview_channel_delegate.cpp" diff --git a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_base_plugin.cpp b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_base_plugin.cpp deleted file mode 100644 index 45c7cbc2..00000000 --- a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_base_plugin.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "flutter_inappwebview_windows_base_plugin.h" - -namespace flutter_inappwebview_plugin -{ - FlutterInappwebviewWindowsBasePlugin::FlutterInappwebviewWindowsBasePlugin(flutter::PluginRegistrarWindows* registrar) : registrar(registrar) - { - - } - - FlutterInappwebviewWindowsBasePlugin::~FlutterInappwebviewWindowsBasePlugin() - { - - } -} \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_base_plugin.h b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_base_plugin.h deleted file mode 100644 index e442060b..00000000 --- a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_base_plugin.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_BASE_PLUGIN_H_ -#define FLUTTER_INAPPWEBVIEW_PLUGIN_BASE_PLUGIN_H_ - -#include - -namespace flutter_inappwebview_plugin -{ - class FlutterInappwebviewWindowsBasePlugin : public flutter::Plugin, public std::enable_shared_from_this { - public: - flutter::PluginRegistrarWindows* registrar; - - FlutterInappwebviewWindowsBasePlugin(flutter::PluginRegistrarWindows* registrar); - - virtual ~FlutterInappwebviewWindowsBasePlugin(); - }; -} - -#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_BASE_PLUGIN_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.cpp b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.cpp index b849e10b..5e4070cb 100644 --- a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.cpp +++ b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.cpp @@ -3,6 +3,8 @@ #include #include +#include "in_app_browser/in_app_browser_manager.h" + namespace flutter_inappwebview_plugin { // static @@ -13,7 +15,7 @@ namespace flutter_inappwebview_plugin } FlutterInappwebviewWindowsPlugin::FlutterInappwebviewWindowsPlugin(flutter::PluginRegistrarWindows* registrar) - : FlutterInappwebviewWindowsBasePlugin(registrar) + : registrar(registrar) { inAppBrowserManager = std::make_unique(this); } diff --git a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.h b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.h index e152a4ef..534ecabb 100644 --- a/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.h +++ b/flutter_inappwebview_windows/windows/flutter_inappwebview_windows_plugin.h @@ -4,16 +4,13 @@ #include #include -#include - -#include "flutter_inappwebview_windows_base_plugin.h" - -#include "in_app_browser/in_app_browser_manager.h" - namespace flutter_inappwebview_plugin { - class FlutterInappwebviewWindowsPlugin : public FlutterInappwebviewWindowsBasePlugin { + class InAppBrowserManager; + + class FlutterInappwebviewWindowsPlugin : public flutter::Plugin { public: + flutter::PluginRegistrarWindows* registrar; std::unique_ptr inAppBrowserManager; static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar); diff --git a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.cpp b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.cpp index 50bc8e6f..0a158848 100644 --- a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.cpp +++ b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.cpp @@ -1,33 +1,11 @@ #include #include "in_app_browser.h" - -#include -#include - -#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 -#include -#include -#include -#include -#include "../utils/strconv.h" #include "../utils/util.h" - -#include -#include +#include "in_app_browser_manager.h" namespace flutter_inappwebview_plugin { - using namespace Microsoft::WRL; - - const wchar_t* CLASS_NAME = L"InAppBrowser"; - - InAppBrowser::InAppBrowser(FlutterInappwebviewWindowsBasePlugin* plugin, const InAppBrowserCreationParams& params) + InAppBrowser::InAppBrowser(FlutterInappwebviewWindowsPlugin* plugin, const InAppBrowserCreationParams& params) : plugin(plugin), m_hInstance(GetModuleHandle(nullptr)), id(params.id), @@ -35,7 +13,7 @@ namespace flutter_inappwebview_plugin channelDelegate(std::make_unique(id, plugin->registrar->messenger())) { WNDCLASS wndClass = {}; - wndClass.lpszClassName = CLASS_NAME; + wndClass.lpszClassName = InAppBrowser::CLASS_NAME; wndClass.hInstance = m_hInstance; wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); @@ -45,9 +23,9 @@ namespace flutter_inappwebview_plugin m_hWnd = CreateWindowEx( 0, // Optional window styles. - CLASS_NAME, // Window class - L"Learn to Program Windows", // Window text - WS_OVERLAPPEDWINDOW, // Window style + InAppBrowser::CLASS_NAME, // Window class + L"", // Window text + WS_OVERLAPPEDWINDOW, // Window style // Size and position CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, @@ -186,15 +164,19 @@ namespace flutter_inappwebview_plugin ) noexcept { switch (message) { case WM_DESTROY: { - webView.reset(); - // might receive multiple WM_DESTROY messages. if (!destroyed_) { destroyed_ = true; + webView.reset(); + if (channelDelegate) { channelDelegate->onExit(); } + + if (plugin && plugin->inAppBrowserManager) { + plugin->inAppBrowserManager->browsers.erase(id); + } } return 0; } diff --git a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.h b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.h index c674718f..a3adb62d 100644 --- a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.h +++ b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser.h @@ -6,7 +6,7 @@ #include #include -#include "../flutter_inappwebview_windows_base_plugin.h" +#include "../flutter_inappwebview_windows_plugin.h" #include "../in_app_webview/in_app_webview.h" #include "../types/url_request.h" #include "in_app_browser_channel_delegate.h" @@ -22,19 +22,20 @@ namespace flutter_inappwebview_plugin class InAppBrowser { public: 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, UINT message, WPARAM wparam, LPARAM lparam) noexcept; - FlutterInappwebviewWindowsBasePlugin* plugin; + FlutterInappwebviewWindowsPlugin* plugin; std::string id; std::optional initialUrlRequest; std::unique_ptr webView; std::unique_ptr channelDelegate; - InAppBrowser(FlutterInappwebviewWindowsBasePlugin* plugin, const InAppBrowserCreationParams& params); + InAppBrowser(FlutterInappwebviewWindowsPlugin* plugin, const InAppBrowserCreationParams& params); ~InAppBrowser(); private: diff --git a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.cpp b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.cpp index ebfee72c..9a253806 100644 --- a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.cpp +++ b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.cpp @@ -5,7 +5,7 @@ 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) { diff --git a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.h b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.h index 6c6fa5cb..488f69f1 100644 --- a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.h +++ b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_channel_delegate.h @@ -11,7 +11,7 @@ namespace flutter_inappwebview_plugin class InAppBrowserChannelDelegate : public ChannelDelegate { public: - InAppBrowserChannelDelegate(const std::string id, flutter::BinaryMessenger* messenger); + InAppBrowserChannelDelegate(const std::string& id, flutter::BinaryMessenger* messenger); ~InAppBrowserChannelDelegate(); void HandleMethodCall( diff --git a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.cpp b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.cpp index b7dad155..a421aaee 100644 --- a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.cpp +++ b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.cpp @@ -1,16 +1,17 @@ #include #include #include +#include #include "in_app_browser_manager.h" #include "../types/url_request.h" -#include "../utils/util.h" +#include "../utils/flutter.h" namespace flutter_inappwebview_plugin { - InAppBrowserManager::InAppBrowserManager(FlutterInappwebviewWindowsBasePlugin* plugin) + InAppBrowserManager::InAppBrowserManager(FlutterInappwebviewWindowsPlugin* plugin) : 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) { - auto id = std::get(arguments->at(flutter::EncodableValue("id"))); - auto urlRequestMap = std::get_if(&arguments->at(flutter::EncodableValue("urlRequest"))); - auto urlRequest = make_pointer_optional(new URLRequest(*urlRequestMap)); + auto id = get_fl_map_value(*arguments, "id"); + auto urlRequestMap = get_optional_fl_map_value(*arguments, "urlRequest"); + std::optional urlRequest = urlRequestMap.has_value() ? std::make_optional(urlRequestMap.value()) : std::optional{}; InAppBrowserCreationParams params = { id, urlRequest }; auto inAppBrowser = std::make_unique(plugin, params); - browsers[id] = std::move(inAppBrowser); + browsers.insert({ id, std::move(inAppBrowser) }); } InAppBrowserManager::~InAppBrowserManager() diff --git a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.h b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.h index 389b27a0..b0093c51 100644 --- a/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.h +++ b/flutter_inappwebview_windows/windows/in_app_browser/in_app_browser_manager.h @@ -6,7 +6,7 @@ #include #include -#include "../flutter_inappwebview_windows_base_plugin.h" +#include "../flutter_inappwebview_windows_plugin.h" #include "in_app_browser.h" @@ -19,10 +19,10 @@ namespace flutter_inappwebview_plugin public: static inline const std::string METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappbrowser"; - FlutterInappwebviewWindowsBasePlugin* plugin; + FlutterInappwebviewWindowsPlugin* plugin; std::map> browsers; - InAppBrowserManager(FlutterInappwebviewWindowsBasePlugin* plugin); + InAppBrowserManager(FlutterInappwebviewWindowsPlugin* plugin); ~InAppBrowserManager(); void HandleMethodCall( diff --git a/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.cpp b/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.cpp index 4ec9f748..51187943 100644 --- a/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.cpp +++ b/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.cpp @@ -6,18 +6,20 @@ #include #include "../utils/strconv.h" #include "../utils/util.h" +#include "../types/web_resource_request.h" +#include "../types/web_resource_error.h" namespace flutter_inappwebview_plugin { using namespace Microsoft::WRL; - InAppWebView::InAppWebView(FlutterInappwebviewWindowsBasePlugin* plugin, std::variant id, const HWND parentWindow, const std::function completionHandler) + InAppWebView::InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant& id, const HWND parentWindow, const std::function completionHandler) : plugin(plugin), id(id), channelDelegate(std::make_unique(this, plugin->registrar->messenger())) { createWebView(parentWindow, completionHandler); } - InAppWebView::InAppWebView(FlutterInappwebviewWindowsBasePlugin* plugin, std::variant id, const HWND parentWindow, const std::string& channelName, const std::function completionHandler) + InAppWebView::InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant& id, const HWND parentWindow, const std::string& channelName, const std::function completionHandler) : plugin(plugin), id(id), channelDelegate(std::make_unique(this, plugin->registrar->messenger(), channelName)) { createWebView(parentWindow, completionHandler); @@ -29,7 +31,7 @@ namespace flutter_inappwebview_plugin Callback( [parentWindow, completionHandler, this](HRESULT result, ICoreWebView2Environment* env) -> HRESULT { webViewEnv = env; - // Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd + // Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window HWND env->CreateCoreWebView2Controller(parentWindow, Callback( [parentWindow, completionHandler, this](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT { if (controller != nullptr) { @@ -67,9 +69,9 @@ namespace flutter_inappwebview_plugin } wil::unique_cotaskmem_string uri = nullptr; - std::optional url = SUCCEEDED(args->get_Uri(&uri)) ? wide_to_utf8(std::wstring(uri.get())) : std::optional{}; + std::optional url = SUCCEEDED(args->get_Uri(&uri)) ? wide_to_utf8(uri.get()) : std::optional{}; - wil::unique_cotaskmem_string method = nullptr; + wil::unique_cotaskmem_string requestMethod = nullptr; wil::com_ptr requestHeaders = nullptr; std::optional> headers = std::optional>{}; if (SUCCEEDED(args->get_RequestHeaders(&requestHeaders))) { @@ -83,26 +85,33 @@ namespace flutter_inappwebview_plugin wil::unique_cotaskmem_string value; if (SUCCEEDED(iterator->GetCurrentHeader(&name, &value))) { - headers->insert({ wide_to_utf8(std::wstring(name.get())), wide_to_utf8(std::wstring(value.get())) }); + headers->insert({ wide_to_utf8(name.get()), wide_to_utf8(value.get()) }); } BOOL hasNext = FALSE; 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"); } - if (callShouldOverrideUrlLoading && method == nullptr) { - // for some reason, we can't cancel and load an URL with other HTTP methods other than GET, - // so ignore the shouldOverrideUrlLoading event. + std::optional method = requestMethod ? wide_to_utf8(requestMethod.get()) : std::optional{}; - auto urlRequest = std::make_shared(url, std::nullopt, headers, std::nullopt); - auto navigationAction = std::make_unique( - urlRequest, - true - ); + auto urlRequest = std::make_shared(url, method, headers, std::nullopt); + auto navigationAction = std::make_shared( + urlRequest, + 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(); callback->nonNullSuccess = [this, urlRequest](const NavigationActionPolicy actionPolicy) { @@ -137,9 +146,17 @@ namespace flutter_inappwebview_plugin webView->add_NavigationCompleted( Callback( [this](ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args) { - COREWEBVIEW2_WEB_ERROR_STATUS web_error_status; - args->get_WebErrorStatus(&web_error_status); - debugLog("WebErrorStatus " + std::to_string(web_error_status) + "\n"); + std::shared_ptr navigationAction; + UINT64 navigationId; + 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; args->get_IsSuccess(&isSuccess); @@ -150,7 +167,21 @@ namespace flutter_inappwebview_plugin if (isSuccess) { channelDelegate->onLoadStop(url); } + else if (!InAppWebView::isSslError(webErrorType) && navigationAction) { + auto webResourceRequest = std::make_unique(url, navigationAction->request->method, navigationAction->request->headers, navigationAction->isForMainFrame); + int httpStatusCode = 0; + wil::com_ptr args2; + if (SUCCEEDED(args->QueryInterface(IID_PPV_ARGS(&args2))) && SUCCEEDED(args2->get_HttpStatusCode(&httpStatusCode)) && httpStatusCode >= 400) { + auto webResourceResponse = std::make_unique(httpStatusCode); + channelDelegate->onReceivedHttpError(std::move(webResourceRequest), std::move(webResourceResponse)); + } + else if (httpStatusCode < 400) { + auto webResourceError = std::make_unique(WebErrorStatusDescription[webErrorType], webErrorType); + channelDelegate->onReceivedError(std::move(webResourceRequest), std::move(webResourceError)); + } + } } + return S_OK; } ).Get(), nullptr); @@ -159,10 +190,10 @@ namespace flutter_inappwebview_plugin std::optional InAppWebView::getUrl() const { LPWSTR uri = nullptr; - return SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(std::wstring(uri)) : std::optional{}; + return SUCCEEDED(webView->get_Source(&uri)) ? wide_to_utf8(uri) : std::optional{}; } - void InAppWebView::loadUrl(const URLRequest urlRequest) const + void InAppWebView::loadUrl(const URLRequest& urlRequest) const { if (!webView || !urlRequest.url.has_value()) { return; @@ -191,7 +222,7 @@ namespace flutter_inappwebview_plugin ); wil::com_ptr 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()); } 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() { debugLog("dealloc InAppWebView"); @@ -217,6 +252,7 @@ namespace flutter_inappwebview_plugin if (webViewController) { webViewController->Close(); } + navigationActions.clear(); plugin = nullptr; } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.h b/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.h index 833fc641..145b2512 100644 --- a/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.h +++ b/flutter_inappwebview_windows/windows/in_app_webview/in_app_webview.h @@ -6,8 +6,9 @@ #include #include #include "../types/url_request.h" +#include "../types/navigation_action.h" #include "webview_channel_delegate.h" -#include "../flutter_inappwebview_windows_base_plugin.h" +#include "../flutter_inappwebview_windows_plugin.h" namespace flutter_inappwebview_plugin { @@ -18,20 +19,22 @@ namespace flutter_inappwebview_plugin public: static inline const std::string METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_"; - FlutterInappwebviewWindowsBasePlugin* plugin; - std::variant id; + const FlutterInappwebviewWindowsPlugin* plugin; + const std::variant id; wil::com_ptr webViewEnv; wil::com_ptr webViewController; wil::com_ptr webView; - std::unique_ptr channelDelegate; + const std::unique_ptr channelDelegate; + std::map> navigationActions = {}; - InAppWebView(FlutterInappwebviewWindowsBasePlugin* plugin, std::variant id, const HWND parentWindow, const std::function completionHandler); - InAppWebView(FlutterInappwebviewWindowsBasePlugin* plugin, std::variant id, const HWND parentWindow, const std::string& channelName, const std::function completionHandler); + InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant& id, const HWND parentWindow, const std::function completionHandler); + InAppWebView(FlutterInappwebviewWindowsPlugin* plugin, const std::variant& id, const HWND parentWindow, const std::string& channelName, const std::function completionHandler); ~InAppWebView(); std::optional getUrl() const; - void loadUrl(const URLRequest urlRequest) const; + void loadUrl(const URLRequest& urlRequest) const; + static bool isSslError(const COREWEBVIEW2_WEB_ERROR_STATUS& webErrorStatus); private: bool callShouldOverrideUrlLoading = true; void createWebView(const HWND parentWindow, const std::function completionHandler); diff --git a/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.cpp b/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.cpp index d68dc2c1..2e6f0d9f 100644 --- a/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.cpp +++ b/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.cpp @@ -1,14 +1,14 @@ #include "in_app_webview.h" #include "webview_channel_delegate.h" -#include "../utils/util.h" +#include "../utils/flutter.h" #include "../utils/strconv.h" #include "../types/base_callback_result.h" namespace flutter_inappwebview_plugin { WebViewChannelDelegate::WebViewChannelDelegate(InAppWebView* webView, flutter::BinaryMessenger* messenger) - : webView(webView), ChannelDelegate(messenger, InAppWebView::METHOD_CHANNEL_NAME_PREFIX + variant_to_string(webView->id)) + : webView(webView), ChannelDelegate(messenger, InAppWebView::METHOD_CHANNEL_NAME_PREFIX + variant_to_string(webView->id)) { } @@ -38,43 +38,44 @@ namespace flutter_inappwebview_plugin } if (method_call.method_name().compare("getUrl") == 0) { - result->Success(optional_to_fl_value(webView->getUrl())); - } else if (method_call.method_name().compare("loadUrl") == 0) { + result->Success(make_fl_value(webView->getUrl())); + } + else if (method_call.method_name().compare("loadUrl") == 0) { auto& arguments = std::get(*method_call.arguments()); auto urlRequest = std::make_unique(get_fl_map_value(arguments, "urlRequest")); webView->loadUrl(*urlRequest); - result->Success(flutter::EncodableValue(true)); + result->Success(make_fl_value(true)); } else { result->NotImplemented(); } } - void WebViewChannelDelegate::onLoadStart(const std::optional url) const + void WebViewChannelDelegate::onLoadStart(const std::optional& url) const { if (!channel) { return; } auto arguments = std::make_unique(flutter::EncodableMap { - {flutter::EncodableValue("url"), optional_to_fl_value(url)}, + {flutter::EncodableValue("url"), make_fl_value(url)}, }); channel->InvokeMethod("onLoadStart", std::move(arguments)); } - void WebViewChannelDelegate::onLoadStop(const std::optional url) const + void WebViewChannelDelegate::onLoadStop(const std::optional& url) const { if (!channel) { return; } auto arguments = std::make_unique(flutter::EncodableMap{ - {flutter::EncodableValue("url"), optional_to_fl_value(url)}, + {flutter::EncodableValue("url"), make_fl_value(url)}, }); channel->InvokeMethod("onLoadStop", std::move(arguments)); } - void WebViewChannelDelegate::shouldOverrideUrlLoading(std::shared_ptr navigationAction, std::unique_ptr callback) + void WebViewChannelDelegate::shouldOverrideUrlLoading(std::shared_ptr navigationAction, std::unique_ptr callback) const { if (!channel) { return; @@ -84,6 +85,32 @@ namespace flutter_inappwebview_plugin channel->InvokeMethod("shouldOverrideUrlLoading", std::move(arguments), std::move(callback)); } + void WebViewChannelDelegate::onReceivedError(std::shared_ptr request, std::shared_ptr error) const + { + if (!channel) { + return; + } + + auto arguments = std::make_unique(flutter::EncodableMap{ + {flutter::EncodableValue("request"), request->toEncodableMap()}, + {flutter::EncodableValue("error"), error->toEncodableMap()}, + }); + channel->InvokeMethod("onReceivedError", std::move(arguments)); + } + + void WebViewChannelDelegate::onReceivedHttpError(std::shared_ptr request, std::shared_ptr errorResponse) const + { + if (!channel) { + return; + } + + auto arguments = std::make_unique(flutter::EncodableMap{ + {flutter::EncodableValue("request"), request->toEncodableMap()}, + {flutter::EncodableValue("errorResponse"), errorResponse->toEncodableMap()}, + }); + channel->InvokeMethod("onReceivedHttpError", std::move(arguments)); + } + WebViewChannelDelegate::~WebViewChannelDelegate() { debugLog("dealloc WebViewChannelDelegate"); diff --git a/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.h b/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.h index a5bfe0a4..768c5191 100644 --- a/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.h +++ b/flutter_inappwebview_windows/windows/in_app_webview/webview_channel_delegate.h @@ -7,6 +7,9 @@ #include "../types/channel_delegate.h" #include "../types/base_callback_result.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 { @@ -33,9 +36,11 @@ namespace flutter_inappwebview_plugin const flutter::MethodCall& method_call, std::unique_ptr> result); - void onLoadStart(const std::optional url) const; - void onLoadStop(const std::optional url) const; - void shouldOverrideUrlLoading(std::shared_ptr navigationAction, std::unique_ptr callback); + void onLoadStart(const std::optional& url) const; + void onLoadStop(const std::optional& url) const; + void shouldOverrideUrlLoading(std::shared_ptr navigationAction, std::unique_ptr callback) const; + void WebViewChannelDelegate::onReceivedError(std::shared_ptr request, std::shared_ptr error) const; + void WebViewChannelDelegate::onReceivedHttpError(std::shared_ptr request, std::shared_ptr error) const; }; } diff --git a/flutter_inappwebview_windows/windows/types/channel_delegate.cpp b/flutter_inappwebview_windows/windows/types/channel_delegate.cpp index b57de4ac..bdec9099 100644 --- a/flutter_inappwebview_windows/windows/types/channel_delegate.cpp +++ b/flutter_inappwebview_windows/windows/types/channel_delegate.cpp @@ -3,6 +3,8 @@ #include "channel_delegate.h" +#include "../utils/util.h" + namespace flutter_inappwebview_plugin { ChannelDelegate::ChannelDelegate(flutter::BinaryMessenger* messenger, const std::string& name) : messenger(messenger) diff --git a/flutter_inappwebview_windows/windows/types/channel_delegate.h b/flutter_inappwebview_windows/windows/types/channel_delegate.h index 79c1b5d9..c637e02f 100644 --- a/flutter_inappwebview_windows/windows/types/channel_delegate.h +++ b/flutter_inappwebview_windows/windows/types/channel_delegate.h @@ -3,11 +3,6 @@ #include -#include -#include - -#include "../flutter_inappwebview_windows_base_plugin.h" - namespace flutter_inappwebview_plugin { class ChannelDelegate diff --git a/flutter_inappwebview_windows/windows/types/navigation_action.cpp b/flutter_inappwebview_windows/windows/types/navigation_action.cpp index 9cb94398..9541dcdb 100644 --- a/flutter_inappwebview_windows/windows/types/navigation_action.cpp +++ b/flutter_inappwebview_windows/windows/types/navigation_action.cpp @@ -4,7 +4,7 @@ namespace flutter_inappwebview_plugin { - NavigationAction::NavigationAction(std::shared_ptr request, bool isForMainFrame) + NavigationAction::NavigationAction(std::shared_ptr request, const bool& isForMainFrame) : request(std::move(request)), isForMainFrame(isForMainFrame) { diff --git a/flutter_inappwebview_windows/windows/types/navigation_action.h b/flutter_inappwebview_windows/windows/types/navigation_action.h index 1b48753b..974b4478 100644 --- a/flutter_inappwebview_windows/windows/types/navigation_action.h +++ b/flutter_inappwebview_windows/windows/types/navigation_action.h @@ -13,7 +13,7 @@ namespace flutter_inappwebview_plugin const std::shared_ptr request; const bool isForMainFrame; - NavigationAction(std::shared_ptr request, bool isForMainFrame); + NavigationAction(std::shared_ptr request, const bool& isForMainFrame); ~NavigationAction() = default; flutter::EncodableMap toEncodableMap(); }; diff --git a/flutter_inappwebview_windows/windows/types/url_request.cpp b/flutter_inappwebview_windows/windows/types/url_request.cpp index ddd7317c..01789955 100644 --- a/flutter_inappwebview_windows/windows/types/url_request.cpp +++ b/flutter_inappwebview_windows/windows/types/url_request.cpp @@ -1,19 +1,20 @@ #include "url_request.h" -#include "../utils/util.h" +#include "../utils/flutter.h" namespace flutter_inappwebview_plugin { - URLRequest::URLRequest(std::optional url, std::optional method, std::optional> headers, std::optional> body) + URLRequest::URLRequest(const std::optional& url, const std::optional& method, + const std::optional>& headers, const std::optional>& 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(map, "url")), method(get_optional_fl_map_value(map, "method")), - headers(get_optional_fl_map_value(map, "headers")), + headers(get_optional_fl_map_value(map, "headers")), body(get_optional_fl_map_value>(map, "body")) { @@ -22,10 +23,10 @@ namespace flutter_inappwebview_plugin flutter::EncodableMap URLRequest::toEncodableMap() { return flutter::EncodableMap{ - {flutter::EncodableValue("url"), optional_to_fl_value(url)}, - {flutter::EncodableValue("method"), optional_to_fl_value(method)}, - {flutter::EncodableValue("headers"), optional_to_fl_value(headers)}, - {flutter::EncodableValue("body"), optional_to_fl_value(body)} + {make_fl_value("url"), make_fl_value(url)}, + {make_fl_value("method"), make_fl_value(method)}, + {make_fl_value("headers"), make_fl_value(headers)}, + {make_fl_value("body"), make_fl_value(body)} }; } } \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/url_request.h b/flutter_inappwebview_windows/windows/types/url_request.h index d05dac7a..0bebc7ad 100644 --- a/flutter_inappwebview_windows/windows/types/url_request.h +++ b/flutter_inappwebview_windows/windows/types/url_request.h @@ -15,8 +15,9 @@ namespace flutter_inappwebview_plugin const std::optional> headers; const std::optional> body; - URLRequest(std::optional url, std::optional method, std::optional> headers, std::optional> body); - URLRequest(const flutter::EncodableMap map); + URLRequest(const std::optional& url, const std::optional& method, + const std::optional>& headers, const std::optional>& body); + URLRequest(const flutter::EncodableMap& map); ~URLRequest() = default; flutter::EncodableMap toEncodableMap(); }; diff --git a/flutter_inappwebview_windows/windows/types/web_resource_error.cpp b/flutter_inappwebview_windows/windows/types/web_resource_error.cpp new file mode 100644 index 00000000..cdadc378 --- /dev/null +++ b/flutter_inappwebview_windows/windows/types/web_resource_error.cpp @@ -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(map, "description")), + type(get_fl_map_value(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)} + }; + } +} \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/web_resource_error.h b/flutter_inappwebview_windows/windows/types/web_resource_error.h new file mode 100644 index 00000000..42f6d797 --- /dev/null +++ b/flutter_inappwebview_windows/windows/types/web_resource_error.h @@ -0,0 +1,46 @@ +#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_ERROR_H_ +#define FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_ERROR_H_ + +#include + +#include + +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_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/web_resource_request.cpp b/flutter_inappwebview_windows/windows/types/web_resource_request.cpp new file mode 100644 index 00000000..c017e199 --- /dev/null +++ b/flutter_inappwebview_windows/windows/types/web_resource_request.cpp @@ -0,0 +1,32 @@ +#include "web_resource_request.h" + +#include "../utils/flutter.h" + +namespace flutter_inappwebview_plugin +{ + WebResourceRequest::WebResourceRequest(const std::optional& url, const std::optional& method, + const std::optional>& headers, const std::optional& isForMainFrame) + : url(url), method(method), headers(headers), isForMainFrame(isForMainFrame) + { + + } + + WebResourceRequest::WebResourceRequest(const flutter::EncodableMap& map) + : url(get_optional_fl_map_value(map, "url")), + method(get_optional_fl_map_value(map, "method")), + headers(get_optional_fl_map_value(map, "headers")), + isForMainFrame(get_optional_fl_map_value(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)} + }; + } +} \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/web_resource_request.h b/flutter_inappwebview_windows/windows/types/web_resource_request.h new file mode 100644 index 00000000..4f8ac07f --- /dev/null +++ b/flutter_inappwebview_windows/windows/types/web_resource_request.h @@ -0,0 +1,26 @@ +#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_REQUEST_H_ +#define FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_REQUEST_H_ + +#include + +#include + +namespace flutter_inappwebview_plugin +{ + class WebResourceRequest + { + public: + const std::optional url; + const std::optional method; + const std::optional> headers; + const std::optional isForMainFrame; + + WebResourceRequest(const std::optional& url, const std::optional& method, + const std::optional>& headers, const std::optional& isForMainFrame); + WebResourceRequest(const flutter::EncodableMap& map); + ~WebResourceRequest() = default; + flutter::EncodableMap toEncodableMap(); + }; +} + +#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_REQUEST_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/web_resource_response.cpp b/flutter_inappwebview_windows/windows/types/web_resource_response.cpp new file mode 100644 index 00000000..5d1d748d --- /dev/null +++ b/flutter_inappwebview_windows/windows/types/web_resource_response.cpp @@ -0,0 +1,25 @@ +#include "web_resource_response.h" + +#include "../utils/flutter.h" + +namespace flutter_inappwebview_plugin +{ + WebResourceResponse::WebResourceResponse(const std::optional& statusCode) + : statusCode(statusCode) + { + + } + + WebResourceResponse::WebResourceResponse(const flutter::EncodableMap& map) + : statusCode(get_optional_fl_map_value(map, "statusCode")) + { + + } + + flutter::EncodableMap WebResourceResponse::toEncodableMap() + { + return flutter::EncodableMap{ + {make_fl_value("statusCode"), make_fl_value(statusCode)} + }; + } +} \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/types/web_resource_response.h b/flutter_inappwebview_windows/windows/types/web_resource_response.h new file mode 100644 index 00000000..caed73b3 --- /dev/null +++ b/flutter_inappwebview_windows/windows/types/web_resource_response.h @@ -0,0 +1,22 @@ +#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_RESPONSE_H_ +#define FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_RESPONSE_H_ + +#include + +#include + +namespace flutter_inappwebview_plugin +{ + class WebResourceResponse + { + public: + const std::optional statusCode; + + WebResourceResponse(const std::optional& statusCode); + WebResourceResponse(const flutter::EncodableMap& map); + ~WebResourceResponse() = default; + flutter::EncodableMap toEncodableMap(); + }; +} + +#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_WEB_RESOURCE_RESPONSE_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/utils/flutter.h b/flutter_inappwebview_windows/windows/utils/flutter.h new file mode 100644 index 00000000..e08ac630 --- /dev/null +++ b/flutter_inappwebview_windows/windows/utils/flutter.h @@ -0,0 +1,77 @@ +#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_ +#define FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_ + +#include +#include +#include + +#include "util.h" + +namespace flutter_inappwebview_plugin +{ + static inline flutter::EncodableValue make_fl_value() + { + return flutter::EncodableValue(); + } + + template + static inline flutter::EncodableValue make_fl_value(const T& val) + { + return flutter::EncodableValue(val); + } + + template + static inline flutter::EncodableValue make_fl_value(const T* val) + { + return val == nullptr ? make_fl_value() : flutter::EncodableValue(val); + } + + template + static inline flutter::EncodableValue make_fl_value(const std::optional& optional) + { + return optional.has_value() ? make_fl_value(optional.value()) : make_fl_value(); + } + + static inline flutter::EncodableValue make_fl_value(const std::optional>& 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 + static inline T get_fl_map_value(const flutter::EncodableMap& map, const char* string) + { + return std::get(map.at(make_fl_value(string))); + } + + template + static inline std::optional get_optional_fl_map_value(const flutter::EncodableMap& map, const char* string) + { + return make_pointer_optional(std::get_if(&map.at(make_fl_value(string)))); + } + + template + static inline std::optional> get_optional_fl_map_value(const flutter::EncodableMap& map, const char* string) + { + auto flMap = std::get_if(&map.at(make_fl_value(string))); + if (flMap) { + auto mapValue = std::map{}; + for (auto itr = flMap->begin(); itr != flMap->end(); itr++) + { + mapValue.insert({ std::get(itr->first), std::get(itr->second) }); + } + return make_pointer_optional>(&mapValue); + } + return std::nullopt; + } +} + +#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_ \ No newline at end of file diff --git a/flutter_inappwebview_windows/windows/utils/util.h b/flutter_inappwebview_windows/windows/utils/util.h index 843401f3..34562bce 100644 --- a/flutter_inappwebview_windows/windows/utils/util.h +++ b/flutter_inappwebview_windows/windows/utils/util.h @@ -22,52 +22,7 @@ namespace flutter_inappwebview_plugin return value == nullptr ? std::nullopt : std::make_optional(*value); } - template - static inline T get_fl_map_value(const flutter::EncodableMap map, const char* string) - { - return std::get(map.at(flutter::EncodableValue(string))); - } - - template - static inline std::optional get_optional_fl_map_value(const flutter::EncodableMap map, const char* string) - { - return make_pointer_optional(std::get_if(&map.at(flutter::EncodableValue(string)))); - } - - static inline std::optional> get_optional_fl_map_value(const flutter::EncodableMap map, const char* string) - { - auto mapValue = std::map{}; - auto flMap = std::get_if(&map.at(flutter::EncodableValue(string))); - if (flMap) { - for (auto itr = flMap->begin(); itr != flMap->end(); itr++) - { - mapValue.insert({ std::get(itr->first), std::get(itr->second) }); - } - } - return make_pointer_optional>(&mapValue); - } - - template - static inline flutter::EncodableValue optional_to_fl_value(const std::optional optional) - { - return optional.has_value() ? flutter::EncodableValue(optional.value()) : flutter::EncodableValue(); - } - - static inline flutter::EncodableValue optional_to_fl_value(const std::optional> 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 var) + static inline std::string variant_to_string(const std::variant& var) { return std::visit([](auto&& arg) { using T = std::decay_t; @@ -79,6 +34,19 @@ namespace flutter_inappwebview_plugin static_assert(always_false_v, "non-exhaustive visitor!"); }, var); } + + template + static inline bool map_contains(const std::map& map, const K& key) + { + return map.find(key) != map.end(); + } + + template + static inline T map_at_or_null(const std::map& map, const K& key) + { + auto itr = map.find(key); + return itr != map.end() ? itr->second : nullptr; + } } #endif //FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_H_ \ No newline at end of file