windows: completed initial javascript handler communication and user scripts support, added support for loadFile and loadData
This commit is contained in:
parent
9a5dae03ba
commit
a4c044a0f1
|
@ -518,7 +518,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))
|
||||
///- Windows ([Official API - ICoreWebView2.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].
|
||||
|
@ -527,7 +527,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))
|
||||
///- Windows ([Official API - ICoreWebView2.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.
|
||||
|
@ -540,7 +540,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))
|
||||
///- Windows ([Official API - ICoreWebView2.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.
|
||||
|
@ -559,7 +559,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))
|
||||
///- Windows ([Official API - ICoreWebView2.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) {}
|
||||
|
||||
|
@ -899,7 +899,7 @@ abstract class PlatformInAppBrowserEvents {
|
|||
///- Android native WebView ([Official API - WebViewClient.doUpdateVisitedHistory](https://developer.android.com/reference/android/webkit/WebViewClient#doUpdateVisitedHistory(android.webkit.WebView,%20java.lang.String,%20boolean)))
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows ([Official API - IWebView2WebView.add_HistoryChanged](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#add_historychanged))
|
||||
///- Windows ([Official API - ICoreWebView2.add_HistoryChanged](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#add_historychanged))
|
||||
void onUpdateVisitedHistory(WebUri? url, bool? isReload) {}
|
||||
|
||||
///Use [onPrintRequest] instead
|
||||
|
@ -969,7 +969,7 @@ abstract class PlatformInAppBrowserEvents {
|
|||
///- Android native WebView ([Official API - WebChromeClient.onReceivedTitle](https://developer.android.com/reference/android/webkit/WebChromeClient#onReceivedTitle(android.webkit.WebView,%20java.lang.String)))
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows ([Official API - IWebView2WebView.add_DocumentTitleChanged](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#add_documenttitlechanged))
|
||||
///- Windows ([Official API - ICoreWebView2.add_DocumentTitleChanged](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#add_documenttitlechanged))
|
||||
void onTitleChanged(String? title) {}
|
||||
|
||||
///Event fired to respond to the results of an over-scroll operation.
|
||||
|
|
|
@ -134,7 +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/icorewebview2?view=webview2-1.0.2210.55#get_source))
|
||||
///- Windows ([Official API - ICoreWebView2.get_Source](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#get_source))
|
||||
///{@endtemplate}
|
||||
Future<WebUri?> getUrl() {
|
||||
throw UnimplementedError(
|
||||
|
@ -151,7 +151,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- iOS ([Official API - WKWebView.title](https://developer.apple.com/documentation/webkit/wkwebview/1415015-title))
|
||||
///- MacOS ([Official API - WKWebView.title](https://developer.apple.com/documentation/webkit/wkwebview/1415015-title))
|
||||
///- Web
|
||||
///- Windows ([Official API - IWebView2WebView.get_DocumentTitle](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#get_documenttitle))
|
||||
///- Windows ([Official API - ICoreWebView2.get_DocumentTitle](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#get_documenttitle))
|
||||
///{@endtemplate}
|
||||
Future<String?> getTitle() {
|
||||
throw UnimplementedError(
|
||||
|
@ -274,11 +274,14 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///Specify a directory to give WebView permission to read additional files in the specified directory.
|
||||
///**NOTE**: available only on iOS and MacOS.
|
||||
///
|
||||
///**NOTE for Windows**: only the [data] parameter is used.
|
||||
///
|
||||
///**Officially Supported Platforms/Implementations**:
|
||||
///- Android native WebView ([Official API - WebView.loadDataWithBaseURL](https://developer.android.com/reference/android/webkit/WebView#loadDataWithBaseURL(java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String)))
|
||||
///- iOS ([Official API - WKWebView.loadHTMLString](https://developer.apple.com/documentation/webkit/wkwebview/1415004-loadhtmlstring) or [Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1415011-load))
|
||||
///- MacOS ([Official API - WKWebView.loadHTMLString](https://developer.apple.com/documentation/webkit/wkwebview/1415004-loadhtmlstring) or [Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1415011-load))
|
||||
///- Web
|
||||
///- Windows ([Official API - ICoreWebView2.NavigateToString](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#navigatetostring))
|
||||
///{@endtemplate}
|
||||
Future<void> loadData(
|
||||
{required String data,
|
||||
|
@ -330,6 +333,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- iOS ([Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1414954-load))
|
||||
///- MacOS ([Official API - WKWebView.load](https://developer.apple.com/documentation/webkit/wkwebview/1414954-load))
|
||||
///- Web
|
||||
///- Windows ([Official API - ICoreWebView2.Navigate](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#navigate))
|
||||
///{@endtemplate}
|
||||
Future<void> loadFile({required String assetFilePath}) {
|
||||
throw UnimplementedError(
|
||||
|
@ -346,7 +350,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- iOS ([Official API - WKWebView.reload](https://developer.apple.com/documentation/webkit/wkwebview/1414969-reload))
|
||||
///- MacOS ([Official API - WKWebView.reload](https://developer.apple.com/documentation/webkit/wkwebview/1414969-reload))
|
||||
///- Web ([Official API - Location.reload](https://developer.mozilla.org/en-US/docs/Web/API/Location/reload))
|
||||
///- Windows ([Official API - IWebView2WebView.Reload](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#reload))
|
||||
///- Windows ([Official API - ICoreWebView2.Reload](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#reload))
|
||||
///{@endtemplate}
|
||||
Future<void> reload() {
|
||||
throw UnimplementedError(
|
||||
|
@ -363,7 +367,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- iOS ([Official API - WKWebView.goBack](https://developer.apple.com/documentation/webkit/wkwebview/1414952-goback))
|
||||
///- MacOS ([Official API - WKWebView.goBack](https://developer.apple.com/documentation/webkit/wkwebview/1414952-goback))
|
||||
///- Web ([Official API - History.back](https://developer.mozilla.org/en-US/docs/Web/API/History/back))
|
||||
///- Windows ([Official API - IWebView2WebView.GoBack](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#goback))
|
||||
///- Windows ([Official API - ICoreWebView2.GoBack](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#goback))
|
||||
///{@endtemplate}
|
||||
Future<void> goBack() {
|
||||
throw UnimplementedError(
|
||||
|
@ -377,7 +381,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- Android native WebView ([Official API - WebView.canGoBack](https://developer.android.com/reference/android/webkit/WebView#canGoBack()))
|
||||
///- iOS ([Official API - WKWebView.canGoBack](https://developer.apple.com/documentation/webkit/wkwebview/1414966-cangoback))
|
||||
///- MacOS ([Official API - WKWebView.canGoBack](https://developer.apple.com/documentation/webkit/wkwebview/1414966-cangoback))
|
||||
///- Windows ([Official API - IWebView2WebView.get_CanGoBack](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#get_cangoback))
|
||||
///- Windows ([Official API - ICoreWebView2.get_CanGoBack](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#get_cangoback))
|
||||
///{@endtemplate}
|
||||
Future<bool> canGoBack() {
|
||||
throw UnimplementedError(
|
||||
|
@ -394,7 +398,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- iOS ([Official API - WKWebView.goForward](https://developer.apple.com/documentation/webkit/wkwebview/1414993-goforward))
|
||||
///- MacOS ([Official API - WKWebView.goForward](https://developer.apple.com/documentation/webkit/wkwebview/1414993-goforward))
|
||||
///- Web ([Official API - History.forward](https://developer.mozilla.org/en-US/docs/Web/API/History/forward))
|
||||
///- Windows ([Official API - IWebView2WebView.GoForward](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#goforward))
|
||||
///- Windows ([Official API - ICoreWebView2.GoForward](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#goforward))
|
||||
///{@endtemplate}
|
||||
Future<void> goForward() {
|
||||
throw UnimplementedError(
|
||||
|
@ -408,7 +412,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- Android native WebView ([Official API - WebView.canGoForward](https://developer.android.com/reference/android/webkit/WebView#canGoForward()))
|
||||
///- iOS ([Official API - WKWebView.canGoForward](https://developer.apple.com/documentation/webkit/wkwebview/1414962-cangoforward))
|
||||
///- MacOS ([Official API - WKWebView.canGoForward](https://developer.apple.com/documentation/webkit/wkwebview/1414962-cangoforward))
|
||||
///- Windows ([Official API - IWebView2WebView.get_CanGoForward](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#get_cangoforward))
|
||||
///- Windows ([Official API - ICoreWebView2.get_CanGoForward](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#get_cangoforward))
|
||||
///{@endtemplate}
|
||||
Future<bool> canGoForward() {
|
||||
throw UnimplementedError(
|
||||
|
@ -487,7 +491,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- iOS ([Official API - WKWebView.stopLoading](https://developer.apple.com/documentation/webkit/wkwebview/1414981-stoploading))
|
||||
///- MacOS ([Official API - WKWebView.stopLoading](https://developer.apple.com/documentation/webkit/wkwebview/1414981-stoploading))
|
||||
///- Web ([Official API - Window.stop](https://developer.mozilla.org/en-US/docs/Web/API/Window/stop))
|
||||
///- Windows ([Official API - IWebView2WebView.Stop](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#stop))
|
||||
///- Windows ([Official API - ICoreWebView2.Stop](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#stop))
|
||||
///{@endtemplate}
|
||||
Future<void> stopLoading() {
|
||||
throw UnimplementedError(
|
||||
|
@ -517,7 +521,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- iOS ([Official API - WKWebView.evaluateJavascript](https://developer.apple.com/documentation/webkit/wkwebview/3656442-evaluatejavascript))
|
||||
///- MacOS ([Official API - WKWebView.evaluateJavascript](https://developer.apple.com/documentation/webkit/wkwebview/3656442-evaluatejavascript))
|
||||
///- Web ([Official API - Window.eval](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval?retiredLocale=it))
|
||||
///- Windows ([Official API - IWebView2WebView.ExecuteScript](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#executescript))
|
||||
///- Windows ([Official API - ICoreWebView2.ExecuteScript](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#executescript))
|
||||
///{@endtemplate}
|
||||
Future<dynamic> evaluateJavascript(
|
||||
{required String source, ContentWorld? contentWorld}) {
|
||||
|
@ -1189,6 +1193,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- Android native WebView
|
||||
///- iOS ([Official API - WKUserContentController.addUserScript](https://developer.apple.com/documentation/webkit/wkusercontentcontroller/1537448-adduserscript))
|
||||
///- MacOS ([Official API - WKUserContentController.addUserScript](https://developer.apple.com/documentation/webkit/wkusercontentcontroller/1537448-adduserscript))
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
Future<void> addUserScript({required UserScript userScript}) {
|
||||
throw UnimplementedError(
|
||||
|
@ -1206,6 +1211,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
Future<void> addUserScripts({required List<UserScript> userScripts}) {
|
||||
throw UnimplementedError(
|
||||
|
@ -1225,6 +1231,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
Future<bool> removeUserScript({required UserScript userScript}) {
|
||||
throw UnimplementedError(
|
||||
|
@ -1243,6 +1250,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
Future<void> removeUserScriptsByGroupName({required String groupName}) {
|
||||
throw UnimplementedError(
|
||||
|
@ -1261,6 +1269,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
Future<void> removeUserScripts({required List<UserScript> userScripts}) {
|
||||
throw UnimplementedError(
|
||||
|
@ -1278,6 +1287,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- Android native WebView
|
||||
///- iOS ([Official API - WKUserContentController.removeAllUserScripts](https://developer.apple.com/documentation/webkit/wkusercontentcontroller/1536540-removealluserscripts))
|
||||
///- MacOS ([Official API - WKUserContentController.removeAllUserScripts](https://developer.apple.com/documentation/webkit/wkusercontentcontroller/1536540-removealluserscripts))
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
Future<void> removeAllUserScripts() {
|
||||
throw UnimplementedError(
|
||||
|
@ -1291,6 +1301,7 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
|
|||
///- Android native WebView
|
||||
///- iOS
|
||||
///- MacOS
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
bool hasUserScript({required UserScript userScript}) {
|
||||
throw UnimplementedError(
|
||||
|
|
|
@ -55,7 +55,7 @@ class PlatformWebViewCreationParams<T> {
|
|||
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview))
|
||||
///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455621-webview))
|
||||
///- Web
|
||||
///- Windows ([Official API - IWebView2WebView.add_NavigationStarting](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/iwebview2webview?view=webview2-0.8.355#add_navigationstarting))
|
||||
///- Windows ([Official API - ICoreWebView2.add_NavigationStarting](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/iwebview2webview?view=webview2-0.8.355#add_navigationstarting))
|
||||
///{@endtemplate}
|
||||
final void Function(T controller, WebUri? url)? onLoadStart;
|
||||
|
||||
|
@ -70,7 +70,7 @@ class PlatformWebViewCreationParams<T> {
|
|||
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview))
|
||||
///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview))
|
||||
///- Web ([Official API - Window.onload](https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event))
|
||||
///- Windows ([Official API - IWebView2WebView.add_NavigationCompleted](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/iwebview2webview?view=webview2-0.8.355#add_navigationcompleted))
|
||||
///- Windows ([Official API - ICoreWebView2.add_NavigationCompleted](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/iwebview2webview?view=webview2-0.8.355#add_navigationcompleted))
|
||||
///{@endtemplate}
|
||||
final void Function(T controller, WebUri? url)? onLoadStop;
|
||||
|
||||
|
@ -86,7 +86,7 @@ class PlatformWebViewCreationParams<T> {
|
|||
///- Android native WebView ([Official API - WebViewClient.onReceivedError](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedError(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20android.webkit.WebResourceError)))
|
||||
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455623-webview))
|
||||
///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455623-webview))
|
||||
///- Windows ([Official API - IWebView2WebView.add_NavigationCompleted](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/iwebview2webview?view=webview2-0.8.355#add_navigationcompleted))
|
||||
///- Windows ([Official API - ICoreWebView2.add_NavigationCompleted](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/iwebview2webview?view=webview2-0.8.355#add_navigationcompleted))
|
||||
///{@endtemplate}
|
||||
final void Function(
|
||||
T controller, WebResourceRequest request, WebResourceError error)?
|
||||
|
@ -111,7 +111,7 @@ class PlatformWebViewCreationParams<T> {
|
|||
///- Android native WebView ([Official API - WebViewClient.onReceivedHttpError](https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedHttpError(android.webkit.WebView,%20android.webkit.WebResourceRequest,%20android.webkit.WebResourceResponse)))
|
||||
///- iOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview))
|
||||
///- MacOS ([Official API - WKNavigationDelegate.webView](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview))
|
||||
///- Windows ([Official API - IWebView2WebView.add_NavigationCompleted](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/iwebview2webview?view=webview2-0.8.355#add_navigationcompleted))
|
||||
///- Windows ([Official API - ICoreWebView2.add_NavigationCompleted](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/iwebview2webview?view=webview2-0.8.355#add_navigationcompleted))
|
||||
///{@endtemplate}
|
||||
final void Function(T controller, WebResourceRequest request,
|
||||
WebResourceResponse errorResponse)? onReceivedHttpError;
|
||||
|
@ -504,7 +504,7 @@ class PlatformWebViewCreationParams<T> {
|
|||
///- iOS
|
||||
///- MacOS
|
||||
///- Web
|
||||
///- Windows ([Official API - IWebView2WebView.add_HistoryChanged](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#add_historychanged))
|
||||
///- Windows ([Official API - ICoreWebView2.add_HistoryChanged](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#add_historychanged))
|
||||
///{@endtemplate}
|
||||
final void Function(T controller, WebUri? url, bool? isReload)?
|
||||
onUpdateVisitedHistory;
|
||||
|
@ -599,7 +599,7 @@ class PlatformWebViewCreationParams<T> {
|
|||
///- iOS
|
||||
///- MacOS
|
||||
///- Web
|
||||
///- Windows ([Official API - IWebView2WebView.add_DocumentTitleChanged](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#add_documenttitlechanged))
|
||||
///- Windows ([Official API - ICoreWebView2.add_DocumentTitleChanged](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2?view=webview2-1.0.2210.55#add_documenttitlechanged))
|
||||
///{@endtemplate}
|
||||
final void Function(T controller, String? title)? onTitleChanged;
|
||||
|
||||
|
@ -1059,6 +1059,7 @@ class PlatformWebViewCreationParams<T> {
|
|||
///- iOS
|
||||
///- MacOS
|
||||
///- Web
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
final URLRequest? initialUrlRequest;
|
||||
|
||||
|
@ -1070,6 +1071,7 @@ class PlatformWebViewCreationParams<T> {
|
|||
///- iOS
|
||||
///- MacOS
|
||||
///- Web
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
final String? initialFile;
|
||||
|
||||
|
@ -1081,6 +1083,7 @@ class PlatformWebViewCreationParams<T> {
|
|||
///- iOS
|
||||
///- MacOS
|
||||
///- Web
|
||||
///- Windows
|
||||
///{@endtemplate}
|
||||
final InAppWebViewInitialData? initialData;
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ list(APPEND PLUGIN_SOURCES
|
|||
"utils/strconv.h"
|
||||
"utils/map.h"
|
||||
"utils/vector.h"
|
||||
"utils/string.h"
|
||||
"utils/util.h"
|
||||
"utils/flutter.h"
|
||||
"types/channel_delegate.cpp"
|
||||
|
@ -80,6 +81,7 @@ list(APPEND PLUGIN_SOURCES
|
|||
"custom_platform_view/util/string_converter.cc"
|
||||
"custom_platform_view/util/string_converter.h"
|
||||
"custom_platform_view/util/swizzle.h"
|
||||
"plugin_scripts_js/plugin_scripts_util.h"
|
||||
"plugin_scripts_js/javascript_bridge_js.cpp"
|
||||
"plugin_scripts_js/javascript_bridge_js.h"
|
||||
"in_app_webview/user_content_controller.cpp"
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace flutter_inappwebview_plugin
|
|||
struct InAppBrowserCreationParams
|
||||
{
|
||||
const std::string id;
|
||||
const std::optional<URLRequest> urlRequest;
|
||||
const std::optional<std::shared_ptr<URLRequest>> urlRequest;
|
||||
const std::shared_ptr<InAppBrowserSettings> initialSettings;
|
||||
const std::shared_ptr<InAppWebViewSettings> initialWebViewSettings;
|
||||
};
|
||||
|
@ -35,7 +35,7 @@ namespace flutter_inappwebview_plugin
|
|||
|
||||
const FlutterInappwebviewWindowsPlugin* plugin;
|
||||
const std::string id;
|
||||
const std::optional<URLRequest> initialUrlRequest;
|
||||
const std::optional<std::shared_ptr<URLRequest>> initialUrlRequest;
|
||||
std::unique_ptr<InAppWebView> webView;
|
||||
std::unique_ptr<InAppBrowserChannelDelegate> channelDelegate;
|
||||
const std::shared_ptr<InAppBrowserSettings> settings;
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace flutter_inappwebview_plugin
|
|||
{
|
||||
auto id = get_fl_map_value<std::string>(*arguments, "id");
|
||||
auto urlRequestMap = get_optional_fl_map_value<flutter::EncodableMap>(*arguments, "urlRequest");
|
||||
std::optional<URLRequest> urlRequest = urlRequestMap.has_value() ? std::make_optional<URLRequest>(urlRequestMap.value()) : std::optional<URLRequest>{};
|
||||
std::optional<std::shared_ptr<URLRequest>> urlRequest = urlRequestMap.has_value() ? std::make_shared<URLRequest>(urlRequestMap.value()) : std::optional<std::shared_ptr<URLRequest>>{};
|
||||
|
||||
auto settingsMap = get_fl_map_value<flutter::EncodableMap>(*arguments, "settings");
|
||||
auto initialSettings = std::make_unique<InAppBrowserSettings>(settingsMap);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <Shlwapi.h>
|
||||
#include <WebView2EnvironmentOptions.h>
|
||||
|
@ -9,7 +10,9 @@
|
|||
#include "../types/web_resource_error.h"
|
||||
#include "../types/web_resource_request.h"
|
||||
#include "../utils/log.h"
|
||||
#include "../utils/map.h"
|
||||
#include "../utils/strconv.h"
|
||||
#include "../utils/string.h"
|
||||
#include "in_app_webview.h"
|
||||
#include "in_app_webview_manager.h"
|
||||
|
||||
|
@ -246,14 +249,14 @@ namespace flutter_inappwebview_plugin
|
|||
{
|
||||
callShouldOverrideUrlLoading_ = false;
|
||||
if (actionPolicy == NavigationActionPolicy::allow) {
|
||||
loadUrl(*urlRequest);
|
||||
loadUrl(urlRequest);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
auto defaultBehaviour = [this, urlRequest](const std::optional<NavigationActionPolicy> actionPolicy)
|
||||
auto defaultBehaviour = [this, urlRequest](const std::optional<const NavigationActionPolicy> actionPolicy)
|
||||
{
|
||||
callShouldOverrideUrlLoading_ = false;
|
||||
loadUrl(*urlRequest);
|
||||
loadUrl(urlRequest);
|
||||
};
|
||||
callback->defaultBehaviour = defaultBehaviour;
|
||||
callback->error = [defaultBehaviour](const std::string& error_code, const std::string& error_message, const flutter::EncodableValue* error_details)
|
||||
|
@ -280,6 +283,11 @@ namespace flutter_inappwebview_plugin
|
|||
{
|
||||
isLoading_ = false;
|
||||
|
||||
if (userContentController) {
|
||||
evaluateJavascript(userContentController->generateWrappedCodeForDocumentEnd(), nullptr);
|
||||
}
|
||||
evaluateJavascript(PLATFORM_READY_JS_SOURCE, nullptr);
|
||||
|
||||
std::shared_ptr<NavigationAction> navigationAction;
|
||||
UINT64 navigationId;
|
||||
if (SUCCEEDED(args->get_NavigationId(&navigationId))) {
|
||||
|
@ -349,12 +357,61 @@ namespace flutter_inappwebview_plugin
|
|||
failedLog(webView->add_WebMessageReceived(Callback<ICoreWebView2WebMessageReceivedEventHandler>(
|
||||
[this](ICoreWebView2* sender, ICoreWebView2WebMessageReceivedEventArgs* args)
|
||||
{
|
||||
wil::unique_cotaskmem_string uri;
|
||||
args->get_Source(&uri);
|
||||
if (!channelDelegate) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
wil::unique_cotaskmem_string url;
|
||||
args->get_Source(&url);
|
||||
|
||||
wil::com_ptr<IUri> uri;
|
||||
failedLog(CreateUri(
|
||||
url.get(), // NULL terminated URI
|
||||
Uri_CREATE_ALLOW_RELATIVE, // Flags to control behavior
|
||||
0, // Reserved must be 0
|
||||
&uri));
|
||||
*/
|
||||
|
||||
wil::unique_cotaskmem_string json;
|
||||
if (succeededOrLog(args->get_WebMessageAsJson(&json))) {
|
||||
debugLog(json.get());
|
||||
auto message = nlohmann::json::parse(wide_to_ansi(json.get()));
|
||||
|
||||
if (message.is_object() && message.contains("name") && message.at("name").is_string() && message.contains("body") && message.at("body").is_object()) {
|
||||
auto name = message.at("name").get<std::string>();
|
||||
auto body = message.at("body").get<nlohmann::json>();
|
||||
|
||||
if (name.compare("callHandler") == 0 && body.contains("handlerName") && body.at("handlerName").is_string()) {
|
||||
auto handlerName = body.at("handlerName").get<std::string>();
|
||||
auto callHandlerID = body.at("_callHandlerID").is_number_integer() ? body.at("_callHandlerID").get<int64_t>() : 0;
|
||||
std::string handlerArgs = body.at("args").is_string() ? body.at("args").get<std::string>() : "";
|
||||
|
||||
auto callback = std::make_unique<WebViewChannelDelegate::CallJsHandlerCallback>();
|
||||
callback->defaultBehaviour = [this, callHandlerID](const std::optional<const flutter::EncodableValue*> response)
|
||||
{
|
||||
std::string json = "null";
|
||||
if (response.has_value() && !response.value()->IsNull()) {
|
||||
json = std::get<std::string>(*(response.value()));
|
||||
}
|
||||
|
||||
evaluateJavascript("if (window." + JAVASCRIPT_BRIDGE_NAME + "[" + std::to_string(callHandlerID) + "] != null) { \
|
||||
window." + JAVASCRIPT_BRIDGE_NAME + "[" + std::to_string(callHandlerID) + "].resolve(" + json + "); \
|
||||
delete window." + JAVASCRIPT_BRIDGE_NAME + "[" + std::to_string(callHandlerID) + "]; \
|
||||
}", nullptr);
|
||||
};
|
||||
callback->error = [this, callHandlerID](const std::string& error_code, const std::string& error_message, const flutter::EncodableValue* error_details)
|
||||
{
|
||||
auto errorMessage = error_code + ", " + error_message;
|
||||
debugLog(errorMessage);
|
||||
|
||||
evaluateJavascript("if (window." + JAVASCRIPT_BRIDGE_NAME + "[" + std::to_string(callHandlerID) + "] != null) { \
|
||||
window." + JAVASCRIPT_BRIDGE_NAME + "[" + std::to_string(callHandlerID) + "].reject(new Error('" + replace_all_copy(errorMessage, "\'", "\\'") + "')); \
|
||||
delete window." + JAVASCRIPT_BRIDGE_NAME + "[" + std::to_string(callHandlerID) + "]; \
|
||||
}", nullptr);
|
||||
};
|
||||
channelDelegate->onCallJsHandler(handlerName, handlerArgs, std::move(callback));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
@ -395,23 +452,23 @@ namespace flutter_inappwebview_plugin
|
|||
return webView && succeededOrLog(webView->get_DocumentTitle(&title)) ? wide_to_utf8(title.get()) : std::optional<std::string>{};
|
||||
}
|
||||
|
||||
void InAppWebView::loadUrl(const URLRequest& urlRequest) const
|
||||
void InAppWebView::loadUrl(const std::shared_ptr<URLRequest> urlRequest) const
|
||||
{
|
||||
if (!webView || !urlRequest.url.has_value()) {
|
||||
if (!webView || !urlRequest->url.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::wstring url = ansi_to_wide(urlRequest.url.value());
|
||||
std::wstring url = ansi_to_wide(urlRequest->url.value());
|
||||
|
||||
wil::com_ptr<ICoreWebView2Environment2> webViewEnv2;
|
||||
wil::com_ptr<ICoreWebView2_2> webView2;
|
||||
if (SUCCEEDED(webViewEnv->QueryInterface(IID_PPV_ARGS(&webViewEnv2))) && SUCCEEDED(webView->QueryInterface(IID_PPV_ARGS(&webView2)))) {
|
||||
wil::com_ptr<ICoreWebView2WebResourceRequest> webResourceRequest;
|
||||
std::wstring method = urlRequest.method.has_value() ? ansi_to_wide(urlRequest.method.value()) : L"GET";
|
||||
std::wstring method = urlRequest->method.has_value() ? ansi_to_wide(urlRequest->method.value()) : L"GET";
|
||||
|
||||
wil::com_ptr<IStream> postDataStream = nullptr;
|
||||
if (urlRequest.body.has_value()) {
|
||||
auto postData = std::string(urlRequest.body->begin(), urlRequest.body->end());
|
||||
if (urlRequest->body.has_value()) {
|
||||
auto postData = std::string(urlRequest->body->begin(), urlRequest->body->end());
|
||||
postDataStream = SHCreateMemStream(
|
||||
reinterpret_cast<const BYTE*>(postData.data()), static_cast<UINT>(postData.length()));
|
||||
}
|
||||
|
@ -427,8 +484,8 @@ namespace flutter_inappwebview_plugin
|
|||
if (method.compare(L"GET") != 0) {
|
||||
requestHeaders->SetHeader(L"Flutter-InAppWebView-Request-Method", method.c_str());
|
||||
}
|
||||
if (urlRequest.headers.has_value()) {
|
||||
auto& headers = urlRequest.headers.value();
|
||||
if (urlRequest->headers.has_value()) {
|
||||
auto& headers = urlRequest->headers.value();
|
||||
for (auto const& [key, val] : headers) {
|
||||
requestHeaders->SetHeader(ansi_to_wide(key).c_str(), ansi_to_wide(val).c_str());
|
||||
}
|
||||
|
@ -441,6 +498,37 @@ namespace flutter_inappwebview_plugin
|
|||
failedLog(webView->Navigate(url.c_str()));
|
||||
}
|
||||
|
||||
|
||||
void InAppWebView::loadFile(const std::string& assetFilePath) const
|
||||
{
|
||||
if (!webView) {
|
||||
return;
|
||||
}
|
||||
|
||||
WCHAR* buf = new WCHAR[32768];
|
||||
GetModuleFileName(NULL, buf, 32768);
|
||||
std::filesystem::path exeAbsPath = std::wstring(buf);
|
||||
delete[] buf;
|
||||
|
||||
std::filesystem::path flutterAssetPath("data/flutter_assets/" + assetFilePath);
|
||||
auto absAssetFilePath = exeAbsPath.parent_path() / flutterAssetPath;
|
||||
|
||||
if (!std::filesystem::exists(absAssetFilePath)) {
|
||||
debugLog(absAssetFilePath.native() + L" asset file cannot be found!");
|
||||
return;
|
||||
}
|
||||
failedLog(webView->Navigate(absAssetFilePath.c_str()));
|
||||
}
|
||||
|
||||
void InAppWebView::loadData(const std::string& data) const
|
||||
{
|
||||
if (!webView) {
|
||||
return;
|
||||
}
|
||||
|
||||
failedLog(webView->NavigateToString(ansi_to_wide(data).c_str()));
|
||||
}
|
||||
|
||||
void InAppWebView::reload() const
|
||||
{
|
||||
if (!webView) {
|
||||
|
@ -527,8 +615,11 @@ namespace flutter_inappwebview_plugin
|
|||
int64_t size = items->size();
|
||||
canGoBackOrForward_ = nextIndex >= 0 && nextIndex < size;
|
||||
}
|
||||
|
||||
if (completionHandler) {
|
||||
completionHandler(canGoBackOrForward_);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -544,13 +635,19 @@ namespace flutter_inappwebview_plugin
|
|||
void InAppWebView::getCopyBackForwardList(const std::function<void(std::unique_ptr<WebHistory>)> completionHandler) const
|
||||
{
|
||||
if (!webView) {
|
||||
if (completionHandler) {
|
||||
completionHandler(std::make_unique<WebHistory>(std::nullopt, std::nullopt));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
failedLog(webView->CallDevToolsProtocolMethod(L"Page.getNavigationHistory", L"{}", Callback<ICoreWebView2CallDevToolsProtocolMethodCompletedHandler>(
|
||||
[completionHandler](HRESULT errorCode, LPCWSTR returnObjectAsJson)
|
||||
{
|
||||
if (!completionHandler) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (errorCode == S_OK) {
|
||||
auto historyJson = nlohmann::json::parse(wide_to_ansi(returnObjectAsJson));
|
||||
|
||||
|
@ -585,7 +682,7 @@ namespace flutter_inappwebview_plugin
|
|||
).Get()));
|
||||
}
|
||||
|
||||
void InAppWebView::evaluateJavascript(const std::string& source, std::function<void(std::string)> completionHanlder) const
|
||||
void InAppWebView::evaluateJavascript(const std::string& source, const std::function<void(std::string)> completionHanlder) const
|
||||
{
|
||||
failedLog(webView->ExecuteScript(ansi_to_wide(source).c_str(),
|
||||
Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
|
||||
|
@ -594,11 +691,51 @@ namespace flutter_inappwebview_plugin
|
|||
if (error != S_OK) {
|
||||
debugLog(error);
|
||||
}
|
||||
|
||||
if (completionHanlder) {
|
||||
completionHanlder(wide_to_ansi(result));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}).Get()));
|
||||
}
|
||||
|
||||
void InAppWebView::addUserScript(const std::shared_ptr<UserScript> userScript) const
|
||||
{
|
||||
if (!userContentController) {
|
||||
return;
|
||||
}
|
||||
|
||||
userContentController->addUserOnlyScript(userScript);
|
||||
}
|
||||
|
||||
void InAppWebView::removeUserScript(const int64_t index, const std::shared_ptr<UserScript> userScript) const
|
||||
{
|
||||
if (!userContentController) {
|
||||
return;
|
||||
}
|
||||
|
||||
userContentController->removeUserOnlyScriptAt(index, userScript->injectionTime);
|
||||
}
|
||||
|
||||
void InAppWebView::removeUserScriptsByGroupName(const std::string& groupName) const
|
||||
{
|
||||
if (!userContentController) {
|
||||
return;
|
||||
}
|
||||
|
||||
userContentController->removeUserOnlyScriptsByGroupName(groupName);
|
||||
}
|
||||
|
||||
void InAppWebView::removeAllUserScripts() const
|
||||
{
|
||||
if (!userContentController) {
|
||||
return;
|
||||
}
|
||||
|
||||
userContentController->removeAllUserOnlyScripts();
|
||||
}
|
||||
|
||||
// flutter_view
|
||||
void InAppWebView::setSurfaceSize(size_t width, size_t height, float scale_factor)
|
||||
{
|
||||
|
|
|
@ -132,7 +132,9 @@ namespace flutter_inappwebview_plugin
|
|||
void prepare();
|
||||
std::optional<std::string> getUrl() const;
|
||||
std::optional<std::string> getTitle() const;
|
||||
void loadUrl(const URLRequest& urlRequest) const;
|
||||
void loadUrl(const std::shared_ptr<URLRequest> urlRequest) const;
|
||||
void loadFile(const std::string& assetFilePath) const;
|
||||
void loadData(const std::string& data) const;
|
||||
void reload() const;
|
||||
void goBack();
|
||||
bool canGoBack() const;
|
||||
|
@ -145,8 +147,12 @@ namespace flutter_inappwebview_plugin
|
|||
return isLoading_;
|
||||
}
|
||||
void stopLoading() const;
|
||||
void evaluateJavascript(const std::string& source, std::function<void(std::string)> completionHanlder) const;
|
||||
void evaluateJavascript(const std::string& source, const std::function<void(std::string)> completionHanlder) const;
|
||||
void getCopyBackForwardList(const std::function<void(std::unique_ptr<WebHistory>)> completionHandler) const;
|
||||
void addUserScript(const std::shared_ptr<UserScript> userScript) const;
|
||||
void removeUserScript(const int64_t index, const std::shared_ptr<UserScript> userScript) const;
|
||||
void removeUserScriptsByGroupName(const std::string& groupName) const;
|
||||
void removeAllUserScripts() const;
|
||||
|
||||
static bool isSslError(const COREWEBVIEW2_WEB_ERROR_STATUS& webErrorStatus);
|
||||
private:
|
||||
|
|
|
@ -76,6 +76,8 @@ namespace flutter_inappwebview_plugin
|
|||
|
||||
auto settingsMap = get_fl_map_value<flutter::EncodableMap>(*arguments, "initialSettings");
|
||||
auto urlRequestMap = get_optional_fl_map_value<flutter::EncodableMap>(*arguments, "initialUrlRequest");
|
||||
auto initialFile = get_optional_fl_map_value<std::string>(*arguments, "initialFile");
|
||||
auto initialDataMap = get_optional_fl_map_value<flutter::EncodableMap>(*arguments, "initialData");
|
||||
|
||||
auto hwnd = CreateWindowEx(0, windowClass_.lpszClassName, L"", 0, CW_DEFAULT,
|
||||
CW_DEFAULT, 0, 0, HWND_MESSAGE, nullptr,
|
||||
|
@ -98,10 +100,16 @@ namespace flutter_inappwebview_plugin
|
|||
std::move(webViewEnv), std::move(webViewController), std::move(webViewCompositionController)
|
||||
);
|
||||
|
||||
std::optional<URLRequest> urlRequest = urlRequestMap.has_value() ? std::make_optional<URLRequest>(urlRequestMap.value()) : std::optional<URLRequest>{};
|
||||
std::optional<std::shared_ptr<URLRequest>> urlRequest = urlRequestMap.has_value() ? std::make_shared<URLRequest>(urlRequestMap.value()) : std::optional<std::shared_ptr<URLRequest>>{};
|
||||
if (urlRequest.has_value()) {
|
||||
inAppWebView->loadUrl(urlRequest.value());
|
||||
}
|
||||
else if (initialFile.has_value()) {
|
||||
inAppWebView->loadFile(initialFile.value());
|
||||
}
|
||||
else if (initialDataMap.has_value()) {
|
||||
inAppWebView->loadData(get_fl_map_value<std::string>(initialDataMap.value(), "data"));
|
||||
}
|
||||
|
||||
auto customPlatformView = std::make_unique<CustomPlatformView>(plugin->registrar->messenger(),
|
||||
plugin->registrar->texture_registrar(),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <wil/wrl.h>
|
||||
|
||||
#include "../utils/log.h"
|
||||
#include "../utils/strconv.h"
|
||||
#include "../utils/string.h"
|
||||
#include "../utils/vector.h"
|
||||
#include "in_app_webview.h"
|
||||
#include "user_content_controller.h"
|
||||
|
@ -25,6 +25,18 @@ namespace flutter_inappwebview_plugin
|
|||
return;
|
||||
}
|
||||
|
||||
if (userScript->injectionTime == UserScriptInjectionTime::atDocumentStart && webView_) {
|
||||
failedLog(webView_->webView->AddScriptToExecuteOnDocumentCreated(ansi_to_wide(userScript->source).c_str(),
|
||||
Callback<ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler>(
|
||||
[userScript](HRESULT error, PCWSTR id) -> HRESULT
|
||||
{
|
||||
if (succeededOrLog(error)) {
|
||||
userScript->id = id;
|
||||
}
|
||||
return S_OK;
|
||||
}).Get()));
|
||||
}
|
||||
|
||||
userOnlyScripts_.at(userScript->injectionTime).push_back(std::move(userScript));
|
||||
}
|
||||
|
||||
|
@ -41,7 +53,11 @@ namespace flutter_inappwebview_plugin
|
|||
return;
|
||||
}
|
||||
|
||||
vector_remove_erase_el(userOnlyScripts_.at(userScript->injectionTime), std::move(userScript));
|
||||
if (webView_) {
|
||||
failedLog(webView_->webView->RemoveScriptToExecuteOnDocumentCreated(userScript->id.c_str()));
|
||||
}
|
||||
|
||||
vector_remove_erase(userOnlyScripts_.at(userScript->injectionTime), std::move(userScript));
|
||||
}
|
||||
|
||||
void UserContentController::removeUserOnlyScriptAt(const int64_t& index, const UserScriptInjectionTime& injectionTime)
|
||||
|
@ -52,13 +68,49 @@ namespace flutter_inappwebview_plugin
|
|||
return;
|
||||
}
|
||||
|
||||
auto& userScript = vec.at(index);
|
||||
if (userScript) {
|
||||
if (webView_) {
|
||||
failedLog(webView_->webView->RemoveScriptToExecuteOnDocumentCreated(userScript->id.c_str()));
|
||||
}
|
||||
vec.erase(vec.begin() + index);
|
||||
}
|
||||
}
|
||||
|
||||
void UserContentController::removeAllUserOnlyScripts()
|
||||
{
|
||||
userOnlyScripts_.at(UserScriptInjectionTime::atDocumentStart).clear();
|
||||
userOnlyScripts_.at(UserScriptInjectionTime::atDocumentEnd).clear();
|
||||
auto& userScriptsAtStart = userOnlyScripts_.at(UserScriptInjectionTime::atDocumentStart);
|
||||
auto& userScriptsAtEnd = userOnlyScripts_.at(UserScriptInjectionTime::atDocumentEnd);
|
||||
|
||||
if (webView_) {
|
||||
for (auto& userScript : userScriptsAtStart) {
|
||||
failedLog(webView_->webView->RemoveScriptToExecuteOnDocumentCreated(userScript->id.c_str()));
|
||||
}
|
||||
for (auto& userScript : userScriptsAtEnd) {
|
||||
failedLog(webView_->webView->RemoveScriptToExecuteOnDocumentCreated(userScript->id.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
userScriptsAtStart.clear();
|
||||
userScriptsAtEnd.clear();
|
||||
}
|
||||
|
||||
void UserContentController::removeUserOnlyScriptsByGroupName(const std::string& groupName)
|
||||
{
|
||||
std::vector<std::shared_ptr<UserScript>> userScriptsAtStart = userOnlyScripts_.at(UserScriptInjectionTime::atDocumentStart);
|
||||
std::vector<std::shared_ptr<UserScript>> userScriptsAtEnd = userOnlyScripts_.at(UserScriptInjectionTime::atDocumentEnd);
|
||||
|
||||
for (auto& userScript : userScriptsAtStart) {
|
||||
if (string_equals(groupName, userScript->groupName)) {
|
||||
removeUserOnlyScript(userScript);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& userScript : userScriptsAtEnd) {
|
||||
if (string_equals(groupName, userScript->groupName)) {
|
||||
removeUserOnlyScript(userScript);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<PluginScript>> UserContentController::getPluginScriptsAt(const UserScriptInjectionTime& injectionTime) const
|
||||
|
@ -66,13 +118,28 @@ namespace flutter_inappwebview_plugin
|
|||
return pluginScripts_.at(injectionTime);
|
||||
}
|
||||
|
||||
bool UserContentController::containsUserOnlyScript(std::shared_ptr<UserScript> userScript) const
|
||||
{
|
||||
if (!userScript) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return vector_contains(userOnlyScripts_.at(userScript->injectionTime), std::move(userScript));
|
||||
}
|
||||
|
||||
bool UserContentController::containsUserOnlyScriptByGroupName(const std::string& groupName) const
|
||||
{
|
||||
return vector_contains_if(userOnlyScripts_.at(UserScriptInjectionTime::atDocumentStart), [groupName](const std::shared_ptr<UserScript> userScript) { return string_equals(groupName, userScript->groupName); }) ||
|
||||
vector_contains_if(userOnlyScripts_.at(UserScriptInjectionTime::atDocumentEnd), [groupName](const std::shared_ptr<UserScript> userScript) { return string_equals(groupName, userScript->groupName); });
|
||||
}
|
||||
|
||||
void UserContentController::addPluginScript(std::shared_ptr<PluginScript> pluginScript)
|
||||
{
|
||||
if (!pluginScript || !webView_) {
|
||||
if (!pluginScript) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pluginScript->injectionTime == UserScriptInjectionTime::atDocumentStart) {
|
||||
if (pluginScript->injectionTime == UserScriptInjectionTime::atDocumentStart && webView_) {
|
||||
failedLog(webView_->webView->AddScriptToExecuteOnDocumentCreated(ansi_to_wide(pluginScript->source).c_str(),
|
||||
Callback<ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler>(
|
||||
[pluginScript](HRESULT error, PCWSTR id) -> HRESULT
|
||||
|
@ -96,19 +163,93 @@ namespace flutter_inappwebview_plugin
|
|||
|
||||
void UserContentController::removePluginScript(std::shared_ptr<PluginScript> pluginScript)
|
||||
{
|
||||
if (!pluginScript || !webView_) {
|
||||
if (!pluginScript) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (webView_) {
|
||||
failedLog(webView_->webView->RemoveScriptToExecuteOnDocumentCreated(pluginScript->id.c_str()));
|
||||
}
|
||||
|
||||
vector_remove_erase_el(pluginScripts_.at(pluginScript->injectionTime), std::move(pluginScript));
|
||||
vector_remove_erase(pluginScripts_.at(pluginScript->injectionTime), std::move(pluginScript));
|
||||
}
|
||||
|
||||
void UserContentController::removeAllPluginScripts()
|
||||
{
|
||||
pluginScripts_.at(UserScriptInjectionTime::atDocumentStart).clear();
|
||||
pluginScripts_.at(UserScriptInjectionTime::atDocumentEnd).clear();
|
||||
auto& pluginScriptsAtStart = pluginScripts_.at(UserScriptInjectionTime::atDocumentStart);
|
||||
auto& pluginScriptsAtEnd = pluginScripts_.at(UserScriptInjectionTime::atDocumentEnd);
|
||||
|
||||
if (webView_) {
|
||||
for (auto& pluginScript : pluginScriptsAtStart) {
|
||||
failedLog(webView_->webView->RemoveScriptToExecuteOnDocumentCreated(pluginScript->id.c_str()));
|
||||
}
|
||||
for (auto& pluginScript : pluginScriptsAtEnd) {
|
||||
failedLog(webView_->webView->RemoveScriptToExecuteOnDocumentCreated(pluginScript->id.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
pluginScriptsAtStart.clear();
|
||||
pluginScriptsAtEnd.clear();
|
||||
}
|
||||
|
||||
bool UserContentController::containsPluginScript(std::shared_ptr<PluginScript> pluginScript) const
|
||||
{
|
||||
if (!pluginScript) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return vector_contains(pluginScripts_.at(pluginScript->injectionTime), std::move(pluginScript));
|
||||
}
|
||||
|
||||
bool UserContentController::containsPluginScriptByGroupName(const std::string& groupName) const
|
||||
{
|
||||
return vector_contains_if(pluginScripts_.at(UserScriptInjectionTime::atDocumentStart), [groupName](const std::shared_ptr<PluginScript> pluginScript) { return string_equals(groupName, pluginScript->groupName); }) ||
|
||||
vector_contains_if(pluginScripts_.at(UserScriptInjectionTime::atDocumentEnd), [groupName](const std::shared_ptr<PluginScript> pluginScript) { return string_equals(groupName, pluginScript->groupName); });
|
||||
}
|
||||
|
||||
void UserContentController::removePluginScriptsByGroupName(const std::string& groupName)
|
||||
{
|
||||
std::vector<std::shared_ptr<PluginScript>> pluginScriptsAtStart = pluginScripts_.at(UserScriptInjectionTime::atDocumentStart);
|
||||
std::vector<std::shared_ptr<PluginScript>> pluginScriptsAtEnd = pluginScripts_.at(UserScriptInjectionTime::atDocumentEnd);
|
||||
|
||||
for (auto& pluginScript : pluginScriptsAtStart) {
|
||||
if (string_equals(groupName, pluginScript->groupName)) {
|
||||
removePluginScript(pluginScript);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& pluginScript : pluginScriptsAtEnd) {
|
||||
if (string_equals(groupName, pluginScript->groupName)) {
|
||||
removePluginScript(pluginScript);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string UserContentController::generatePluginScriptsCodeAt(const UserScriptInjectionTime& injectionTime) const
|
||||
{
|
||||
std::string code;
|
||||
std::vector<std::shared_ptr<PluginScript>> pluginScripts = pluginScripts_.at(injectionTime);
|
||||
for (auto& pluginScript : pluginScripts) {
|
||||
code += ";" + pluginScript->source;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
std::string UserContentController::generateUserOnlyScriptsCodeAt(const UserScriptInjectionTime& injectionTime) const
|
||||
{
|
||||
std::string code;
|
||||
std::vector<std::shared_ptr<UserScript>> userScripts = userOnlyScripts_.at(injectionTime);
|
||||
for (auto& userScript : userScripts) {
|
||||
code += ";" + userScript->source;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
std::string UserContentController::generateWrappedCodeForDocumentEnd() const
|
||||
{
|
||||
std::string code = generatePluginScriptsCodeAt(UserScriptInjectionTime::atDocumentEnd);
|
||||
code += generateUserOnlyScriptsCodeAt(UserScriptInjectionTime::atDocumentEnd);
|
||||
return replace_all_copy(USER_SCRIPTS_AT_DOCUMENT_END_WRAPPER_JS_SOURCE, VAR_PLACEHOLDER_VALUE, code);
|
||||
}
|
||||
|
||||
UserContentController::~UserContentController()
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "../plugin_scripts_js/javascript_bridge_js.h"
|
||||
#include "../plugin_scripts_js/plugin_scripts_util.h"
|
||||
#include "../types/plugin_script.h"
|
||||
#include "../types/user_script.h"
|
||||
|
||||
|
@ -11,6 +13,12 @@ namespace flutter_inappwebview_plugin
|
|||
{
|
||||
class InAppWebView;
|
||||
|
||||
const std::string USER_SCRIPTS_AT_DOCUMENT_END_WRAPPER_JS_SOURCE =
|
||||
"if (window." + JAVASCRIPT_BRIDGE_NAME + " != null && (window." + JAVASCRIPT_BRIDGE_NAME + "._userScriptsAtDocumentEndLoaded == null || !window." + JAVASCRIPT_BRIDGE_NAME + "._userScriptsAtDocumentEndLoaded)) { \
|
||||
window." + JAVASCRIPT_BRIDGE_NAME + "._userScriptsAtDocumentEndLoaded = true; \
|
||||
" + VAR_PLACEHOLDER_VALUE + " \
|
||||
}";
|
||||
|
||||
class UserContentController
|
||||
{
|
||||
public:
|
||||
|
@ -23,11 +31,20 @@ namespace flutter_inappwebview_plugin
|
|||
void removeUserOnlyScript(std::shared_ptr<UserScript> userScript);
|
||||
void removeUserOnlyScriptAt(const int64_t& index, const UserScriptInjectionTime& injectionTime);
|
||||
void removeAllUserOnlyScripts();
|
||||
bool containsUserOnlyScript(std::shared_ptr<UserScript> userScript) const;
|
||||
bool containsUserOnlyScriptByGroupName(const std::string& groupName) const;
|
||||
void removeUserOnlyScriptsByGroupName(const std::string& groupName);
|
||||
std::vector<std::shared_ptr<PluginScript>> getPluginScriptsAt(const UserScriptInjectionTime& injectionTime) const;
|
||||
void addPluginScript(std::shared_ptr<PluginScript> pluginScript);
|
||||
void addPluginScripts(std::vector<std::shared_ptr<PluginScript>> pluginScripts);
|
||||
void removePluginScript(std::shared_ptr<PluginScript> pluginScript);
|
||||
void removeAllPluginScripts();
|
||||
bool containsPluginScript(std::shared_ptr<PluginScript> pluginScript) const;
|
||||
bool containsPluginScriptByGroupName(const std::string& groupName) const;
|
||||
void removePluginScriptsByGroupName(const std::string& groupName);
|
||||
std::string generatePluginScriptsCodeAt(const UserScriptInjectionTime& injectionTime) const;
|
||||
std::string generateUserOnlyScriptsCodeAt(const UserScriptInjectionTime& injectionTime) const;
|
||||
std::string generateWrappedCodeForDocumentEnd() const;
|
||||
private:
|
||||
InAppWebView* webView_;
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "../utils/flutter.h"
|
||||
#include "../utils/log.h"
|
||||
#include "../utils/strconv.h"
|
||||
#include "../utils/string.h"
|
||||
#include "in_app_webview.h"
|
||||
#include "webview_channel_delegate.h"
|
||||
|
||||
|
@ -28,6 +29,14 @@ namespace flutter_inappwebview_plugin
|
|||
};
|
||||
}
|
||||
|
||||
WebViewChannelDelegate::CallJsHandlerCallback::CallJsHandlerCallback()
|
||||
{
|
||||
decodeResult = [](const flutter::EncodableValue* value)
|
||||
{
|
||||
return value;
|
||||
};
|
||||
}
|
||||
|
||||
void WebViewChannelDelegate::HandleMethodCall(const flutter::MethodCall<flutter::EncodableValue>& method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
|
||||
{
|
||||
|
@ -37,42 +46,53 @@ namespace flutter_inappwebview_plugin
|
|||
}
|
||||
|
||||
auto& arguments = std::get<flutter::EncodableMap>(*method_call.arguments());
|
||||
auto& methodName = method_call.method_name();
|
||||
|
||||
if (method_call.method_name().compare("getUrl") == 0) {
|
||||
if (string_equals(methodName, "getUrl")) {
|
||||
result->Success(make_fl_value(webView->getUrl()));
|
||||
}
|
||||
else if (method_call.method_name().compare("getTitle") == 0) {
|
||||
else if (string_equals(methodName, "getTitle")) {
|
||||
result->Success(make_fl_value(webView->getUrl()));
|
||||
}
|
||||
else if (method_call.method_name().compare("loadUrl") == 0) {
|
||||
else if (string_equals(methodName, "loadUrl")) {
|
||||
auto urlRequest = std::make_unique<URLRequest>(get_fl_map_value<flutter::EncodableMap>(arguments, "urlRequest"));
|
||||
webView->loadUrl(*urlRequest);
|
||||
webView->loadUrl(std::move(urlRequest));
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("reload") == 0) {
|
||||
else if (string_equals(methodName, "loadFile")) {
|
||||
auto assetFilePath = get_fl_map_value<std::string>(arguments, "assetFilePath");
|
||||
webView->loadFile(assetFilePath);
|
||||
result->Success(true);
|
||||
}
|
||||
else if (string_equals(methodName, "loadData")) {
|
||||
auto data = get_fl_map_value<std::string>(arguments, "data");
|
||||
webView->loadData(data);
|
||||
result->Success(true);
|
||||
}
|
||||
else if (string_equals(methodName, "reload")) {
|
||||
webView->reload();
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("goBack") == 0) {
|
||||
else if (string_equals(methodName, "goBack")) {
|
||||
webView->goBack();
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("canGoBack") == 0) {
|
||||
else if (string_equals(methodName, "canGoBack")) {
|
||||
result->Success(webView->canGoBack());
|
||||
}
|
||||
else if (method_call.method_name().compare("goForward") == 0) {
|
||||
else if (string_equals(methodName, "goForward")) {
|
||||
webView->goForward();
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("canGoForward") == 0) {
|
||||
else if (string_equals(methodName, "canGoForward")) {
|
||||
result->Success(webView->canGoForward());
|
||||
}
|
||||
else if (method_call.method_name().compare("goBackOrForward") == 0) {
|
||||
else if (string_equals(methodName, "goBackOrForward")) {
|
||||
auto steps = get_fl_map_value<int>(arguments, "steps");
|
||||
webView->goBackOrForward(steps);
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("canGoBackOrForward") == 0) {
|
||||
else if (string_equals(methodName, "canGoBackOrForward")) {
|
||||
auto result_ = std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result));
|
||||
|
||||
auto steps = get_fl_map_value<int>(arguments, "steps");
|
||||
|
@ -81,14 +101,14 @@ namespace flutter_inappwebview_plugin
|
|||
result_->Success(value);
|
||||
});
|
||||
}
|
||||
else if (method_call.method_name().compare("isLoading") == 0) {
|
||||
else if (string_equals(methodName, "isLoading")) {
|
||||
result->Success(webView->isLoading());
|
||||
}
|
||||
else if (method_call.method_name().compare("stopLoading") == 0) {
|
||||
else if (string_equals(methodName, "stopLoading")) {
|
||||
webView->stopLoading();
|
||||
result->Success(true);
|
||||
}
|
||||
else if (method_call.method_name().compare("evaluateJavascript") == 0) {
|
||||
else if (string_equals(methodName, "evaluateJavascript")) {
|
||||
auto result_ = std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result));
|
||||
|
||||
auto source = get_fl_map_value<std::string>(arguments, "source");
|
||||
|
@ -97,23 +117,43 @@ namespace flutter_inappwebview_plugin
|
|||
result_->Success(value);
|
||||
});
|
||||
}
|
||||
else if (method_call.method_name().compare("getCopyBackForwardList") == 0) {
|
||||
else if (string_equals(methodName, "getCopyBackForwardList")) {
|
||||
auto result_ = std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result));
|
||||
webView->getCopyBackForwardList([result_ = std::move(result_)](const std::unique_ptr<WebHistory> value)
|
||||
{
|
||||
result_->Success(value->toEncodableMap());
|
||||
});
|
||||
}
|
||||
else if (string_equals(methodName, "addUserScript")) {
|
||||
auto userScript = std::make_unique<UserScript>(get_fl_map_value<flutter::EncodableMap>(arguments, "userScript"));
|
||||
webView->addUserScript(std::move(userScript));
|
||||
result->Success(true);
|
||||
}
|
||||
else if (string_equals(methodName, "removeUserScript")) {
|
||||
auto index = get_fl_map_value<int64_t>(arguments, "index");
|
||||
auto userScript = std::make_unique<UserScript>(get_fl_map_value<flutter::EncodableMap>(arguments, "userScript"));
|
||||
webView->removeUserScript(index, std::move(userScript));
|
||||
result->Success(true);
|
||||
}
|
||||
else if (string_equals(methodName, "removeUserScriptsByGroupName")) {
|
||||
auto groupName = get_fl_map_value<std::string>(arguments, "groupName");
|
||||
webView->removeUserScriptsByGroupName(groupName);
|
||||
result->Success(true);
|
||||
}
|
||||
else if (string_equals(methodName, "removeAllUserScripts")) {
|
||||
webView->removeAllUserScripts();
|
||||
result->Success(true);
|
||||
}
|
||||
// for inAppBrowser
|
||||
else if (webView->inAppBrowser && method_call.method_name().compare("show") == 0) {
|
||||
else if (webView->inAppBrowser && string_equals(methodName, "show")) {
|
||||
webView->inAppBrowser->show();
|
||||
result->Success(true);
|
||||
}
|
||||
else if (webView->inAppBrowser && method_call.method_name().compare("hide") == 0) {
|
||||
else if (webView->inAppBrowser && string_equals(methodName, "hide")) {
|
||||
webView->inAppBrowser->hide();
|
||||
result->Success(true);
|
||||
}
|
||||
else if (webView->inAppBrowser && method_call.method_name().compare("close") == 0) {
|
||||
else if (webView->inAppBrowser && string_equals(methodName, "close")) {
|
||||
webView->inAppBrowser->close();
|
||||
result->Success(true);
|
||||
}
|
||||
|
@ -211,6 +251,19 @@ namespace flutter_inappwebview_plugin
|
|||
channel->InvokeMethod("onUpdateVisitedHistory", std::move(arguments));
|
||||
}
|
||||
|
||||
void WebViewChannelDelegate::onCallJsHandler(const std::string& handlerName, const std::string& args, std::unique_ptr<CallJsHandlerCallback> callback) const
|
||||
{
|
||||
if (!channel) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto arguments = std::make_unique<flutter::EncodableValue>(flutter::EncodableMap{
|
||||
{"handlerName", handlerName},
|
||||
{"args", args}
|
||||
});
|
||||
channel->InvokeMethod("onCallJsHandler", std::move(arguments), std::move(callback));
|
||||
}
|
||||
|
||||
WebViewChannelDelegate::~WebViewChannelDelegate()
|
||||
{
|
||||
debugLog("dealloc WebViewChannelDelegate");
|
||||
|
|
|
@ -22,12 +22,18 @@ namespace flutter_inappwebview_plugin
|
|||
public:
|
||||
InAppWebView* webView;
|
||||
|
||||
class ShouldOverrideUrlLoadingCallback : public BaseCallbackResult<NavigationActionPolicy> {
|
||||
class ShouldOverrideUrlLoadingCallback : public BaseCallbackResult<const NavigationActionPolicy> {
|
||||
public:
|
||||
ShouldOverrideUrlLoadingCallback();
|
||||
~ShouldOverrideUrlLoadingCallback() = default;
|
||||
};
|
||||
|
||||
class CallJsHandlerCallback : public BaseCallbackResult<const flutter::EncodableValue*> {
|
||||
public:
|
||||
CallJsHandlerCallback();
|
||||
~CallJsHandlerCallback() = default;
|
||||
};
|
||||
|
||||
WebViewChannelDelegate(InAppWebView* webView, flutter::BinaryMessenger* messenger);
|
||||
WebViewChannelDelegate(InAppWebView* webView, flutter::BinaryMessenger* messenger, const std::string& name);
|
||||
~WebViewChannelDelegate();
|
||||
|
@ -43,6 +49,7 @@ namespace flutter_inappwebview_plugin
|
|||
void onReceivedHttpError(std::shared_ptr<WebResourceRequest> request, std::shared_ptr<WebResourceResponse> error) const;
|
||||
void onTitleChanged(const std::optional<std::string>& title) const;
|
||||
void onUpdateVisitedHistory(const std::optional<std::string>& url, const std::optional<bool>& isReload) const;
|
||||
void onCallJsHandler(const std::string& handlerName, const std::string& args, std::unique_ptr<CallJsHandlerCallback> callback) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,12 @@
|
|||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "javascript_bridge_js.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
const std::string JAVASCRIPT_BRIDGE_JS_SOURCE = "window." + JAVASCRIPT_BRIDGE_NAME + " = {}; \
|
||||
window." + JAVASCRIPT_BRIDGE_NAME + ".callHandler = function() { \
|
||||
var _callHandlerID = setTimeout(function() {}); \
|
||||
window.chrome.webview.postMessage({ 'internalHandlerName': 'callHandler', 'handlerName': arguments[0], '_callHandlerID' : _callHandlerID, 'args' : JSON.stringify(Array.prototype.slice.call(arguments, 1)) }); \
|
||||
return new Promise(function(resolve, reject) { \
|
||||
window." + JAVASCRIPT_BRIDGE_NAME + "[_callHandlerID] = { resolve: resolve, reject : reject };\
|
||||
});\
|
||||
};";
|
||||
|
||||
std::unique_ptr<PluginScript> createJavaScriptBridgePluginScript()
|
||||
{
|
||||
const std::set<std::string> allowedOriginRules = { "*" };
|
||||
const std::vector<std::string> allowedOriginRules = { "*" };
|
||||
return std::make_unique<PluginScript>(
|
||||
JAVASCRIPT_BRIDGE_JS_PLUGIN_SCRIPT_GROUP_NAME,
|
||||
JAVASCRIPT_BRIDGE_JS_SOURCE,
|
||||
|
|
|
@ -9,7 +9,21 @@
|
|||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
const std::string JAVASCRIPT_BRIDGE_NAME = "flutter_inappwebview";
|
||||
const std::string JAVASCRIPT_BRIDGE_JS_SOURCE = "window." + JAVASCRIPT_BRIDGE_NAME + " = {}; \
|
||||
window." + JAVASCRIPT_BRIDGE_NAME + ".callHandler = function() { \
|
||||
var _callHandlerID = setTimeout(function() {}); \
|
||||
window.chrome.webview.postMessage({ 'name': 'callHandler', 'body': {'handlerName': arguments[0], '_callHandlerID' : _callHandlerID, 'args' : JSON.stringify(Array.prototype.slice.call(arguments, 1))} }); \
|
||||
return new Promise(function(resolve, reject) { \
|
||||
window." + JAVASCRIPT_BRIDGE_NAME + "[_callHandlerID] = { resolve: resolve, reject : reject };\
|
||||
});\
|
||||
};";
|
||||
const std::string JAVASCRIPT_BRIDGE_JS_PLUGIN_SCRIPT_GROUP_NAME = "IN_APP_WEBVIEW_JAVASCRIPT_BRIDGE_JS_PLUGIN_SCRIPT";
|
||||
const std::string PLATFORM_READY_JS_SOURCE = "(function() { \
|
||||
if ((window.top == null || window.top === window) && window." + JAVASCRIPT_BRIDGE_NAME + " != null && window." + JAVASCRIPT_BRIDGE_NAME + "._platformReady == null) { \
|
||||
window.dispatchEvent(new Event('flutterInAppWebViewPlatformReady')); \
|
||||
window." + JAVASCRIPT_BRIDGE_NAME + "._platformReady = true; \
|
||||
} \
|
||||
})();";
|
||||
|
||||
std::unique_ptr<PluginScript> createJavaScriptBridgePluginScript();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_PLUGIN_SCRIPTS_UTIL_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_PLUGIN_SCRIPTS_UTIL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
const std::string VAR_PLACEHOLDER_VALUE = "$IN_APP_WEBVIEW_PLACEHOLDER_VALUE";
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_PLUGIN_SCRIPTS_UTIL_H_
|
|
@ -6,7 +6,7 @@ namespace flutter_inappwebview_plugin
|
|||
const std::optional<std::string>& groupName,
|
||||
const std::string& source,
|
||||
const UserScriptInjectionTime& injectionTime,
|
||||
const std::set<std::string>& allowedOriginRules
|
||||
const std::vector<std::string>& allowedOriginRules
|
||||
) : UserScript(groupName, source, injectionTime, allowedOriginRules)
|
||||
{}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace flutter_inappwebview_plugin
|
|||
const std::optional<std::string>& groupName,
|
||||
const std::string& source,
|
||||
const UserScriptInjectionTime& injectionTime,
|
||||
const std::set<std::string>& allowedOriginRules
|
||||
const std::vector<std::string>& allowedOriginRules
|
||||
);
|
||||
~PluginScript();
|
||||
};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "../utils/map.h"
|
||||
#include "user_script.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
|
@ -6,10 +7,17 @@ namespace flutter_inappwebview_plugin
|
|||
const std::optional<std::string>& groupName,
|
||||
const std::string& source,
|
||||
const UserScriptInjectionTime& injectionTime,
|
||||
const std::set<std::string>& allowedOriginRules
|
||||
const std::vector<std::string>& allowedOriginRules
|
||||
) : groupName(groupName), source(source), injectionTime(injectionTime), allowedOriginRules(allowedOriginRules)
|
||||
{}
|
||||
|
||||
UserScript::UserScript(const flutter::EncodableMap& map)
|
||||
: groupName(get_optional_fl_map_value<std::string>(map, "groupName")),
|
||||
source(get_fl_map_value<std::string>(map, "source")),
|
||||
injectionTime(static_cast<UserScriptInjectionTime>(get_fl_map_value<int>(map, "injectionTime"))),
|
||||
allowedOriginRules(functional_map(get_fl_map_value<flutter::EncodableList>(map, "allowedOriginRules"), [](const flutter::EncodableValue& m) { return std::get<std::string>(m); }))
|
||||
{}
|
||||
|
||||
UserScript::~UserScript()
|
||||
{}
|
||||
}
|
|
@ -1,14 +1,17 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_USER_SCRIPT_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_USER_SCRIPT_H_
|
||||
|
||||
#include <flutter/standard_method_codec.h>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../utils/flutter.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
enum UserScriptInjectionTime {
|
||||
atDocumentStart,
|
||||
atDocumentStart = 0,
|
||||
atDocumentEnd
|
||||
};
|
||||
|
||||
|
@ -19,14 +22,15 @@ namespace flutter_inappwebview_plugin
|
|||
const std::optional<std::string> groupName;
|
||||
const std::string source;
|
||||
const UserScriptInjectionTime injectionTime;
|
||||
const std::set<std::string> allowedOriginRules;
|
||||
const std::vector<std::string> allowedOriginRules;
|
||||
|
||||
UserScript(
|
||||
const std::optional<std::string>& groupName,
|
||||
const std::string& source,
|
||||
const UserScriptInjectionTime& injectionTime,
|
||||
const std::set<std::string>& allowedOriginRules
|
||||
const std::vector<std::string>& allowedOriginRules
|
||||
);
|
||||
UserScript(const flutter::EncodableMap& map);
|
||||
~UserScript();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "../utils/util.h"
|
||||
#include "../utils/vector.h"
|
||||
#include "web_history.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_
|
||||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_FLUTTER_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_FLUTTER_H_
|
||||
|
||||
#include <flutter/encodable_value.h>
|
||||
|
||||
|
@ -148,4 +148,4 @@ namespace flutter_inappwebview_plugin
|
|||
}
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_FLUTTER_UTIL_H_
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_FLUTTER_H_
|
|
@ -4,12 +4,14 @@
|
|||
#include <comdef.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "strconv.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
static inline void debugLog(const std::string& msg, const bool& isError = false)
|
||||
template <typename T>
|
||||
static inline void debugLog(const std::basic_string<T>& msg, const bool& isError = false)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (isError) {
|
||||
|
@ -22,11 +24,30 @@ namespace flutter_inappwebview_plugin
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline void debugLog(const char* msg, const bool& isError = false)
|
||||
{
|
||||
debugLog(std::string(msg), isError);
|
||||
}
|
||||
|
||||
static inline void debugLog(const std::wstring& msg, const bool& isError = false)
|
||||
{
|
||||
debugLog(wide_to_ansi(msg), isError);
|
||||
}
|
||||
|
||||
static inline void debugLog(const bool& value, const bool& isError = false)
|
||||
{
|
||||
debugLog(value ? "true" : "false", isError);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type
|
||||
>
|
||||
static inline void debugLog(const T& value, const bool& isError = false)
|
||||
{
|
||||
debugLog(std::to_string(value), isError);
|
||||
}
|
||||
|
||||
static inline std::string getHRMessage(const HRESULT& error)
|
||||
{
|
||||
return wide_to_ansi(_com_error(error).ErrorMessage());
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_MAP_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_MAP_H_
|
||||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_MAP_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_MAP_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
|
@ -33,39 +32,6 @@ namespace flutter_inappwebview_plugin
|
|||
auto itr = map.find(key);
|
||||
return itr != map.end() ? itr->second : nullptr;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Func>
|
||||
static inline auto functional_map(Iterator begin, Iterator end, Func&& func) ->
|
||||
std::vector<decltype(func(std::declval<typename Iterator::value_type>()))>
|
||||
{
|
||||
using value_type = decltype(func(std::declval<typename Iterator::value_type>()));
|
||||
|
||||
std::vector<value_type> out_vector;
|
||||
out_vector.reserve(std::distance(begin, end));
|
||||
|
||||
std::transform(begin, end, std::back_inserter(out_vector),
|
||||
std::forward<Func>(func));
|
||||
|
||||
return out_vector;
|
||||
}
|
||||
|
||||
template <typename T, typename Func>
|
||||
static inline auto functional_map(const T& iterable, Func&& func) ->
|
||||
std::vector<decltype(func(std::declval<typename T::value_type>()))>
|
||||
{
|
||||
return functional_map(std::begin(iterable), std::end(iterable),
|
||||
std::forward<Func>(func));
|
||||
}
|
||||
|
||||
template <typename T, typename Func>
|
||||
static inline auto functional_map(const std::optional<T>& iterable, Func&& func) ->
|
||||
std::vector<decltype(func(std::declval<typename T::value_type>()))>
|
||||
{
|
||||
if (!iterable.has_value()) {
|
||||
return {};
|
||||
}
|
||||
return functional_map(iterable.value(), std::forward<Func>(func));
|
||||
}
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_MAP_H_
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_MAP_H_
|
|
@ -0,0 +1,112 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_STRING_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_STRING_H_
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "strconv.h"
|
||||
|
||||
namespace flutter_inappwebview_plugin
|
||||
{
|
||||
template <typename T>
|
||||
struct is_string
|
||||
: std::false_type
|
||||
{};
|
||||
|
||||
// Partial specialization - parameters used to qualify the specialization
|
||||
template <typename CharT, typename TraitsT, typename AllocT>
|
||||
struct is_string<std::basic_string<CharT, TraitsT, AllocT>>
|
||||
: std::true_type
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
using is_basic_string = is_string<std::remove_cv_t<T>>;
|
||||
|
||||
template <typename T>
|
||||
static inline bool string_equals(const std::basic_string<T>& s1, const std::basic_string<T>& s2)
|
||||
{
|
||||
return s1.compare(s2) == 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline bool string_equals(const std::basic_string<T>& s1, const char* s2)
|
||||
{
|
||||
return s1.compare(s2) == 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline bool string_equals(const char* s1, const std::basic_string<T>& s2)
|
||||
{
|
||||
return s2.compare(s1) == 0;
|
||||
}
|
||||
|
||||
static inline bool string_equals(const std::string& s1, const std::wstring& s2)
|
||||
{
|
||||
return string_equals(s1, wide_to_ansi(s2));
|
||||
}
|
||||
|
||||
static inline bool string_equals(const std::wstring& s1, const std::string& s2)
|
||||
{
|
||||
return string_equals(wide_to_ansi(s1), s2);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline bool string_equals(const std::optional<std::basic_string<T>>& s1, const std::basic_string<T>& s2)
|
||||
{
|
||||
return s1.has_value() ? string_equals(s1.value(), s2) : false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline bool string_equals(const std::basic_string<T>& s1, const std::optional<std::basic_string<T>>& s2)
|
||||
{
|
||||
return s2.has_value() ? string_equals(s1, s2.value()) : false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline bool string_equals(const std::optional<std::basic_string<T>>& s1, const std::optional<std::basic_string<T>>& s2)
|
||||
{
|
||||
return s1.has_value() && s2.has_value() ? string_equals(s1.value(), s2.value()) : true;
|
||||
}
|
||||
|
||||
static inline void replace_all(std::string& source, const std::string& from, const std::string& to)
|
||||
{
|
||||
std::string newString;
|
||||
newString.reserve(source.length()); // avoids a few memory allocations
|
||||
|
||||
std::string::size_type lastPos = 0;
|
||||
std::string::size_type findPos;
|
||||
|
||||
while (std::string::npos != (findPos = source.find(from, lastPos))) {
|
||||
newString.append(source, lastPos, findPos - lastPos);
|
||||
newString += to;
|
||||
lastPos = findPos + from.length();
|
||||
}
|
||||
|
||||
// Care for the rest after last occurrence
|
||||
newString += source.substr(lastPos);
|
||||
|
||||
source.swap(newString);
|
||||
}
|
||||
|
||||
static inline std::string replace_all_copy(const std::string& source, const std::string& from, const std::string& to)
|
||||
{
|
||||
std::string newString;
|
||||
newString.reserve(source.length()); // avoids a few memory allocations
|
||||
|
||||
std::string::size_type lastPos = 0;
|
||||
std::string::size_type findPos;
|
||||
|
||||
while (std::string::npos != (findPos = source.find(from, lastPos))) {
|
||||
newString.append(source, lastPos, findPos - lastPos);
|
||||
newString += to;
|
||||
lastPos = findPos + from.length();
|
||||
}
|
||||
|
||||
// Care for the rest after last occurrence
|
||||
newString += source.substr(lastPos);
|
||||
|
||||
return newString;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_STRING_H_
|
|
@ -1,7 +1,8 @@
|
|||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_VECTOR_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_VECTOR_H_
|
||||
#ifndef FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_VECTOR_H_
|
||||
#define FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_VECTOR_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
@ -26,16 +27,73 @@ namespace flutter_inappwebview_plugin
|
|||
struct is_vector : is_vector_impl<T>::type { };
|
||||
|
||||
template <typename T>
|
||||
static inline void vector_remove_el(std::vector<T>& vec, const T& el)
|
||||
static inline void vector_remove(std::vector<T>& vec, const T& el)
|
||||
{
|
||||
std::remove(vec.begin(), vec.end(), el);
|
||||
}
|
||||
|
||||
template <typename T, typename UnaryPredicate>
|
||||
static inline void vector_remove_if(std::vector<T>& vec, UnaryPredicate&& predicate)
|
||||
{
|
||||
std::remove_if(vec.begin(), vec.end(), std::forward<UnaryPredicate>(predicate));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline void vector_remove_erase_el(std::vector<T>& vec, const T& el)
|
||||
static inline void vector_remove_erase(std::vector<T>& vec, const T& el)
|
||||
{
|
||||
vec.erase(std::remove(vec.begin(), vec.end(), el), vec.end());
|
||||
}
|
||||
|
||||
template <typename T, typename UnaryPredicate>
|
||||
static inline void vector_remove_erase_if(std::vector<T>& vec, UnaryPredicate&& predicate)
|
||||
{
|
||||
vec.erase(std::remove_if(vec.begin(), vec.end(), std::forward<UnaryPredicate>(predicate)), vec.end());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline bool vector_contains(const std::vector<T>& vec, const T& value)
|
||||
{
|
||||
return std::find(vec.begin(), vec.end(), value) != vec.end();
|
||||
}
|
||||
|
||||
template <typename T, typename UnaryPredicate>
|
||||
static inline bool vector_contains_if(const std::vector<T>& vec, UnaryPredicate&& predicate)
|
||||
{
|
||||
return std::find_if(vec.begin(), vec.end(), std::forward<UnaryPredicate>(predicate)) != vec.end();
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Func>
|
||||
static inline auto functional_map(Iterator begin, Iterator end, Func&& func) ->
|
||||
std::vector<decltype(func(std::declval<typename Iterator::value_type>()))>
|
||||
{
|
||||
using value_type = decltype(func(std::declval<typename Iterator::value_type>()));
|
||||
|
||||
std::vector<value_type> out_vector;
|
||||
out_vector.reserve(std::distance(begin, end));
|
||||
|
||||
std::transform(begin, end, std::back_inserter(out_vector),
|
||||
std::forward<Func>(func));
|
||||
|
||||
return out_vector;
|
||||
}
|
||||
|
||||
template <typename T, typename Func>
|
||||
static inline auto functional_map(const T& iterable, Func&& func) ->
|
||||
std::vector<decltype(func(std::declval<typename T::value_type>()))>
|
||||
{
|
||||
return functional_map(std::begin(iterable), std::end(iterable),
|
||||
std::forward<Func>(func));
|
||||
}
|
||||
|
||||
template <typename T, typename Func>
|
||||
static inline auto functional_map(const std::optional<T>& iterable, Func&& func) ->
|
||||
std::vector<decltype(func(std::declval<typename T::value_type>()))>
|
||||
{
|
||||
if (!iterable.has_value()) {
|
||||
return {};
|
||||
}
|
||||
return functional_map(iterable.value(), std::forward<Func>(func));
|
||||
}
|
||||
}
|
||||
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_VECTOR_H_
|
||||
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_UTIL_VECTOR_H_
|
Loading…
Reference in New Issue