dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
21.98k stars 1.71k forks source link

`HtmlWebViewSource` support for upcoming `HybridWebView` control #23908

Open hansmbakker opened 1 month ago

hansmbakker commented 1 month ago

Description

HybridWebView will become part of .NET 9.

Currently the WebView control supports a HtmlWebViewSource which allows rendering HTML from a string rather than from a URL.

However, HybridWebView does not support that now. This feature request is to request that support.

Public API Changes

In the preview the API was already there, however it threw an ArgumentNullException: https://github.com/Eilon/MauiHybridWebView/issues/68.

Intended Use-Case

Render HTML strings which could be generated on-the-fly.

For example: MAUI has no markdown control. What could be done is using MarkDig to convert it to HTML and then render the resulting HTML

https://github.com/Eilon/MauiHybridWebView/issues/68#issuecomment-2246274605

Eilon commented 1 month ago

@hansmbakker - I like the idea of being able to control the sources more precisely. For the regular WebView control I think it would only let you set a single Source but if that source referenced anything else, like CSS/JS/etc. then you couldn't control that.

In your scenario do you want to potentially serve up many 'fake' files all together? If so, then using HtmlWebViewSource probably wouldn't be enough. I'd like to instead support a pattern where let's say there's an event like OnUrlLoading and you could handle that like this:

void OnHybridWebView_UrlLoading(UrlLoadingArgs e)
{
    if (e.Url == "/") { e.Content = "<html>content for '/'.</html>"; }
    else if (e.Url == "/scripts/app.js") { e.ContentStream = new Stream(<some js content>); }
    else if (e.Url.StartsWith("/images/")) { e.ContentStream = LoadImageStream(e.Url); }
}

Or something like that. In this manner your app could choose to handle any URL in some custom manner by providing the content to serve. It's a bit more complicated than just that, for example to return the MIME type or other headers, but that's the general idea.

hansmbakker commented 1 month ago

What I did with the current WebView / HtmlWebViewSource combination, is to have only the fake "index" page in the HtmlWebViewSource and have it reference files that were included as MauiAsset (e.g. a css file or js file); it could find those files.

There might be other people having different usecases though.

Eilon commented 1 month ago

@hansmbakker understood, thanks for clarifying the scenario. I hope to have a more generic solution so that you could replace any content in the app with runtime-determined content. The experimental version had some support for that, and my hope is to enable it generically for all scenarios.

Supposing the code I posted above for a new OnUrlLoading event were to actually work, would that work for you?

hansmbakker commented 1 month ago

Supposing the code I posted above for a new OnUrlLoading event were to actually work, would that work for you?

@Eilon we're using MVVM and using events is always a bit tricky then. Would there be an option that would work better in an MVVM context? (I mean: would there be a way to bind to a property containing a HTML string for example?)

Eilon commented 1 month ago

Supposing the code I posted above for a new OnUrlLoading event were to actually work, would that work for you?

@Eilon we're using MVVM and using events is always a bit tricky then. Would there be an option that would work better in an MVVM context? (I mean: would there be a way to bind to a property containing a HTML string for example?)

Ah interesting. I'd like to be able to support multiple arbitrary files being dynamically set instead of only one property being set, so I wonder what pattern could work well for that in a way that also makes sense for MVVM?