Skip to content

Commit

Permalink
Fix for #5523 MauiWebView not loading local files on Windows (#7672)
Browse files Browse the repository at this point in the history
* Fix for #5523 MauiWebView not loading local files on Windows

* Unpackaged app support for local HTML files.

* Use property for path

* Auto map/unmap virtual host for app dir when navigating to safe/unsafe URIs

Co-authored-by: Conor Breen <[email protected]>
  • Loading branch information
breenbob and conbre authored Jun 21, 2022
1 parent 630cdcd commit 8eba70e
Showing 1 changed file with 50 additions and 3 deletions.
53 changes: 50 additions & 3 deletions src/Core/src/Platform/Windows/MauiWebView.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
using Microsoft.Maui.ApplicationModel;
using Microsoft.UI.Xaml.Controls;
using Windows.ApplicationModel;

namespace Microsoft.Maui.Platform
{
public class MauiWebView : WebView2, IWebViewDelegate
{
public MauiWebView()
{
NavigationStarting += (sender, args) =>
{
// Auto map local virtual app dir host, e.g. if navigating back to local site from a link to an external site
if (args?.Uri?.ToLowerInvariant().StartsWith(LocalScheme.TrimEnd('/').ToLowerInvariant()) == true)
{
CoreWebView2.SetVirtualHostNameToFolderMapping(
LocalHostName,
ApplicationPath,
Web.WebView2.Core.CoreWebView2HostResourceAccessKind.Allow);
}
// Auto unmap local virtual app dir host if navigating to any other potentially unsafe domain
else
{
CoreWebView2.ClearVirtualHostNameToFolderMapping(LocalHostName);
}
};
}

WebView2? _internalWebView;

const string LocalScheme = "ms-appx-web:///";
// Arbitrary local host name for virtual folder mapping
const string LocalHostName = "appdir";
const string LocalScheme = $"https://{LocalHostName}/";

// Script to insert a <base> tag into an HTML document
const string BaseInsertionScript = @"
Expand All @@ -19,11 +43,19 @@ public class MauiWebView : WebView2, IWebViewDelegate
head.innerHTML = 'baseTag' + head.innerHTML;
}";

// Allow for packaged/unpackaged app support
string ApplicationPath => AppInfoUtils.IsPackagedApp
? Package.Current.InstalledLocation.Path
: AppContext.BaseDirectory;

public async void LoadHtml(string? html, string? baseUrl)
{
var mapBaseDirectory = false;

if (string.IsNullOrEmpty(baseUrl))
{
baseUrl = LocalScheme;
mapBaseDirectory = true;
}

// Generate a base tag for the document
Expand All @@ -36,7 +68,7 @@ public async void LoadHtml(string? html, string? baseUrl)
_internalWebView = new WebView2();

// TODO: For now, the CoreWebView2 won't be created without either setting Source or
// calling EnsureCoreWebView2Async().
// calling EnsureCoreWebView2Async().
await _internalWebView.EnsureCoreWebView2Async();

// When the 'navigation' to the original HTML string is done, we can modify it to include our <base> tag
Expand All @@ -55,6 +87,14 @@ public async void LoadHtml(string? html, string? baseUrl)

await EnsureCoreWebView2Async();

if (mapBaseDirectory)
{
CoreWebView2.SetVirtualHostNameToFolderMapping(
LocalHostName,
ApplicationPath,
Web.WebView2.Core.CoreWebView2HostResourceAccessKind.Allow);
}

// Set the HTML for the 'real' WebView to the updated HTML
NavigateToString(!string.IsNullOrEmpty(htmlWithBaseTag) ? htmlWithBaseTag : html);

Expand All @@ -66,12 +106,19 @@ public async void LoadHtml(string? html, string? baseUrl)
_internalWebView.NavigateToString(html);
}

public void LoadUrl(string? url)
public async void LoadUrl(string? url)
{
Uri uri = new Uri(url ?? string.Empty, UriKind.RelativeOrAbsolute);

if (!uri.IsAbsoluteUri)
{
await EnsureCoreWebView2Async();

CoreWebView2.SetVirtualHostNameToFolderMapping(
LocalHostName,
ApplicationPath,
Web.WebView2.Core.CoreWebView2HostResourceAccessKind.Allow);

uri = new Uri(LocalScheme + url, UriKind.RelativeOrAbsolute);
}

Expand Down

0 comments on commit 8eba70e

Please sign in to comment.