diff --git a/Core/Handling/ResourceHandlerFactory.cs b/Core/Handling/ResourceHandlerFactory.cs new file mode 100644 index 00000000..cba2649e --- /dev/null +++ b/Core/Handling/ResourceHandlerFactory.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Concurrent; +using CefSharp; +using TweetDuck.Data; + +namespace TweetDuck.Core.Handling{ + sealed class ResourceHandlerFactory : IResourceHandlerFactory{ + public bool HasHandlers => !handlers.IsEmpty; + + private readonly ConcurrentDictionary<string, IResourceHandler> handlers = new ConcurrentDictionary<string, IResourceHandler>(StringComparer.OrdinalIgnoreCase); + + public IResourceHandler GetResourceHandler(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request){ + try{ + return handlers.TryGetValue(request.Url, out IResourceHandler handler) ? handler : null; + }finally{ + request.Dispose(); + } + } + + // registration + + public bool RegisterHandler(string url, IResourceHandler handler){ + if (Uri.TryCreate(url, UriKind.Absolute, out Uri uri)){ + handlers.AddOrUpdate(uri.AbsoluteUri, handler, (key, prev) => handler); + return true; + } + + return false; + } + + public bool RegisterHandler(ResourceLink link){ + return RegisterHandler(link.Url, link.Handler); + } + + public bool UnregisterHandler(string url){ + return handlers.TryRemove(url, out IResourceHandler _); + } + + public bool UnregisterHandler(ResourceLink link){ + return UnregisterHandler(link.Url); + } + } +} diff --git a/Core/Notification/FormNotificationBase.cs b/Core/Notification/FormNotificationBase.cs index 228b0bbe..cc3275fa 100644 --- a/Core/Notification/FormNotificationBase.cs +++ b/Core/Notification/FormNotificationBase.cs @@ -121,18 +121,20 @@ protected FormNotificationBase(FormBrowser owner, bool enableContextMenu){ this.owner = owner; this.owner.FormClosed += owner_FormClosed; + ResourceHandlerFactory resourceHandlerFactory = new ResourceHandlerFactory(); + resourceHandlerFactory.RegisterHandler(TwitterUtils.TweetDeckURL, this.resourceHandler); + resourceHandlerFactory.RegisterHandler(TweetNotification.AppLogo); + this.browser = new ChromiumWebBrowser("about:blank"){ MenuHandler = new ContextMenuNotification(this, enableContextMenu), JsDialogHandler = new JavaScriptDialogHandler(), LifeSpanHandler = new LifeSpanHandler(), - RequestHandler = new RequestHandlerBase(false) + RequestHandler = new RequestHandlerBase(false), + ResourceHandlerFactory = resourceHandlerFactory }; this.browser.Dock = DockStyle.None; this.browser.ClientSize = ClientSize; - - this.browser.SetupResourceHandler(TwitterUtils.TweetDeckURL, this.resourceHandler); - this.browser.SetupResourceHandler(TweetNotification.AppLogo); this.browser.SetupZoomEvents(); Controls.Add(browser); diff --git a/Core/Other/FormGuide.cs b/Core/Other/FormGuide.cs index 4dec265b..67aa2051 100644 --- a/Core/Other/FormGuide.cs +++ b/Core/Other/FormGuide.cs @@ -63,12 +63,16 @@ private FormGuide(string url, FormBrowser owner){ Text = Program.BrandName+" Guide"; Size = new Size(owner.Size.Width*3/4, owner.Size.Height*3/4); VisibleChanged += (sender, args) => this.MoveToCenter(owner); + + ResourceHandlerFactory resourceHandlerFactory = new ResourceHandlerFactory(); + resourceHandlerFactory.RegisterHandler(DummyPage); this.browser = new ChromiumWebBrowser(url){ MenuHandler = new ContextMenuGuide(owner), JsDialogHandler = new JavaScriptDialogHandler(), LifeSpanHandler = new LifeSpanHandler(), - RequestHandler = new RequestHandlerBase(true) + RequestHandler = new RequestHandlerBase(true), + ResourceHandlerFactory = resourceHandlerFactory }; browser.LoadingStateChanged += browser_LoadingStateChanged; @@ -77,8 +81,6 @@ private FormGuide(string url, FormBrowser owner){ browser.BrowserSettings.BackgroundColor = (uint)BackColor.ToArgb(); browser.Dock = DockStyle.None; browser.Location = ControlExtensions.InvisibleLocation; - - browser.SetupResourceHandler(DummyPage); browser.SetupZoomEvents(); Controls.Add(browser); diff --git a/Core/TweetDeckBrowser.cs b/Core/TweetDeckBrowser.cs index c024d96a..9d11d7c2 100644 --- a/Core/TweetDeckBrowser.cs +++ b/Core/TweetDeckBrowser.cs @@ -39,10 +39,14 @@ public bool IsTweetDeckWebsite{ } private readonly ChromiumWebBrowser browser; + private readonly ResourceHandlerFactory resourceHandlerFactory = new ResourceHandlerFactory(); private string prevSoundNotificationPath = null; public TweetDeckBrowser(FormBrowser owner, PluginManager plugins, TweetDeckBridge tdBridge, UpdateBridge updateBridge){ + resourceHandlerFactory.RegisterHandler(TweetNotification.AppLogo); + resourceHandlerFactory.RegisterHandler(TwitterUtils.LoadingSpinner); + RequestHandlerBrowser requestHandler = new RequestHandlerBrowser(); this.browser = new ChromiumWebBrowser(TwitterUtils.TweetDeckURL){ @@ -52,7 +56,8 @@ public TweetDeckBrowser(FormBrowser owner, PluginManager plugins, TweetDeckBridg JsDialogHandler = new JavaScriptDialogHandler(), KeyboardHandler = new KeyboardHandlerBrowser(owner), LifeSpanHandler = new LifeSpanHandler(), - RequestHandler = requestHandler + RequestHandler = requestHandler, + ResourceHandlerFactory = resourceHandlerFactory }; this.browser.LoadingStateChanged += browser_LoadingStateChanged; @@ -66,11 +71,8 @@ public TweetDeckBrowser(FormBrowser owner, PluginManager plugins, TweetDeckBridg this.browser.BrowserSettings.BackgroundColor = (uint)TwitterUtils.BackgroundColor.ToArgb(); this.browser.Dock = DockStyle.None; this.browser.Location = ControlExtensions.InvisibleLocation; - - this.browser.SetupResourceHandler(TweetNotification.AppLogo); - this.browser.SetupResourceHandler(TwitterUtils.LoadingSpinner); this.browser.SetupZoomEvents(); - + owner.Controls.Add(browser); plugins.Register(browser, PluginEnvironment.Browser, owner, true); @@ -174,10 +176,16 @@ private void Config_SoundNotificationInfoChanged(object sender, EventArgs e){ bool hasCustomSound = Config.IsCustomSoundNotificationSet; string newNotificationPath = Config.NotificationSoundPath; - + if (prevSoundNotificationPath != newNotificationPath){ - browser.SetupResourceHandler(soundUrl, hasCustomSound ? SoundNotification.CreateFileHandler(newNotificationPath) : null); prevSoundNotificationPath = newNotificationPath; + + if (hasCustomSound){ + resourceHandlerFactory.RegisterHandler(soundUrl, SoundNotification.CreateFileHandler(newNotificationPath)); + } + else{ + resourceHandlerFactory.UnregisterHandler(soundUrl); + } } browser.ExecuteScriptAsync("TDGF_setSoundNotificationData", hasCustomSound, Config.NotificationSoundVolume); diff --git a/Core/Utils/BrowserUtils.cs b/Core/Utils/BrowserUtils.cs index c6019af6..ad143c0c 100644 --- a/Core/Utils/BrowserUtils.cs +++ b/Core/Utils/BrowserUtils.cs @@ -60,21 +60,6 @@ public static ChromiumWebBrowser AsControl(this IWebBrowser browserControl){ return (ChromiumWebBrowser)browserControl; } - public static void SetupResourceHandler(this ChromiumWebBrowser browser, string url, IResourceHandler handler){ - DefaultResourceHandlerFactory factory = (DefaultResourceHandlerFactory)browser.ResourceHandlerFactory; - - if (handler == null){ - factory.UnregisterHandler(url); - } - else{ - factory.RegisterHandler(url, handler); - } - } - - public static void SetupResourceHandler(this ChromiumWebBrowser browser, ResourceLink resource){ - browser.SetupResourceHandler(resource.Url, resource.Handler); - } - public static void SetupZoomEvents(this ChromiumWebBrowser browser){ void UpdateZoomLevel(object sender, EventArgs args){ SetZoomLevel(browser.GetBrowser(), Config.ZoomLevel); diff --git a/TweetDuck.csproj b/TweetDuck.csproj index 35223003..06ae04dc 100644 --- a/TweetDuck.csproj +++ b/TweetDuck.csproj @@ -95,6 +95,7 @@ <Compile Include="Core\Handling\KeyboardHandlerNotification.cs" /> <Compile Include="Core\Handling\RequestHandlerBase.cs" /> <Compile Include="Core\Handling\RequestHandlerBrowser.cs" /> + <Compile Include="Core\Handling\ResourceHandlerFactory.cs" /> <Compile Include="Core\Handling\ResourceHandlerNotification.cs" /> <Compile Include="Core\Management\ContextInfo.cs" /> <Compile Include="Core\Notification\Example\FormNotificationExample.cs">