diff --git a/Core/FormBrowser.cs b/Core/FormBrowser.cs index 169be2d8..c800efdb 100644 --- a/Core/FormBrowser.cs +++ b/Core/FormBrowser.cs @@ -12,6 +12,7 @@ using TweetDuck.Core.Other.Analytics; using TweetDuck.Core.Utils; using TweetDuck.Plugins; +using TweetDuck.Plugins.Enums; using TweetDuck.Plugins.Events; using TweetDuck.Updates; @@ -38,6 +39,7 @@ public bool IsWaiting{ public string UpdateInstallerPath { get; private set; } + public PluginManager PluginManager => plugins; public AnalyticsFile AnalyticsFile => analytics?.File ?? AnalyticsFile.Dummy; private readonly TweetDeckBrowser browser; @@ -57,17 +59,19 @@ public FormBrowser(UpdaterSettings updaterSettings){ InitializeComponent(); Text = Program.BrandName; - - this.browser = new TweetDeckBrowser(this, new TweetDeckBridge.Browser(this, notification)); - this.contextMenu = ContextMenuBrowser.CreateMenu(this); - this.plugins = new PluginManager(browser, Program.PluginPath, Program.PluginConfigFilePath); + this.plugins = new PluginManager(Program.PluginPath, Program.PluginConfigFilePath); this.plugins.Reloaded += plugins_Reloaded; this.plugins.Executed += plugins_Executed; this.plugins.Reload(); this.notification = new FormNotificationTweet(this, plugins); this.notification.Show(); + + this.browser = new TweetDeckBrowser(this, new TweetDeckBridge.Browser(this, notification)); + this.contextMenu = ContextMenuBrowser.CreateMenu(this); + + this.plugins.Register(browser, PluginEnvironment.Browser, true); Controls.Add(new MenuStrip{ Visible = false }); // fixes Alt freezing the program in Win 10 Anniversary Update diff --git a/Core/Notification/FormNotificationMain.cs b/Core/Notification/FormNotificationMain.cs index e2eac9b1..b6dc98d2 100644 --- a/Core/Notification/FormNotificationMain.cs +++ b/Core/Notification/FormNotificationMain.cs @@ -12,7 +12,7 @@ using TweetDuck.Resources; namespace TweetDuck.Core.Notification{ - abstract partial class FormNotificationMain : FormNotificationBase{ + abstract partial class FormNotificationMain : FormNotificationBase, ITweetDeckBrowser{ private const string NotificationScriptFile = "notification.js"; private static readonly string NotificationScriptIdentifier = ScriptLoader.GetRootIdentifier(NotificationScriptFile); @@ -81,17 +81,35 @@ protected FormNotificationMain(FormBrowser owner, PluginManager pluginManager, b this.timerBarHeight = BrowserUtils.Scale(4, DpiScale); browser.KeyboardHandler = new KeyboardHandlerNotification(this); - browser.RegisterAsyncJsObject("$TD", new TweetDeckBridge.Notification(owner, this)); - browser.RegisterAsyncJsObject("$TDP", plugins.Bridge); browser.LoadingStateChanged += Browser_LoadingStateChanged; browser.FrameLoadEnd += Browser_FrameLoadEnd; + plugins.Register(this, PluginEnvironment.Notification); + mouseHookDelegate = MouseHookProc; Disposed += (sender, args) => StopMouseHook(true); } + void ITweetDeckBrowser.RegisterBridge(string name, object obj){ + browser.RegisterAsyncJsObject(name, obj); + } + + void ITweetDeckBrowser.OnFrameLoaded(Action<IFrame> callback){ + browser.FrameLoadEnd += (sender, args) => { + IFrame frame = args.Frame; + + if (frame.IsMain && NotificationJS != null && browser.Address != "about:blank"){ + callback(frame); + } + }; + } + + void ITweetDeckBrowser.ExecuteFunction(string name, params object[] args){ + browser.ExecuteScriptAsync(name, args); + } + // mouse wheel hook private void StartMouseHook(){ @@ -166,7 +184,6 @@ private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){ if (e.Frame.IsMain && NotificationJS != null && browser.Address != "about:blank"){ e.Frame.ExecuteJavaScriptAsync(PropertyBridge.GenerateScript(PropertyBridge.Environment.Notification)); ScriptLoader.ExecuteScript(e.Frame, NotificationJS, NotificationScriptIdentifier); - plugins.ExecutePlugins(e.Frame, PluginEnvironment.Notification); } } @@ -232,7 +249,7 @@ public override void ResumeNotification(){ protected override string GetTweetHTML(TweetNotification tweet){ string html = base.GetTweetHTML(tweet); - foreach(InjectedHTML injection in plugins.Bridge.NotificationInjections){ + foreach(InjectedHTML injection in plugins.NotificationInjections){ html = injection.Inject(html); } diff --git a/Core/Notification/Screenshot/FormNotificationScreenshotable.cs b/Core/Notification/Screenshot/FormNotificationScreenshotable.cs index 5b2cabc5..df508819 100644 --- a/Core/Notification/Screenshot/FormNotificationScreenshotable.cs +++ b/Core/Notification/Screenshot/FormNotificationScreenshotable.cs @@ -33,7 +33,7 @@ public FormNotificationScreenshotable(Action callback, FormBrowser owner, Plugin protected override string GetTweetHTML(TweetNotification tweet){ string html = tweet.GenerateHtml("td-screenshot", false); - foreach(InjectedHTML injection in plugins.Bridge.NotificationInjections){ + foreach(InjectedHTML injection in plugins.NotificationInjections){ html = injection.Inject(html); } diff --git a/Plugins/PluginManager.cs b/Plugins/PluginManager.cs index 5ea1609e..3ed0917c 100644 --- a/Plugins/PluginManager.cs +++ b/Plugins/PluginManager.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using TweetDuck.Core; +using TweetDuck.Data; using TweetDuck.Plugins.Enums; using TweetDuck.Plugins.Events; using TweetDuck.Resources; @@ -21,42 +22,46 @@ sealed class PluginManager{ public string PathCustomPlugins => Path.Combine(rootPath, "user"); public IEnumerable<Plugin> Plugins => plugins; + public IEnumerable<InjectedHTML> NotificationInjections => bridge.NotificationInjections; + public PluginConfig Config { get; } - public PluginBridge Bridge { get; } public event EventHandler<PluginErrorEventArgs> Reloaded; public event EventHandler<PluginErrorEventArgs> Executed; - private readonly ITweetDeckBrowser browser; private readonly string rootPath; private readonly string configPath; + private readonly PluginBridge bridge; private readonly HashSet<Plugin> plugins = new HashSet<Plugin>(); private readonly Dictionary<int, Plugin> tokens = new Dictionary<int, Plugin>(); private readonly Random rand = new Random(); - public PluginManager(ITweetDeckBrowser browser, string rootPath, string configPath){ - this.browser = browser; + private ITweetDeckBrowser mainBrowser; + + public PluginManager(string rootPath, string configPath){ this.rootPath = rootPath; this.configPath = configPath; this.Config = new PluginConfig(); - this.Bridge = new PluginBridge(this); - - this.browser.OnFrameLoaded(OnFrameLoaded); - this.browser.RegisterBridge("$TDP", Bridge); + this.bridge = new PluginBridge(this); Config.Load(configPath); Config.PluginChangedState += Config_PluginChangedState; } - private void Config_PluginChangedState(object sender, PluginChangedStateEventArgs e){ - browser.ExecuteFunction("TDPF_setPluginState", e.Plugin, e.IsEnabled); - Config.Save(configPath); + public void Register(ITweetDeckBrowser browser, PluginEnvironment environment, bool asMainBrowser = false){ + browser.OnFrameLoaded(frame => ExecutePlugins(frame, environment)); + browser.RegisterBridge("$TDP", bridge); + + if (asMainBrowser){ + mainBrowser = browser; + } } - private void OnFrameLoaded(IFrame frame){ - ExecutePlugins(frame, PluginEnvironment.Browser); + private void Config_PluginChangedState(object sender, PluginChangedStateEventArgs e){ + mainBrowser?.ExecuteFunction("TDPF_setPluginState", e.Plugin, e.IsEnabled); + Config.Save(configPath); } public bool IsPluginInstalled(string identifier){ @@ -68,12 +73,12 @@ public bool HasAnyPlugin(PluginEnvironment environment){ } public bool IsPluginConfigurable(Plugin plugin){ - return plugin.HasConfig || Bridge.WithConfigureFunction.Contains(plugin); + return plugin.HasConfig || bridge.WithConfigureFunction.Contains(plugin); } public void ConfigurePlugin(Plugin plugin){ - if (Bridge.WithConfigureFunction.Contains(plugin)){ - browser.ExecuteFunction("TDPF_configurePlugin", plugin); + if (bridge.WithConfigureFunction.Contains(plugin)){ + mainBrowser?.ExecuteFunction("TDPF_configurePlugin", plugin); } else if (plugin.HasConfig){ if (File.Exists(plugin.ConfigPath)){ @@ -143,7 +148,7 @@ IEnumerable<Plugin> LoadPluginsFrom(string path, PluginGroup group){ Reloaded?.Invoke(this, new PluginErrorEventArgs(loadErrors)); } - public void ExecutePlugins(IFrame frame, PluginEnvironment environment){ + private void ExecutePlugins(IFrame frame, PluginEnvironment environment){ if (!HasAnyPlugin(environment)){ return; }