diff --git a/src/Uno.UI/UI/Xaml/Controls/WebView/Core/CoreWebView2.cs b/src/Uno.UI/UI/Xaml/Controls/WebView/Core/CoreWebView2.cs index 8df8a25e9735461928b7cc89267b836c5f04851b..d502a2cdab581bbb3a50e863aa3bfba5003e3a18 100644 --- a/src/Uno.UI/UI/Xaml/Controls/WebView/Core/CoreWebView2.cs +++ b/src/Uno.UI/UI/Xaml/Controls/WebView/Core/CoreWebView2.cs @@ -99,6 +99,16 @@ public partial class CoreWebView2 return _nativeWebView.ExecuteScriptAsync(javaScript, ct); }); + internal async Task InvokeScriptAsync(string script, string[]? arguments, CancellationToken ct) + { + if (_nativeWebView is null) + { + return null; + } + + return await _nativeWebView.InvokeScriptAsync(script, arguments, ct); + } + internal void OnOwnerApplyTemplate() { _nativeWebView = GetNativeWebViewFromTemplate(); diff --git a/src/Uno.UI/UI/Xaml/Controls/WebView/Native/Android/NativeWebViewWrapper.Android.cs b/src/Uno.UI/UI/Xaml/Controls/WebView/Native/Android/NativeWebViewWrapper.Android.cs index e280686371f12bc99c4650d3a7ff851fe3419a1f..3aec29f279e458718d5f574749f278d371f47cce 100644 --- a/src/Uno.UI/UI/Xaml/Controls/WebView/Native/Android/NativeWebViewWrapper.Android.cs +++ b/src/Uno.UI/UI/Xaml/Controls/WebView/Native/Android/NativeWebViewWrapper.Android.cs @@ -160,8 +160,6 @@ internal class NativeWebViewWrapper : INativeWebView _webView.LoadDataWithBaseURL(null, html, "text/html; charset=utf-8", "utf-8", null); } - //_owner should be IAsyncOperation instead of Task but we use an extension method to enable the same signature in Win. - //IAsyncOperation is not available in Xamarin. async Task INativeWebView.ExecuteScriptAsync(string script, CancellationToken token) { TaskCompletionSource tcs = new TaskCompletionSource(); @@ -175,6 +173,20 @@ internal class NativeWebViewWrapper : INativeWebView return await tcs.Task; } + async Task INativeWebView.InvokeScriptAsync(string script, string[] arguments, CancellationToken ct) + { + var argumentString = Windows.UI.Xaml.Controls.WebView.ConcatenateJavascriptArguments(arguments); + + TaskCompletionSource tcs = new TaskCompletionSource(); + ct.Register(() => tcs.TrySetCanceled()); + + _webView.EvaluateJavascript( + string.Format(CultureInfo.InvariantCulture, "javascript:{0}(\"{1}\");", script, argumentString), + new ScriptResponse(value => tcs.SetResult(value))); + + return await tcs.Task; + } + // On Windows, the WebView ignores "about:blank" entries from its navigation history. // Because Android doesn't let you modify the navigation history, // we need CanGoBack, CanGoForward, GoBack and GoForward to take the above condition into consideration. diff --git a/src/Uno.UI/UI/Xaml/Controls/WebView/Native/INativeWebView.cs b/src/Uno.UI/UI/Xaml/Controls/WebView/Native/INativeWebView.cs index db21593ec80be737ed2046df98f330fd26dc5a2c..6ea4c53e43741b66bea102db09a96d4e8fd9adf9 100644 --- a/src/Uno.UI/UI/Xaml/Controls/WebView/Native/INativeWebView.cs +++ b/src/Uno.UI/UI/Xaml/Controls/WebView/Native/INativeWebView.cs @@ -25,5 +25,7 @@ internal partial interface INativeWebView Task ExecuteScriptAsync(string script, CancellationToken token); + Task InvokeScriptAsync(string script, string[]? arguments, CancellationToken token); + void SetScrollingEnabled(bool isScrollingEnabled); } diff --git a/src/Uno.UI/UI/Xaml/Controls/WebView/Native/iOSmacOS/UnoWKWebView.iOSmacOS.cs b/src/Uno.UI/UI/Xaml/Controls/WebView/Native/iOSmacOS/UnoWKWebView.iOSmacOS.cs index 42a74bd2fc4ba4511bf7a5c3a43452d5ac12e974..14182de5b699ee2279d15144cff0e70018c4c003 100644 --- a/src/Uno.UI/UI/Xaml/Controls/WebView/Native/iOSmacOS/UnoWKWebView.iOSmacOS.cs +++ b/src/Uno.UI/UI/Xaml/Controls/WebView/Native/iOSmacOS/UnoWKWebView.iOSmacOS.cs @@ -644,6 +644,36 @@ public partial class UnoWKWebView : WKWebView, INativeWebView, IWKScriptMessageH return await tcs.Task; } + async Task INativeWebView.InvokeScriptAsync(string script, string[] arguments, CancellationToken ct) + { + var argumentString = Windows.UI.Xaml.Controls.WebView.ConcatenateJavascriptArguments(arguments); + var javascript = string.Format(CultureInfo.InvariantCulture, "javascript:{0}(\"{1}\")", script, argumentString); + + if (this.Log().IsEnabled(Uno.Foundation.Logging.LogLevel.Debug)) + { + this.Log().Debug($"EvaluateJavascriptAsync: {javascript}"); + } + + var tcs = new TaskCompletionSource(); + + using (ct.Register(() => tcs.TrySetCanceled())) + { + EvaluateJavaScript(javascript, (result, error) => + { + if (error != null) + { + tcs.TrySetException(new InvalidOperationException($"Failed to execute javascript {error.LocalizedDescription}, {error.LocalizedFailureReason}, {error.LocalizedRecoverySuggestion}")); + } + else + { + tcs.TrySetResult(result as NSString); + } + }); + + return await tcs.Task; + } + } + private void ProcessNSUrlRequest(NSUrlRequest request) { if (request == null) diff --git a/src/Uno.UI/UI/Xaml/Controls/WebView/WebView1/WebView.cs b/src/Uno.UI/UI/Xaml/Controls/WebView/WebView1/WebView.cs index f9e267f8cea7e47843cff1e734e09af0b7f5c491..bc3f4a108179cdfe942a2fb5205571a3433aeece 100644 --- a/src/Uno.UI/UI/Xaml/Controls/WebView/WebView1/WebView.cs +++ b/src/Uno.UI/UI/Xaml/Controls/WebView/WebView1/WebView.cs @@ -59,16 +59,23 @@ public partial class WebView : Control, IWebView public IAsyncOperation InvokeScriptAsync(string scriptName, IEnumerable arguments) => AsyncOperation.FromTask(ct => InvokeScriptAsync(ct, scriptName, arguments?.ToArray())); - public async Task InvokeScriptAsync(CancellationToken ct, string script, string[]? arguments) - { - var argumentString = ConcatenateJavascriptArguments(arguments); - var javaScript = string.Format(CultureInfo.InvariantCulture, "{0}(\"{1}\")", script, argumentString); - return AdjustInvokeScriptResult(await CoreWebView2.ExecuteScriptAsync(javaScript)); - } + public async Task InvokeScriptAsync(CancellationToken ct, string script, string[]? arguments) => + await CoreWebView2.InvokeScriptAsync(script, arguments, ct); public void NavigateWithHttpRequestMessage(global::System.Net.Http.HttpRequestMessage requestMessage) => CoreWebView2.NavigateWithHttpRequestMessage(requestMessage); + internal static string ConcatenateJavascriptArguments(string[]? arguments) + { + var argument = string.Empty; + if (arguments != null && arguments.Length > 0) + { + argument = string.Join(",", arguments); + } + + return argument; + } + private void CoreWebView2_DocumentTitleChanged(CoreWebView2 sender, object args) => DocumentTitle = sender.DocumentTitle; @@ -114,30 +121,4 @@ public partial class WebView : Control, IWebView private void CoreWebView2_UnsupportedUriSchemeIdentified(CoreWebView2 sender, WebViewUnsupportedUriSchemeIdentifiedEventArgs args) => UnsupportedUriSchemeIdentified?.Invoke(this, args); - - private static string? AdjustInvokeScriptResult(string result) - { - if (result is null) - { - return null; - } - - if (result.StartsWith("\"", StringComparison.Ordinal) && result.EndsWith("\"", StringComparison.Ordinal)) - { - return result.Substring(1, result.Length - 2); - } - - return ""; - } - - private static string ConcatenateJavascriptArguments(string[]? arguments) - { - var argument = string.Empty; - if (arguments != null && arguments.Length > 0) - { - argument = string.Join(",", arguments); - } - - return argument; - } }