From 4b9b46255e216dd289fe072f6b0d2a368dadd1fd Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 14 Oct 2026 19:21:05 +0200 Subject: [PATCH] [WebKit] Preserve native defaults for unhandled WebView policy events Mark the three WebPolicyDelegate decision callbacks with NoDefaultValue so the generated event delegate only responds to selectors with subscribed handlers. This lets WebKit apply its native policy when, for example, navigation is handled but MIME-type decisions are not, instead of leaving the load unresolved. Add a macOS regression test covering each selector as handlers are added and removed, while preserving the ordinary policy-failure notification. Fixes https://github.com/dotnet/macios/issues/4214 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 94248f0f-e005-4288-8334-d17603eeaf29 --- src/webkit.cs | 3 ++ tests/monotouch-test/WebKit/WebViewTest.cs | 56 ++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 tests/monotouch-test/WebKit/WebViewTest.cs diff --git a/src/webkit.cs b/src/webkit.cs index a856d7517355..ebe772e853c8 100644 --- a/src/webkit.cs +++ b/src/webkit.cs @@ -2429,6 +2429,7 @@ partial interface WebPolicyDelegate { To be added. To be added. """)] + [NoDefaultValue] void DecidePolicyForNavigation (WebView webView, NSDictionary actionInformation, NSUrlRequest request, WebFrame frame, NSObject decisionToken); /// To be added. @@ -2442,6 +2443,7 @@ partial interface WebPolicyDelegate { To be added. To be added. """)] + [NoDefaultValue] void DecidePolicyForNewWindow (WebView webView, NSDictionary actionInformation, NSUrlRequest request, string newFrameName, NSObject decisionToken); /// To be added. @@ -2455,6 +2457,7 @@ partial interface WebPolicyDelegate { To be added. To be added. """)] + [NoDefaultValue] void DecidePolicyForMimeType (WebView webView, string mimeType, NSUrlRequest request, WebFrame frame, NSObject decisionToken); /// To be added. diff --git a/tests/monotouch-test/WebKit/WebViewTest.cs b/tests/monotouch-test/WebKit/WebViewTest.cs new file mode 100644 index 000000000000..17639a5bb6c1 --- /dev/null +++ b/tests/monotouch-test/WebKit/WebViewTest.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#nullable enable + +#if __MACOS__ + +using WebKit; + +namespace MonoTouchFixtures.WebKit { + [TestFixture] + [Preserve (AllMembers = true)] + public class WebViewTest { + [Test] + public void PolicyDelegateSelectors () + { + using var view = new WebView (); + view.UnableToImplementPolicy += (sender, e) => { }; + + var policyDelegate = view.WeakPolicyDelegate ?? throw new AssertionException ("Policy delegate was not created."); + + var navigation = new Selector ("webView:decidePolicyForNavigationAction:request:frame:decisionListener:"); + var newWindow = new Selector ("webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:"); + var mimeType = new Selector ("webView:decidePolicyForMIMEType:request:frame:decisionListener:"); + var failure = new Selector ("webView:unableToImplementPolicyWithError:frame:"); + + void AssertSelectors (bool handlesNavigation, bool handlesNewWindow, bool handlesMimeType) + { + Assert.That (policyDelegate.RespondsToSelector (navigation), Is.EqualTo (handlesNavigation), "Navigation"); + Assert.That (policyDelegate.RespondsToSelector (newWindow), Is.EqualTo (handlesNewWindow), "New window"); + Assert.That (policyDelegate.RespondsToSelector (mimeType), Is.EqualTo (handlesMimeType), "MIME type"); + Assert.That (policyDelegate.RespondsToSelector (failure), Is.True, "Failure notification"); + } + + EventHandler navigationHandler = (sender, e) => { }; + EventHandler newWindowHandler = (sender, e) => { }; + EventHandler mimeTypeHandler = (sender, e) => { }; + + AssertSelectors (false, false, false); + view.DecidePolicyForNavigation += navigationHandler; + AssertSelectors (true, false, false); + view.DecidePolicyForNewWindow += newWindowHandler; + AssertSelectors (true, true, false); + view.DecidePolicyForMimeType += mimeTypeHandler; + AssertSelectors (true, true, true); + view.DecidePolicyForNavigation -= navigationHandler; + AssertSelectors (false, true, true); + view.DecidePolicyForNewWindow -= newWindowHandler; + AssertSelectors (false, false, true); + view.DecidePolicyForMimeType -= mimeTypeHandler; + AssertSelectors (false, false, false); + } + } +} + +#endif