maui: Unable to block popups in BlazorWebView

Description

When trying to manually handle CoreWebViewOnNewWindowRequested Event we are unable to supress the starting of an external process opening the file dragged into the webiew. It will always open for example Notepad when dragging a .txt file into it.

I managed to locate why this is happening: https://github.com/dotnet/maui/commit/78c1ffe593965d16b5aacd9d320e19c1cac55031#diff-75c4562a2bc68615b8d28c071b33a112272d1e08e4ba087c461736787ff8f534

I think it would be better to check if args.Handled is already set to true and do not proceed if condition matches.

    private void CoreWebView2_NewWindowRequested(object? sender, CoreWebView2NewWindowRequestedEventArgs args)
    {
        // Intercept _blank target <a> tags to always open in device browser.
        // The ExternalLinkCallback is not invoked.

        if (!args.Handled && Uri.TryCreate(args.Uri, UriKind.RelativeOrAbsolute, out var uri))
        {
            LaunchUriInExternalBrowser(uri);
            args.Handled = true;
        }
    }

I did not test it and it may depend on the order of execution of the event listeners. But there has to be a way to disable it. This also prevents any js popup to appear through the webview.

Steps to Reproduce

  1. Create a WinForms app with BlazorWebView.
  2. Drag any file into the webview
  3. A Process will start

Version with bug

6.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

Windows, macOS, Other (Tizen, Linux, etc. not supported by Microsoft directly)

Affected platform versions

Any Version of Windows, MacOS or Linux

Did you find any workaround?

If the page has loaded just do this. It will remove any event handler that was not registered by current class:

    var coreWebView = _blazorWebView.WebView.CoreWebView2;
         
    var eventHandlerField = (EventHandler<CoreWebView2NewWindowRequestedEventArgs>) coreWebView.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
            .First(it => it.Name == "newWindowRequested").GetValue(coreWebView);

    foreach (EventHandler<CoreWebView2NewWindowRequestedEventArgs> subscriber in eventHandlerField.GetInvocationList())
    {
        if (subscriber.Method.DeclaringType == GetType()) continue;
        coreWebView.NewWindowRequested -= subscriber;
    }

Relevant log output

No response

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 24 (8 by maintainers)

Most upvoted comments

I updated my reproduction steps because they weren’t correct. You have to create a WinForms App and use BlazorWebView.