diff --git a/src/SamplesApp/SamplesApp.Shared/App.xaml.cs b/src/SamplesApp/SamplesApp.Shared/App.xaml.cs index 82cc89b9571e..56720c0a71df 100644 --- a/src/SamplesApp/SamplesApp.Shared/App.xaml.cs +++ b/src/SamplesApp/SamplesApp.Shared/App.xaml.cs @@ -160,9 +160,9 @@ override void OnLaunched(LaunchActivatedEventArgs e) HandleLaunchArguments(e); - if (SampleControl.Presentation.SampleChooserViewModel.Instance.CurrentSelectedSample is null) + if (SampleControl.Presentation.SampleChooserViewModel.Instance is { } vm && vm.CurrentSelectedSample is null) { - SampleControl.Presentation.SampleChooserViewModel.Instance.SetSelectedSample(CancellationToken.None, "Playground", "Playground"); + vm.SetSelectedSample(CancellationToken.None, "Playground", "Playground"); } Console.WriteLine("Done loading " + sw.Elapsed); diff --git a/src/Uno.UI.RuntimeTests/Tests/Microsoft_UI_Xaml_Controls/Given_WebView2.cs b/src/Uno.UI.RuntimeTests/Tests/Microsoft_UI_Xaml_Controls/Given_WebView2.cs index 7337c0029db1..219ea153a3ca 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Microsoft_UI_Xaml_Controls/Given_WebView2.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Microsoft_UI_Xaml_Controls/Given_WebView2.cs @@ -42,10 +42,13 @@ public async Task When_Navigate() await TestServices.WindowHelper.WaitForLoaded(border); var uri = new Uri("https://example.com/"); await webView.EnsureCoreWebView2Async(); + bool navigationStarting = false; bool navigationDone = false; + webView.NavigationStarting += (s, e) => navigationStarting = true; webView.NavigationCompleted += (s, e) => navigationDone = true; webView.CoreWebView2.Navigate(uri.ToString()); Assert.IsNull(webView.Source); + await TestServices.WindowHelper.WaitFor(() => navigationStarting, 1000); await TestServices.WindowHelper.WaitFor(() => navigationDone, 3000); Assert.IsNotNull(webView.Source); Assert.IsTrue(webView.Source.OriginalString.StartsWith("https://example.com/", StringComparison.OrdinalIgnoreCase)); @@ -63,10 +66,13 @@ public async Task When_NavigateToString() await TestServices.WindowHelper.WaitForLoaded(border); var uri = new Uri("https://example.com/"); await webView.EnsureCoreWebView2Async(); + bool navigationStarting = false; bool navigationDone = false; + webView.NavigationStarting += (s, e) => navigationStarting = true; webView.NavigationCompleted += (s, e) => navigationDone = true; webView.Source = uri; Assert.IsNotNull(webView.Source); + await TestServices.WindowHelper.WaitFor(() => navigationStarting, 1000); await TestServices.WindowHelper.WaitFor(() => navigationDone, 3000); Assert.IsNotNull(webView.Source); navigationDone = false; 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 8f14c1d81472..2c7e9bd8314d 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 @@ -126,13 +126,13 @@ public void ProcessNavigation(Uri uri) if (uri.Scheme.Equals("local", StringComparison.OrdinalIgnoreCase)) { var path = $"file:///android_asset/{uri.PathAndQuery}"; - _webView.LoadUrl(path); + ScheduleNavigationStarting(path, () => _webView.LoadUrl(path)); return; } if (uri.Scheme.Equals(Uri.UriSchemeMailto, StringComparison.OrdinalIgnoreCase)) { - CreateAndLaunchMailtoIntent(_webView.Context, uri.AbsoluteUri); + ScheduleNavigationStarting(uri.AbsoluteUri, () => CreateAndLaunchMailtoIntent(_webView.Context, uri.AbsoluteUri)); return; } @@ -155,7 +155,8 @@ public void ProcessNavigation(Uri uri) //The replace is present because the URI cuts off any slashes that are more than two when it creates the URI. //Therefore we add the final forward slash manually in Android because the file:/// requires 3 slashes. - _webView.LoadUrl(uri.AbsoluteUri.Replace("file://", "file:///")); + var actualUri = uri.AbsoluteUri.Replace("file://", "file:///"); + ScheduleNavigationStarting(actualUri, () => _webView.LoadUrl(actualUri)); } public void ProcessNavigation(HttpRequestMessage requestMessage) @@ -169,14 +170,30 @@ public void ProcessNavigation(HttpRequestMessage requestMessage) ); _wasLoadedFromString = false; - _webView.LoadUrl(uri.AbsoluteUri, headers); + ScheduleNavigationStarting(uri.AbsoluteUri, () => _webView.LoadUrl(uri.AbsoluteUri, headers)); } public void ProcessNavigation(string html) { _wasLoadedFromString = true; //Note : _webView.LoadData does not work properly on Android 10 even when we encode to base64. - _webView.LoadDataWithBaseURL(null, html, "text/html; charset=utf-8", "utf-8", null); + ScheduleNavigationStarting(null, () => _webView.LoadDataWithBaseURL(null, html, "text/html; charset=utf-8", "utf-8", null)); + } + + private void ScheduleNavigationStarting(string url, Action loadAction) + { + // For programmatically-triggered navigations the ShouldOverrideUrlLoading method is not called, + // to workaround this, we raise the NavigationStarting event here, asynchronously to be in line with + // the WinUI behavior. + _ = _coreWebView.Owner.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () => + { + _coreWebView.RaiseNavigationStarting(url, out var cancel); + + if (!cancel) + { + loadAction?.Invoke(); + } + }); } async Task INativeWebView.ExecuteScriptAsync(string script, CancellationToken token)