-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Blazor Windows Open Links in Browser with Configurability #4680
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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,30 @@ 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) | ||
{ | ||
var uri = new Uri(args.Uri); | ||
TanayParikh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (uri.Host != "0.0.0.0" && _externalLinkMode == ExternalLinkMode.OpenInExternalBrowser) | ||
{ | ||
_ = Launcher.LaunchUriAsync(uri); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we log errors thrown by these tasks or do they appear somewhere? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just searched through, there doesn't seem to be an existing logging mechanism. Is there a standardized mechanism we could use here (or perhaps #4441 would cover it?). |
||
args.Cancel = true; | ||
} | ||
} | ||
|
||
private void CoreWebView2_NewWindowRequested(CoreWebView2 sender, CoreWebView2NewWindowRequestedEventArgs args) | ||
{ | ||
// Intercept _blank target <a> tags to always open in device browser | ||
// regardless of ExternalLinkMode.OpenInWebview | ||
var uri = new Uri(args.Uri); | ||
_ = Launcher.LaunchUriAsync(uri); | ||
args.Handled = true; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to unsubscribed when this type is disposed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was under the impression the lifecycle of the
WinUIWebViewManager
and the associatedWebView2Control
would be essentially the same, hence I didn't bother with unsubscribing (given if they get disposed at the same time then there shouldn't be any stray references preventing GC). This is in line with the current async lambda we have forBlazor.Start()
:maui/src/BlazorWebView/src/Maui/Windows/WinUIWebViewManager.cs
Lines 98 to 103 in b00586c
I can add it in if you think it'd be beneficial.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively, instead of hooking the Initialized event at all, you can wait until we force initialization and then hook the events you actually want directly. Here's where we force initialization in the shared code: https://github.com/dotnet/maui/blob/main/src/BlazorWebView/src/SharedSource/WebView2WebViewManager.cs#L93
Because presumably we want exactly this logic on WinForms and WPF as well. Launching the browser will be different between WinUI and non-WinUI, but that could be abstracted via a delegate or something.