Skip to content

Commit

Permalink
OnExternalNavigationStarting
Browse files Browse the repository at this point in the history
  • Loading branch information
TanayParikh committed Feb 17, 2022
1 parent 96a56cb commit 3c7c2d0
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 37 deletions.
3 changes: 2 additions & 1 deletion Microsoft.Maui.sln
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MauiBlazorWebView.DeviceTes
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SharedSource", "SharedSource", "{4F2926C8-43AB-4328-A735-D9EAD699F81D}"
ProjectSection(SolutionItems) = preProject
src\BlazorWebView\src\SharedSource\ExternalLinkMode.cs = src\BlazorWebView\src\SharedSource\ExternalLinkMode.cs
src\BlazorWebView\src\SharedSource\ExternalLinkNavigationInfo.cs = src\BlazorWebView\src\SharedSource\ExternalLinkNavigationInfo.cs
src\BlazorWebView\src\SharedSource\ExternalLinkNavigationPolicy.cs = src\BlazorWebView\src\SharedSource\ExternalLinkNavigationPolicy.cs
src\BlazorWebView\src\SharedSource\QueryStringHelper.cs = src\BlazorWebView\src\SharedSource\QueryStringHelper.cs
src\BlazorWebView\src\SharedSource\WebView2WebViewManager.cs = src\BlazorWebView\src\SharedSource\WebView2WebViewManager.cs
EndProjectSection
Expand Down
24 changes: 15 additions & 9 deletions src/BlazorWebView/src/Maui/Android/WebKitWebViewClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ public override bool ShouldOverrideUrlLoading(AWebView? view, IWebResourceReques
// Handle redirects to the app custom scheme by reloading the URL in the view.
// Handle navigation to external URLs using the system browser, unless overriden.
var requestUri = request?.Url?.ToString();
if (requestUri != null)
if (Uri.TryCreate(requestUri, UriKind.RelativeOrAbsolute, out var uri))
{
var uri = new Uri(requestUri);

if (uri.Host == BlazorWebView.AppHostAddress &&
view is not null &&
request is not null &&
Expand All @@ -46,13 +44,21 @@ request is not null &&
view.LoadUrl(uri.ToString());
return true;
}
else if (uri.Host != BlazorWebView.AppHostAddress &&
_webViewHandler != null &&
_webViewHandler.ExternalLinkMode == ExternalLinkMode.OpenInExternalBrowser)
else if (uri.Host != BlazorWebView.AppHostAddress && _webViewHandler != null)
{
var intent = new Intent(Intent.ActionView, AUri.Parse(requestUri));
_webViewHandler.Context.StartActivity(intent);
return true;
var callbackArgs = new ExternalLinkNavigationInfo(uri);
var externalLinkMode = _webViewHandler.OnExternalNavigationStarting?.Invoke(callbackArgs) ?? ExternalLinkNavigationPolicy.OpenInExternalBrowser;

if (externalLinkMode == ExternalLinkNavigationPolicy.OpenInExternalBrowser)
{
var intent = new Intent(Intent.ActionView, AUri.Parse(requestUri));
_webViewHandler.Context.StartActivity(intent);
}

if (externalLinkMode != ExternalLinkNavigationPolicy.OpenInWebView)
{
return true;
}
}
}

Expand Down
11 changes: 4 additions & 7 deletions src/BlazorWebView/src/Maui/BlazorWebView.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components.Web;
using System;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebView;
using Microsoft.Extensions.FileProviders;

Expand All @@ -21,12 +22,8 @@ public BlazorWebView()

public RootComponentsCollection RootComponents { get; }

/// <summary>
/// Specify whether links should be opened in the external
/// system default browser, or within the webview.
/// </summary>
/// <value>Defaults to opening links in the system default browser.</value>
public ExternalLinkMode ExternalLinkMode { get; set; } = ExternalLinkMode.OpenInExternalBrowser;
/// <inheritdoc/>
public Func<ExternalLinkNavigationInfo, ExternalLinkNavigationPolicy>? OnExternalNavigationStarting { get; set; }

/// <inheritdoc/>
public virtual IFileProvider CreateFileProvider(string contentRootDir)
Expand Down
11 changes: 6 additions & 5 deletions src/BlazorWebView/src/Maui/BlazorWebViewHandler.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using Microsoft.AspNetCore.Components.WebView;
using Microsoft.Maui;
using Microsoft.Maui.Handlers;
Expand All @@ -11,7 +12,7 @@ public partial class BlazorWebViewHandler
{
[nameof(IBlazorWebView.HostPage)] = MapHostPage,
[nameof(IBlazorWebView.RootComponents)] = MapRootComponents,
[nameof(IBlazorWebView.ExternalLinkMode)] = MapExternalLinkMode,
[nameof(IBlazorWebView.OnExternalNavigationStarting)] = MapOnExternalNavigationStarting,
};

public BlazorWebViewHandler() : base(BlazorWebViewMapper)
Expand Down Expand Up @@ -42,17 +43,17 @@ public static void MapRootComponents(BlazorWebViewHandler handler, IBlazorWebVie
#endif
}

public static void MapExternalLinkMode(BlazorWebViewHandler handler, IBlazorWebView webView)
public static void MapOnExternalNavigationStarting(BlazorWebViewHandler handler, IBlazorWebView webView)
{
#if !NETSTANDARD
handler.ExternalLinkMode = webView.ExternalLinkMode;
handler.OnExternalNavigationStarting = webView.OnExternalNavigationStarting;
handler.StartWebViewCoreIfPossible();
#endif
}

#if !NETSTANDARD
private string? HostPage { get; set; }
internal ExternalLinkMode ExternalLinkMode { get; private set; }
internal Func<ExternalLinkNavigationInfo, ExternalLinkNavigationPolicy>? OnExternalNavigationStarting { get; private set; }

private RootComponentsCollection? _rootComponents;
private RootComponentsCollection? RootComponents
Expand Down
9 changes: 5 additions & 4 deletions src/BlazorWebView/src/Maui/IBlazorWebView.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components.Web;
using System;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebView;
using Microsoft.Extensions.FileProviders;
using Microsoft.Maui;
Expand All @@ -12,10 +13,10 @@ public interface IBlazorWebView : IView
JSComponentConfigurationStore JSComponents { get; }

/// <summary>
/// Specify whether links should be opened in the external
/// system default browser, or within the webview.
/// Allows customizing how external links are opened.
/// Opens external links in the system browser by default.
/// </summary>
ExternalLinkMode ExternalLinkMode { get; set; }
Func<ExternalLinkNavigationInfo, ExternalLinkNavigationPolicy>? OnExternalNavigationStarting { get; set; }

/// <summary>
/// Creates a file provider for static assets used in the <see cref="BlazorWebView"/>. The default implementation
Expand Down
22 changes: 15 additions & 7 deletions src/BlazorWebView/src/Maui/Windows/WinUIWebViewManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,19 +105,27 @@ protected override async Task HandleWebResourceRequest(CoreWebView2WebResourceRe

protected override void CoreWebView2_NavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs args)
{
if (Uri.TryCreate(args.Uri, UriKind.RelativeOrAbsolute, out var uri) &&
uri.Host != AppHostAddress &&
_blazorWebViewHandler.ExternalLinkMode == ExternalLinkMode.OpenInExternalBrowser)
if (Uri.TryCreate(args.Uri, UriKind.RelativeOrAbsolute, out var uri) && uri.Host != AppHostAddress)
{
_ = Launcher.LaunchUriAsync(uri);
args.Cancel = true;
var callbackArgs = new ExternalLinkNavigationInfo(uri);
var externalLinkMode = _blazorWebViewHandler.OnExternalNavigationStarting?.Invoke(callbackArgs) ?? ExternalLinkNavigationPolicy.OpenInExternalBrowser;

if (externalLinkMode == ExternalLinkNavigationPolicy.OpenInExternalBrowser)
{
_ = Launcher.LaunchUriAsync(uri);
}

if (externalLinkMode != ExternalLinkNavigationPolicy.OpenInWebView)
{
args.Cancel = true;
}
}
}

protected override void CoreWebView2_NewWindowRequested(object sender, CoreWebView2NewWindowRequestedEventArgs args)
{
// Intercept _blank target <a> tags to always open in device browser
// regardless of ExternalLinkMode.OpenInWebview
// Intercept _blank target <a> tags to always open in device browser.
// The ExternalLinkCallback is not invoked.
if (Uri.TryCreate(args.Uri, UriKind.RelativeOrAbsolute, out var uri))
{
_ = Launcher.LaunchUriAsync(uri);
Expand Down
23 changes: 23 additions & 0 deletions src/BlazorWebView/src/SharedSource/ExternalLinkNavigationInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;

namespace Microsoft.AspNetCore.Components.WebView
{
/// <summary>
/// Used to provide information about a link (<![CDATA[<a>]]>) clicked within a Blazor WebView.
///
/// `_blank` target links will always open in the default browser
/// thus the OnExternalNavigationStarting won't be called.
/// </summary>
public class ExternalLinkNavigationInfo
{
public ExternalLinkNavigationInfo(Uri uri)
{
Uri = uri;
}

/// <summary>
/// External <see cref="Uri">Uri</see> to be navigated to.
/// </summary>
public Uri Uri { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
namespace Microsoft.AspNetCore.Components.WebView
{
/// <summary>
/// Link handling mode for anchor tags <![CDATA[<a>]]> within a Blazor WebView.
/// Link handling policy for anchor tags <![CDATA[<a>]]> within a Blazor WebView.
///
/// `_blank` target links will always open in the default browser
/// regardless of this setting.
/// regardless of the policy.
/// </summary>
public enum ExternalLinkMode
public enum ExternalLinkNavigationPolicy
{
/// <summary>
/// Opens anchor tags <![CDATA[<a>]]> in the system default browser.
Expand All @@ -16,6 +16,11 @@ public enum ExternalLinkMode
/// <summary>
/// Opens anchor tags <![CDATA[<a>]]> in the WebView. This is not recommended.
/// </summary>
OpenInWebView
OpenInWebView,

/// <summary>
/// Cancels the current navigation attempt to an external link.
/// </summary>
CancelNavigation
}
}

0 comments on commit 3c7c2d0

Please sign in to comment.