diff --git a/CefGlue.Common/BaseCefBrowser.cs b/CefGlue.Common/BaseCefBrowser.cs index 999dee74..077d1340 100644 --- a/CefGlue.Common/BaseCefBrowser.cs +++ b/CefGlue.Common/BaseCefBrowser.cs @@ -201,6 +201,11 @@ protected virtual void Dispose(bool disposing) /// Return the handler for JavaScript dialogs. If no handler is provided the default implementation will be used. /// public JSDialogHandler JSDialogHandler { get => _adapter.JSDialogHandler; set => _adapter.JSDialogHandler = value; } + + /// + /// Return the handler for browser permission events. + /// + public PermissionHandler PermissionHandler { get => _adapter.PermissionHandler; set => _adapter.PermissionHandler = value; } /// /// Gets or set the url. diff --git a/CefGlue.Common/CommonBrowserAdapter.cs b/CefGlue.Common/CommonBrowserAdapter.cs index 5f249930..bc8a3293 100644 --- a/CefGlue.Common/CommonBrowserAdapter.cs +++ b/CefGlue.Common/CommonBrowserAdapter.cs @@ -137,6 +137,7 @@ protected virtual void InnerDispose() { } public DisplayHandler DisplayHandler { get; set; } public RenderHandler RenderHandler { get; set; } public JSDialogHandler JSDialogHandler { get; set; } + public PermissionHandler PermissionHandler { get; set; } #endregion diff --git a/CefGlue.Common/CommonCefClient.cs b/CefGlue.Common/CommonCefClient.cs index c11aad77..ee344c62 100644 --- a/CefGlue.Common/CommonCefClient.cs +++ b/CefGlue.Common/CommonCefClient.cs @@ -104,6 +104,11 @@ protected override CefFrameHandler GetFrameHandler() { return _frameHandler; } + + protected override CefPermissionHandler GetPermissionHandler() + { + return _owner.PermissionHandler; + } protected override bool OnProcessMessageReceived(CefBrowser browser, CefFrame frame, CefProcessId sourceProcess, CefProcessMessage message) { diff --git a/CefGlue.Common/Handlers/Handlers.cs b/CefGlue.Common/Handlers/Handlers.cs index 7591b417..f83fad63 100644 --- a/CefGlue.Common/Handlers/Handlers.cs +++ b/CefGlue.Common/Handlers/Handlers.cs @@ -103,6 +103,8 @@ public class FocusHandler : CefFocusHandler { } public abstract class JSDialogHandler : CefJSDialogHandler { } public class KeyboardHandler : CefKeyboardHandler { } + + public abstract class PermissionHandler : CefPermissionHandler { } public class LifeSpanHandler : CefLifeSpanHandler { diff --git a/CefGlue.Common/ICefBrowserHost.cs b/CefGlue.Common/ICefBrowserHost.cs index 92074670..ff57fc6e 100644 --- a/CefGlue.Common/ICefBrowserHost.cs +++ b/CefGlue.Common/ICefBrowserHost.cs @@ -41,5 +41,6 @@ internal interface ICefBrowserHost DisplayHandler DisplayHandler { get; set; } RenderHandler RenderHandler { get; set; } JSDialogHandler JSDialogHandler { get; set; } + PermissionHandler PermissionHandler { get; set; } } } diff --git a/CefGlue.Demo.Avalonia/BrowserView.axaml.cs b/CefGlue.Demo.Avalonia/BrowserView.axaml.cs index 51cecec4..b44aeeea 100644 --- a/CefGlue.Demo.Avalonia/BrowserView.axaml.cs +++ b/CefGlue.Demo.Avalonia/BrowserView.axaml.cs @@ -30,6 +30,7 @@ public BrowserView() browser.LoadStart += OnBrowserLoadStart; browser.TitleChanged += OnBrowserTitleChanged; browser.LifeSpanHandler = new BrowserLifeSpanHandler(); + browser.PermissionHandler = new BrowserPermissionHandler(); browserWrapper.Child = browser; } @@ -169,5 +170,51 @@ protected override bool OnBeforePopup( return true; } } + + /// + /// Simplified permission handler for browser requests. + /// + internal sealed class BrowserPermissionHandler : PermissionHandler + { + protected override bool OnRequestMediaAccessPermission(CefBrowser browser, CefFrame frame, + string requestingOrigin, + CefMediaAccessPermissionTypes requestedPermissions, CefMediaAccessCallback callback) + { + if (browser == null || callback == null) return false; + + // Grant all requested media permissions for all sites. + callback.Continue(requestedPermissions); + return true; + } + + /// + /// Called when a permission prompt is shown (e.g., clipboard, geolocation, notifications). + /// Grants permissions for all sites. For testing, you can filter by checking requestingOrigin, + /// e.g., if (requestingOrigin.Contains("test-site.com")) to restrict to specific domains. + /// + /// The browser instance initiating the prompt. + /// The unique ID of the permission prompt. + /// The origin requesting the permission. + /// The requested permission types. + /// The callback to invoke with the permission result. + /// True if the prompt was handled, false otherwise. + protected override bool OnShowPermissionPrompt(CefBrowser browser, ulong promptId, string requestingOrigin, + CefPermissionRequestTypes requestedPermissions, CefPermissionPromptCallback callback) + { + if (browser == null || callback == null) return false; + + // Allow clipboard, geolocation, and notifications for all sites. + var result = CefPermissionRequestResult.Deny; + if (requestedPermissions.HasFlag(CefPermissionRequestTypes.Clipboard) || + requestedPermissions.HasFlag(CefPermissionRequestTypes.Geolocation) || + requestedPermissions.HasFlag(CefPermissionRequestTypes.Notifications)) + { + result = CefPermissionRequestResult.Accept; + } + + callback.Continue(result); + return true; + } + } } } diff --git a/CefGlue.Demo.WPF/BrowserView.xaml.cs b/CefGlue.Demo.WPF/BrowserView.xaml.cs index a1df8f21..8a7c47f1 100644 --- a/CefGlue.Demo.WPF/BrowserView.xaml.cs +++ b/CefGlue.Demo.WPF/BrowserView.xaml.cs @@ -3,6 +3,7 @@ using System.Windows.Controls; using System.Windows.Input; using Xilium.CefGlue.Common.Events; +using Xilium.CefGlue.Common.Handlers; namespace Xilium.CefGlue.Demo.WPF { @@ -12,6 +13,53 @@ public BrowserView() { InitializeComponent(); //browser.RegisterJavascriptObject(new BindingTestClass(), "boundBeforeLoadObject"); + //browser.PermissionHandler = new BrowserPermissionHandler(); + } + + /// + /// Simplified permission handler for browser requests. + /// + internal sealed class BrowserPermissionHandler : PermissionHandler + { + protected override bool OnRequestMediaAccessPermission(CefBrowser browser, CefFrame frame, + string requestingOrigin, + CefMediaAccessPermissionTypes requestedPermissions, CefMediaAccessCallback callback) + { + if (browser == null || callback == null) return false; + + // Grant all requested media permissions for all sites. + callback.Continue(requestedPermissions); + return true; + } + + /// + /// Called when a permission prompt is shown (e.g., clipboard, geolocation, notifications). + /// Grants permissions for all sites. For testing, you can filter by checking requestingOrigin, + /// e.g., if (requestingOrigin.Contains("test-site.com")) to restrict to specific domains. + /// + /// The browser instance initiating the prompt. + /// The unique ID of the permission prompt. + /// The origin requesting the permission. + /// The requested permission types. + /// The callback to invoke with the permission result. + /// True if the prompt was handled, false otherwise. + protected override bool OnShowPermissionPrompt(CefBrowser browser, ulong promptId, string requestingOrigin, + CefPermissionRequestTypes requestedPermissions, CefPermissionPromptCallback callback) + { + if (browser == null || callback == null) return false; + + // Allow clipboard, geolocation, and notifications for all sites. + var result = CefPermissionRequestResult.Deny; + if (requestedPermissions.HasFlag(CefPermissionRequestTypes.Clipboard) || + requestedPermissions.HasFlag(CefPermissionRequestTypes.Geolocation) || + requestedPermissions.HasFlag(CefPermissionRequestTypes.Notifications)) + { + result = CefPermissionRequestResult.Accept; + } + + callback.Continue(result); + return true; + } } public event Action TitleChanged;