Skip to content

Commit

Permalink
Merge pull request unoplatform#15487 from unoplatform/dev/mazi/webvie…
Browse files Browse the repository at this point in the history
…w-adjust

fix: Make Android `WebView2.NavigationStarting` more reliable
  • Loading branch information
jeromelaban authored Feb 15, 2024
2 parents 64fc934 + 7f79610 commit 7da9fb5
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/SamplesApp/SamplesApp.Shared/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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)
Expand All @@ -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<string> INativeWebView.ExecuteScriptAsync(string script, CancellationToken token)
Expand Down

0 comments on commit 7da9fb5

Please sign in to comment.