windows: completed initial javascript handler communication and user scripts support, added support for loadFile and loadData

This commit is contained in:
unknown 2024-01-19 18:52:00 +01:00
parent 9a5dae03ba
commit a4c044a0f1
26 changed files with 711 additions and 141 deletions

View File

@ -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.

View File

@ -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(

View File

@ -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;

View File

@ -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"

View File

@ -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;

View File

@ -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);

View File

@ -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)
{

View File

@ -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:

View File

@ -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(),

View File

@ -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()

View File

@ -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_;

View File

@ -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");

View File

@ -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;
};
}

View File

@ -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,

View File

@ -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();
}

View File

@ -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_

View File

@ -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)
{}

View File

@ -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();
};

View File

@ -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()
{}
}

View File

@ -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();
};
}

View File

@ -1,4 +1,4 @@
#include "../utils/util.h"
#include "../utils/vector.h"
#include "web_history.h"
namespace flutter_inappwebview_plugin

View File

@ -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_

View File

@ -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());

View File

@ -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_

View File

@ -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_

View File

@ -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());
}
#endif //FLUTTER_INAPPWEBVIEW_PLUGIN_LOG_VECTOR_H_
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_UTIL_VECTOR_H_