dotnet / dotnet/maui

[Enhancement] Improved WebView That Supports Async Cancellation + Extensibility

Open
#3,388 1 comment 1 reaction 0 assignees View on GitHub
area-controls-webview legacy-area-controls proposal/open
Dominant language
C#
Stars
23.3k
Forks
2k
Avg merge
1d 15h
Merged PRs (30d)
290

Description

## Summary
In Xamarin.Forms I had raised the following issue & PR:

[[Bug] WebView Navigating Race Condition #12720](https://github.com/xamarin/Xamarin.Forms/issues/12720)
[WebView Navigation Now Uses Deferral Token #14137](https://github.com/xamarin/Xamarin.Forms/pull/14137)

A requirement for the app I was developing at the time was to confirm ability to navigate to a site within the webview (if I click microsoft.com, is the user allowed to visit the site). This functionality was restricted by the implementation of the webview the cancellation result could not be delayed.

I raised an initial PR converting the implementation to use a task. @PureWeen had a great suggestion of using a `DeferralToken` to control the navigation, making the whole cancellation process easier for multiple subscribers to halt. I have raised that PR but it contains a break to the API, so is not suitable for Xamarin Forms.

I had business needs to implement this feature as any hacks / work arounds carried other bugs which were not ideal. I forked the WebView control and currently use an [alternate implementation](https://github.com/Axemasta/SuperWebView) of `WebView` which contains the changes I made in this PR + extra nice to haves.

I was reading the implementation of `WebView` in MAUI and its the same as in forms, meaning that the issue will persist in MAUI. Since MAUI is in development, I think its the perfect time to revisit the API of `WebView`, make the control more powerful aswell as addressing some pain points I experienced refactoring the code for my control.

## API Changes

Change `WebViewNavigatingArgs`:
- Remove `Cancel` boolean
- Add `DeferralToken` property
- Cancellation is performed in the following manor:

```csharp
private async void OnNavigating(object sender, WebNavigatingEventArgs e)
{
if (e.CanCancel)
{
var token = e.GetDeferral();

bool canBrowse = await CanBrowse(e.Url);

if (!canBrowse)
{
e.Cancel();
}

token.Complete();
}
}
```

The API changes I made in my XF PR ended up refactoring the deferral token code from Shell & making it more generic. I also changed the navigating args to implement an interface instead of inheriting an abstract base:

```csharp
public interface IWebNavigationEventArgs
{
WebNavigationEvent NavigationEvent { get; }

WebViewSource Source { get; }

string Url { get; }
}
```
This was so I could make the `DeferralToken` available to the event args by inheriting a base class.

## Intended Use Case
This will generally improve the experience developers have with `WebView`. Developers can confirm navigation without having a race condition present when navigating. The only way I could get around this issue in XF without my custom `SuperWebView` was to cancel navigation immediately, run a task then re-navigate (this was hacky & caused other issues).

## Proof Of Concept
I have raised this issue & will put up a PR with my first cut of what I think it should look like. I'm very happy to accept and and all advice for design & implementation + I would like ideas on the best way of testing this functionality.

I've maintained the code for iOS & Android and the implementations vary WILDY between them, so it will end up affecting a lot of code. I think there will need to be a lot of testing to make this feature a success.

Contributor guide

Open the contributing guide

Research direction

The issue names WebView, WebViewNavigatingArgs, the iOS and Android implementations, and Shell’s deferral-token code as the relevant entry points. Read those implementations first and identify the existing navigation event and cancellation tests; no test files are named. Done means agreeing on a compatible deferral-based API, implementing it across both platforms, and covering delayed cancellation and multiple subscribers.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, csharp, ios
Domain
frontend, mobile-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.