diff --git a/src/BlazorWebView/src/Maui/Windows/BlazorWebViewHandler.Windows.cs b/src/BlazorWebView/src/Maui/Windows/BlazorWebViewHandler.Windows.cs index 66e44a550b81..818e97aac615 100644 --- a/src/BlazorWebView/src/Maui/Windows/BlazorWebViewHandler.Windows.cs +++ b/src/BlazorWebView/src/Maui/Windows/BlazorWebViewHandler.Windows.cs @@ -58,7 +58,14 @@ private void StartWebViewCoreIfPossible() var fileProvider = VirtualView.CreateFileProvider(contentRootDir); - _webviewManager = new WinUIWebViewManager(NativeView, Services!, ComponentsDispatcher, fileProvider, VirtualView.JSComponents, hostPageRelativePath, contentRootDir); + _webviewManager = new WinUIWebViewManager(NativeView, + Services!, + ComponentsDispatcher, + fileProvider, + VirtualView.JSComponents, + hostPageRelativePath, + contentRootDir, + ExternalLinkMode); if (RootComponents != null) { diff --git a/src/BlazorWebView/src/Maui/Windows/WinUIWebViewManager.cs b/src/BlazorWebView/src/Maui/Windows/WinUIWebViewManager.cs index 9a1378614013..f4a948ef0ec3 100644 --- a/src/BlazorWebView/src/Maui/Windows/WinUIWebViewManager.cs +++ b/src/BlazorWebView/src/Maui/Windows/WinUIWebViewManager.cs @@ -8,6 +8,7 @@ using Microsoft.Web.WebView2.Core; using Windows.ApplicationModel; using Windows.Storage.Streams; +using Launcher = Windows.System.Launcher; using WebView2Control = Microsoft.UI.Xaml.Controls.WebView2; namespace Microsoft.AspNetCore.Components.WebView.Maui @@ -21,13 +22,25 @@ public class WinUIWebViewManager : WebView2WebViewManager private readonly WebView2Control _webview; private readonly string _hostPageRelativePath; private readonly string _contentRootDir; + private readonly ExternalLinkMode _externalLinkMode; - public WinUIWebViewManager(WebView2Control webview, IServiceProvider services, Dispatcher dispatcher, IFileProvider fileProvider, JSComponentConfigurationStore jsComponents, string hostPageRelativePath, string contentRootDir) + public WinUIWebViewManager( + WebView2Control webview!!, + IServiceProvider services, + Dispatcher dispatcher, + IFileProvider fileProvider, + JSComponentConfigurationStore jsComponents, + string hostPageRelativePath, + string contentRootDir, + ExternalLinkMode externalLinkMode) : base(webview, services, dispatcher, fileProvider, jsComponents, hostPageRelativePath) { _webview = webview; _hostPageRelativePath = hostPageRelativePath; _contentRootDir = contentRootDir; + _externalLinkMode = externalLinkMode; + + _webview.CoreWebView2Initialized += Webview_CoreWebView2Initialized; } protected override async Task HandleWebResourceRequest(CoreWebView2WebResourceRequestedEventArgs eventArgs) @@ -102,5 +115,33 @@ protected override void QueueBlazorStart() "); }; } + + private void Webview_CoreWebView2Initialized(WebView2Control sender, UI.Xaml.Controls.CoreWebView2InitializedEventArgs args) + { + _webview.CoreWebView2.NavigationStarting += CoreWebView2_NavigationStarting; + _webview.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested; + } + + private void CoreWebView2_NavigationStarting(CoreWebView2 sender, CoreWebView2NavigationStartingEventArgs args) + { + if (Uri.TryCreate(args.Uri, UriKind.RelativeOrAbsolute, out var uri) && + uri.Host != "0.0.0.0" && + _externalLinkMode == ExternalLinkMode.OpenInExternalBrowser) + { + _ = Launcher.LaunchUriAsync(uri); + args.Cancel = true; + } + } + + private void CoreWebView2_NewWindowRequested(CoreWebView2 sender, CoreWebView2NewWindowRequestedEventArgs args) + { + // Intercept _blank target tags to always open in device browser + // regardless of ExternalLinkMode.OpenInWebview + if (Uri.TryCreate(args.Uri, UriKind.RelativeOrAbsolute, out var uri)) + { + _ = Launcher.LaunchUriAsync(uri); + args.Handled = true; + } + } } }