mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-06-07 20:34:08 +02:00
Refactor TweetDeck browser into a separate class
This commit is contained in:
parent
0b4aaf80dc
commit
351b174b86
@ -1,13 +1,10 @@
|
|||||||
using CefSharp;
|
using System;
|
||||||
using CefSharp.WinForms;
|
|
||||||
using System;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using TweetDuck.Configuration;
|
using TweetDuck.Configuration;
|
||||||
using TweetDuck.Core.Bridge;
|
using TweetDuck.Core.Bridge;
|
||||||
using TweetDuck.Core.Controls;
|
using TweetDuck.Core.Controls;
|
||||||
using TweetDuck.Core.Handling;
|
using TweetDuck.Core.Handling;
|
||||||
using TweetDuck.Core.Handling.General;
|
|
||||||
using TweetDuck.Core.Notification;
|
using TweetDuck.Core.Notification;
|
||||||
using TweetDuck.Core.Notification.Screenshot;
|
using TweetDuck.Core.Notification.Screenshot;
|
||||||
using TweetDuck.Core.Other;
|
using TweetDuck.Core.Other;
|
||||||
@ -15,9 +12,7 @@
|
|||||||
using TweetDuck.Core.Other.Settings;
|
using TweetDuck.Core.Other.Settings;
|
||||||
using TweetDuck.Core.Utils;
|
using TweetDuck.Core.Utils;
|
||||||
using TweetDuck.Plugins;
|
using TweetDuck.Plugins;
|
||||||
using TweetDuck.Plugins.Enums;
|
|
||||||
using TweetDuck.Plugins.Events;
|
using TweetDuck.Plugins.Events;
|
||||||
using TweetDuck.Resources;
|
|
||||||
using TweetDuck.Updates;
|
using TweetDuck.Updates;
|
||||||
using TweetLib.Audio;
|
using TweetLib.Audio;
|
||||||
|
|
||||||
@ -44,15 +39,13 @@ public bool IsWaiting{
|
|||||||
|
|
||||||
public string UpdateInstallerPath { get; private set; }
|
public string UpdateInstallerPath { get; private set; }
|
||||||
|
|
||||||
private readonly ChromiumWebBrowser browser;
|
private readonly TweetDeckBrowser browser;
|
||||||
private readonly PluginManager plugins;
|
private readonly PluginManager plugins;
|
||||||
private readonly UpdateHandler updates;
|
private readonly UpdateHandler updates;
|
||||||
private readonly FormNotificationTweet notification;
|
private readonly FormNotificationTweet notification;
|
||||||
private readonly ContextMenu contextMenu;
|
private readonly ContextMenu contextMenu;
|
||||||
private readonly MemoryUsageTracker memoryUsageTracker;
|
|
||||||
|
|
||||||
private bool isLoaded;
|
private bool isLoaded;
|
||||||
private bool isBrowserReady;
|
|
||||||
private FormWindowState prevState;
|
private FormWindowState prevState;
|
||||||
|
|
||||||
private TweetScreenshotManager notificationScreenshotManager;
|
private TweetScreenshotManager notificationScreenshotManager;
|
||||||
@ -67,12 +60,8 @@ public FormBrowser(UpdaterSettings updaterSettings){
|
|||||||
this.plugins = new PluginManager(Program.PluginPath, Program.PluginConfigFilePath);
|
this.plugins = new PluginManager(Program.PluginPath, Program.PluginConfigFilePath);
|
||||||
this.plugins.Reloaded += plugins_Reloaded;
|
this.plugins.Reloaded += plugins_Reloaded;
|
||||||
this.plugins.Executed += plugins_Executed;
|
this.plugins.Executed += plugins_Executed;
|
||||||
this.plugins.PluginChangedState += plugins_PluginChangedState;
|
|
||||||
this.plugins.Reload();
|
this.plugins.Reload();
|
||||||
|
|
||||||
this.contextMenu = ContextMenuBrowser.CreateMenu(this);
|
|
||||||
this.memoryUsageTracker = new MemoryUsageTracker("TDGF_tryRunCleanup");
|
|
||||||
|
|
||||||
this.notification = new FormNotificationTweet(this, plugins){
|
this.notification = new FormNotificationTweet(this, plugins){
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
CanMoveWindow = () => (ModifierKeys & Keys.Alt) == Keys.Alt
|
CanMoveWindow = () => (ModifierKeys & Keys.Alt) == Keys.Alt
|
||||||
@ -83,37 +72,12 @@ public FormBrowser(UpdaterSettings updaterSettings){
|
|||||||
|
|
||||||
this.notification.Show();
|
this.notification.Show();
|
||||||
|
|
||||||
this.browser = new ChromiumWebBrowser("https://tweetdeck.twitter.com/"){
|
this.browser = new TweetDeckBrowser(this, plugins, new TweetDeckBridge(this, notification));
|
||||||
DialogHandler = new FileDialogHandler(),
|
this.contextMenu = ContextMenuBrowser.CreateMenu(this);
|
||||||
DragHandler = new DragHandlerBrowser(),
|
|
||||||
MenuHandler = new ContextMenuBrowser(this),
|
|
||||||
JsDialogHandler = new JavaScriptDialogHandler(),
|
|
||||||
KeyboardHandler = new KeyboardHandlerBrowser(this),
|
|
||||||
LifeSpanHandler = new LifeSpanHandler(),
|
|
||||||
RequestHandler = new RequestHandlerBrowser()
|
|
||||||
};
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
this.browser.ConsoleMessage += BrowserUtils.HandleConsoleMessage;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
this.browser.LoadingStateChanged += browser_LoadingStateChanged;
|
|
||||||
this.browser.FrameLoadStart += browser_FrameLoadStart;
|
|
||||||
this.browser.FrameLoadEnd += browser_FrameLoadEnd;
|
|
||||||
this.browser.LoadError += browser_LoadError;
|
|
||||||
this.browser.RegisterAsyncJsObject("$TD", new TweetDeckBridge(this, notification));
|
|
||||||
this.browser.RegisterAsyncJsObject("$TDP", plugins.Bridge);
|
|
||||||
|
|
||||||
browser.BrowserSettings.BackgroundColor = (uint)TwitterUtils.BackgroundColor.ToArgb();
|
|
||||||
browser.Dock = DockStyle.None;
|
|
||||||
browser.Location = ControlExtensions.InvisibleLocation;
|
|
||||||
Controls.Add(browser);
|
|
||||||
|
|
||||||
Controls.Add(new MenuStrip{ Visible = false }); // fixes Alt freezing the program in Win 10 Anniversary Update
|
Controls.Add(new MenuStrip{ Visible = false }); // fixes Alt freezing the program in Win 10 Anniversary Update
|
||||||
|
|
||||||
Disposed += (sender, args) => {
|
Disposed += (sender, args) => {
|
||||||
memoryUsageTracker.Dispose();
|
|
||||||
|
|
||||||
browser.Dispose();
|
browser.Dispose();
|
||||||
contextMenu.Dispose();
|
contextMenu.Dispose();
|
||||||
|
|
||||||
@ -128,10 +92,7 @@ public FormBrowser(UpdaterSettings updaterSettings){
|
|||||||
|
|
||||||
UpdateTrayIcon();
|
UpdateTrayIcon();
|
||||||
|
|
||||||
Config.MuteToggled += Config_MuteToggled;
|
this.updates = browser.CreateUpdateHandler(updaterSettings);
|
||||||
Config.ZoomLevelChanged += Config_ZoomLevelChanged;
|
|
||||||
|
|
||||||
this.updates = new UpdateHandler(browser, updaterSettings);
|
|
||||||
this.updates.UpdateAccepted += updates_UpdateAccepted;
|
this.updates.UpdateAccepted += updates_UpdateAccepted;
|
||||||
this.updates.UpdateDismissed += updates_UpdateDismissed;
|
this.updates.UpdateDismissed += updates_UpdateDismissed;
|
||||||
|
|
||||||
@ -156,81 +117,11 @@ private void RestoreWindow(){
|
|||||||
isLoaded = true;
|
isLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnBrowserReady(){
|
|
||||||
if (!isBrowserReady){
|
|
||||||
browser.Location = Point.Empty;
|
|
||||||
browser.Dock = DockStyle.Fill;
|
|
||||||
isBrowserReady = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateTrayIcon(){
|
private void UpdateTrayIcon(){
|
||||||
trayIcon.Visible = Config.TrayBehavior.ShouldDisplayIcon();
|
trayIcon.Visible = Config.TrayBehavior.ShouldDisplayIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
// active event handlers
|
// event handlers
|
||||||
|
|
||||||
private void browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e){
|
|
||||||
if (!e.IsLoading){
|
|
||||||
foreach(string word in TwitterUtils.DictionaryWords){
|
|
||||||
browser.AddWordToDictionary(word);
|
|
||||||
}
|
|
||||||
|
|
||||||
BeginInvoke(new Action(OnBrowserReady));
|
|
||||||
browser.LoadingStateChanged -= browser_LoadingStateChanged;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void browser_FrameLoadStart(object sender, FrameLoadStartEventArgs e){
|
|
||||||
if (e.Frame.IsMain){
|
|
||||||
memoryUsageTracker.Stop();
|
|
||||||
|
|
||||||
if (Config.ZoomLevel != 100){
|
|
||||||
BrowserUtils.SetZoomLevel(browser.GetBrowser(), Config.ZoomLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TwitterUtils.IsTwitterWebsite(e.Frame)){
|
|
||||||
ScriptLoader.ExecuteFile(e.Frame, "twitter.js");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
|
|
||||||
if (e.Frame.IsMain && TwitterUtils.IsTweetDeckWebsite(e.Frame)){
|
|
||||||
e.Frame.ExecuteJavaScriptAsync(TwitterUtils.BackgroundColorFix);
|
|
||||||
|
|
||||||
UpdateProperties(PropertyBridge.Environment.Browser);
|
|
||||||
TweetDeckBridge.RestoreSessionData(e.Frame);
|
|
||||||
ScriptLoader.ExecuteFile(e.Frame, "code.js");
|
|
||||||
InjectBrowserCSS();
|
|
||||||
ReinjectCustomCSS(Config.CustomBrowserCSS);
|
|
||||||
plugins.ExecutePlugins(e.Frame, PluginEnvironment.Browser);
|
|
||||||
|
|
||||||
TweetDeckBridge.ResetStaticProperties();
|
|
||||||
|
|
||||||
if (Program.SystemConfig.EnableBrowserGCReload){
|
|
||||||
memoryUsageTracker.Start(this, e.Browser, Program.SystemConfig.BrowserMemoryThreshold);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Config.FirstRun){
|
|
||||||
ScriptLoader.ExecuteFile(e.Frame, "introduction.js");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void browser_LoadError(object sender, LoadErrorEventArgs e){
|
|
||||||
if (e.ErrorCode == CefErrorCode.Aborted){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!e.FailedUrl.StartsWith("http://td/", StringComparison.Ordinal)){
|
|
||||||
string errorPage = ScriptLoader.LoadResource("pages/error.html", true);
|
|
||||||
|
|
||||||
if (errorPage != null){
|
|
||||||
browser.LoadHtml(errorPage.Replace("{err}", BrowserUtils.GetErrorName(e.ErrorCode)), "http://td/error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void timerResize_Tick(object sender, EventArgs e){
|
private void timerResize_Tick(object sender, EventArgs e){
|
||||||
FormBrowser_ResizeEnd(this, e); // also stops timer
|
FormBrowser_ResizeEnd(this, e); // also stops timer
|
||||||
@ -300,14 +191,6 @@ private void FormBrowser_FormClosed(object sender, FormClosedEventArgs e){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Config_MuteToggled(object sender, EventArgs e){
|
|
||||||
UpdateProperties(PropertyBridge.Environment.Browser);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Config_ZoomLevelChanged(object sender, EventArgs e){
|
|
||||||
BrowserUtils.SetZoomLevel(browser.GetBrowser(), Config.ZoomLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Config_TrayBehaviorChanged(object sender, EventArgs e){
|
private void Config_TrayBehaviorChanged(object sender, EventArgs e){
|
||||||
UpdateTrayIcon();
|
UpdateTrayIcon();
|
||||||
}
|
}
|
||||||
@ -339,10 +222,6 @@ private static void plugins_Executed(object sender, PluginErrorEventArgs e){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void plugins_PluginChangedState(object sender, PluginChangedStateEventArgs e){
|
|
||||||
browser.ExecuteScriptAsync("window.TDPF_setPluginState", e.Plugin, e.IsEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updates_UpdateAccepted(object sender, UpdateEventArgs e){
|
private void updates_UpdateAccepted(object sender, UpdateEventArgs e){
|
||||||
this.InvokeAsyncSafe(() => {
|
this.InvokeAsyncSafe(() => {
|
||||||
FormManager.CloseAllDialogs();
|
FormManager.CloseAllDialogs();
|
||||||
@ -400,12 +279,12 @@ protected override void WndProc(ref Message m){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBrowserReady && m.Msg == NativeMethods.WM_PARENTNOTIFY && (m.WParam.ToInt32() & 0xFFFF) == NativeMethods.WM_XBUTTONDOWN){
|
if (browser.Ready && m.Msg == NativeMethods.WM_PARENTNOTIFY && (m.WParam.ToInt32() & 0xFFFF) == NativeMethods.WM_XBUTTONDOWN){
|
||||||
if (videoPlayer != null && videoPlayer.Running){
|
if (videoPlayer != null && videoPlayer.Running){
|
||||||
videoPlayer.Close();
|
videoPlayer.Close();
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
browser.ExecuteScriptAsync("TDGF_onMouseClickExtra", (m.WParam.ToInt32() >> 16) & 0xFFFF);
|
browser.OnMouseClickExtra(m.WParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -428,22 +307,18 @@ public void ResumeNotification(){
|
|||||||
notification.ResumeNotification();
|
notification.ResumeNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
// javascript calls
|
// browser bridge methods
|
||||||
|
|
||||||
public void InjectBrowserCSS(){
|
|
||||||
browser.ExecuteScriptAsync("TDGF_injectBrowserCSS", ScriptLoader.LoadResource("styles/browser.css").TrimEnd());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ReinjectCustomCSS(string css){
|
public void ReinjectCustomCSS(string css){
|
||||||
browser.ExecuteScriptAsync("TDGF_reinjectCustomCSS", css?.Replace(Environment.NewLine, " ") ?? string.Empty);
|
browser.ReinjectCustomCSS(css);
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateProperties(PropertyBridge.Environment environment){
|
|
||||||
browser.ExecuteScriptAsync(PropertyBridge.GenerateScript(environment));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReloadToTweetDeck(){
|
public void ReloadToTweetDeck(){
|
||||||
browser.ExecuteScriptAsync($"if(window.TDGF_reload)window.TDGF_reload();else window.location.href='{TwitterUtils.TweetDeckURL}'");
|
browser.ReloadToTweetDeck();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TriggerTweetScreenshot(){
|
||||||
|
browser.TriggerTweetScreenshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
// callback handlers
|
// callback handlers
|
||||||
@ -486,19 +361,14 @@ public void OpenSettings(Type startTab){
|
|||||||
trayIcon.HasNotifications = false;
|
trayIcon.HasNotifications = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Program.SystemConfig.EnableBrowserGCReload){
|
browser.RefreshMemoryTracker();
|
||||||
memoryUsageTracker.Start(this, browser.GetBrowser(), Program.SystemConfig.BrowserMemoryThreshold);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
memoryUsageTracker.Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (form.ShouldReloadBrowser){
|
if (form.ShouldReloadBrowser){
|
||||||
FormManager.TryFind<FormPlugins>()?.Close();
|
FormManager.TryFind<FormPlugins>()?.Close();
|
||||||
plugins.Reload(); // also reloads the browser
|
plugins.Reload(); // also reloads the browser
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
UpdateProperties(PropertyBridge.Environment.Browser);
|
browser.UpdateProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
notification.RequiresResize = true;
|
notification.RequiresResize = true;
|
||||||
@ -551,18 +421,13 @@ public void PlayVideo(string url, string username){
|
|||||||
videoPlayer = new VideoPlayer(this);
|
videoPlayer = new VideoPlayer(this);
|
||||||
|
|
||||||
videoPlayer.ProcessExited += (sender, args) => {
|
videoPlayer.ProcessExited += (sender, args) => {
|
||||||
browser.GetBrowser().GetHost().SendFocusEvent(true);
|
browser.HideVideoOverlay(true);
|
||||||
HideVideoOverlay();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
videoPlayer.Launch(url, username);
|
videoPlayer.Launch(url, username);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HideVideoOverlay(){
|
|
||||||
browser.ExecuteScriptAsync("$('#td-video-player-overlay').remove()");
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ProcessBrowserKey(Keys key){
|
public bool ProcessBrowserKey(Keys key){
|
||||||
if (videoPlayer != null && videoPlayer.Running){
|
if (videoPlayer != null && videoPlayer.Running){
|
||||||
videoPlayer.SendKeyEvent(key);
|
videoPlayer.SendKeyEvent(key);
|
||||||
@ -575,15 +440,13 @@ public bool ProcessBrowserKey(Keys key){
|
|||||||
public void ShowTweetDetail(string columnId, string chirpId, string fallbackUrl){
|
public void ShowTweetDetail(string columnId, string chirpId, string fallbackUrl){
|
||||||
Activate();
|
Activate();
|
||||||
|
|
||||||
using(IFrame frame = browser.GetBrowser().MainFrame){
|
if (!browser.IsTweetDeckWebsite){
|
||||||
if (!TwitterUtils.IsTweetDeckWebsite(frame)){
|
|
||||||
FormMessage.Error("View Tweet Detail", "TweetDeck is not currently loaded.", FormMessage.OK);
|
FormMessage.Error("View Tweet Detail", "TweetDeck is not currently loaded.", FormMessage.OK);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
notification.FinishCurrentNotification();
|
notification.FinishCurrentNotification();
|
||||||
browser.ExecuteScriptAsync("window.TDGF_showTweetDetail", columnId, chirpId, fallbackUrl);
|
browser.ShowTweetDetail(columnId, chirpId, fallbackUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnTweetScreenshotReady(string html, int width, int height){
|
public void OnTweetScreenshotReady(string html, int width, int height){
|
||||||
@ -604,9 +467,5 @@ public void DisplayTooltip(string text){
|
|||||||
toolTip.Show(text, this, position);
|
toolTip.Show(text, this, position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TriggerTweetScreenshot(){
|
|
||||||
browser.ExecuteScriptAsync("TDGF_triggerScreenshot()");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
using System.Timers;
|
using System.Timers;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using CefSharp;
|
using CefSharp;
|
||||||
|
using CefSharp.WinForms;
|
||||||
using Timer = System.Timers.Timer;
|
using Timer = System.Timers.Timer;
|
||||||
|
|
||||||
namespace TweetDuck.Core.Other.Management{
|
namespace TweetDuck.Core.Other.Management{
|
||||||
@ -25,11 +26,11 @@ public MemoryUsageTracker(string cleanupFunctionName){
|
|||||||
this.timer.Elapsed += timer_Elapsed;
|
this.timer.Elapsed += timer_Elapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start(Form owner, IBrowser browser, int thresholdMB){
|
public void Start(ChromiumWebBrowser control, int thresholdMB){
|
||||||
Stop();
|
Stop();
|
||||||
|
|
||||||
this.owner = owner;
|
this.owner = (Form)control.Parent; // TODO ugly
|
||||||
this.browser = browser;
|
this.browser = control.GetBrowser();
|
||||||
this.threshold = thresholdMB*1024L*1024L;
|
this.threshold = thresholdMB*1024L*1024L;
|
||||||
this.timer.SynchronizingObject = owner;
|
this.timer.SynchronizingObject = owner;
|
||||||
this.timer.Start();
|
this.timer.Start();
|
||||||
|
230
Core/TweetDeckBrowser.cs
Normal file
230
Core/TweetDeckBrowser.cs
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using CefSharp;
|
||||||
|
using CefSharp.WinForms;
|
||||||
|
using TweetDuck.Core.Bridge;
|
||||||
|
using TweetDuck.Core.Controls;
|
||||||
|
using TweetDuck.Core.Handling;
|
||||||
|
using TweetDuck.Core.Handling.General;
|
||||||
|
using TweetDuck.Core.Other.Management;
|
||||||
|
using TweetDuck.Core.Utils;
|
||||||
|
using TweetDuck.Plugins;
|
||||||
|
using TweetDuck.Plugins.Enums;
|
||||||
|
using TweetDuck.Plugins.Events;
|
||||||
|
using TweetDuck.Resources;
|
||||||
|
using TweetDuck.Updates;
|
||||||
|
|
||||||
|
namespace TweetDuck.Core{
|
||||||
|
sealed class TweetDeckBrowser : IDisposable{
|
||||||
|
public bool Ready { get; private set; }
|
||||||
|
|
||||||
|
public bool Enabled{
|
||||||
|
get => browser.Enabled;
|
||||||
|
set => browser.Enabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsTweetDeckWebsite{
|
||||||
|
get{
|
||||||
|
using(IFrame frame = browser.GetBrowser().MainFrame){
|
||||||
|
return TwitterUtils.IsTweetDeckWebsite(frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly ChromiumWebBrowser browser;
|
||||||
|
private readonly PluginManager plugins;
|
||||||
|
private readonly MemoryUsageTracker memoryUsageTracker;
|
||||||
|
|
||||||
|
public TweetDeckBrowser(FormBrowser owner, PluginManager plugins, TweetDeckBridge bridge){
|
||||||
|
this.browser = new ChromiumWebBrowser(TwitterUtils.TweetDeckURL){
|
||||||
|
DialogHandler = new FileDialogHandler(),
|
||||||
|
DragHandler = new DragHandlerBrowser(),
|
||||||
|
MenuHandler = new ContextMenuBrowser(owner),
|
||||||
|
JsDialogHandler = new JavaScriptDialogHandler(),
|
||||||
|
KeyboardHandler = new KeyboardHandlerBrowser(owner),
|
||||||
|
LifeSpanHandler = new LifeSpanHandler(),
|
||||||
|
RequestHandler = new RequestHandlerBrowser()
|
||||||
|
};
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
this.browser.ConsoleMessage += BrowserUtils.HandleConsoleMessage;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
this.browser.LoadingStateChanged += browser_LoadingStateChanged;
|
||||||
|
this.browser.FrameLoadStart += browser_FrameLoadStart;
|
||||||
|
this.browser.FrameLoadEnd += browser_FrameLoadEnd;
|
||||||
|
this.browser.LoadError += browser_LoadError;
|
||||||
|
|
||||||
|
this.browser.RegisterAsyncJsObject("$TD", bridge);
|
||||||
|
this.browser.RegisterAsyncJsObject("$TDP", plugins.Bridge);
|
||||||
|
|
||||||
|
this.browser.BrowserSettings.BackgroundColor = (uint)TwitterUtils.BackgroundColor.ToArgb();
|
||||||
|
this.browser.Dock = DockStyle.None;
|
||||||
|
this.browser.Location = ControlExtensions.InvisibleLocation;
|
||||||
|
|
||||||
|
owner.Controls.Add(browser);
|
||||||
|
|
||||||
|
this.plugins = plugins;
|
||||||
|
this.plugins.PluginChangedState += plugins_PluginChangedState;
|
||||||
|
|
||||||
|
this.memoryUsageTracker = new MemoryUsageTracker("TDGF_tryRunCleanup");
|
||||||
|
|
||||||
|
Program.UserConfig.MuteToggled += UserConfig_MuteToggled;
|
||||||
|
Program.UserConfig.ZoomLevelChanged += UserConfig_ZoomLevelChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup and management
|
||||||
|
|
||||||
|
private void OnBrowserReady(){
|
||||||
|
if (!Ready){
|
||||||
|
browser.Location = Point.Empty;
|
||||||
|
browser.Dock = DockStyle.Fill;
|
||||||
|
Ready = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Focus(){
|
||||||
|
browser.Focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose(){
|
||||||
|
plugins.PluginChangedState -= plugins_PluginChangedState;
|
||||||
|
|
||||||
|
Program.UserConfig.MuteToggled -= UserConfig_MuteToggled;
|
||||||
|
Program.UserConfig.ZoomLevelChanged -= UserConfig_ZoomLevelChanged;
|
||||||
|
|
||||||
|
memoryUsageTracker.Dispose();
|
||||||
|
browser.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// event handlers
|
||||||
|
|
||||||
|
private void browser_LoadingStateChanged(object sender, LoadingStateChangedEventArgs e){
|
||||||
|
if (!e.IsLoading){
|
||||||
|
foreach(string word in TwitterUtils.DictionaryWords){
|
||||||
|
browser.AddWordToDictionary(word);
|
||||||
|
}
|
||||||
|
|
||||||
|
browser.BeginInvoke(new Action(OnBrowserReady));
|
||||||
|
browser.LoadingStateChanged -= browser_LoadingStateChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void browser_FrameLoadStart(object sender, FrameLoadStartEventArgs e){
|
||||||
|
if (e.Frame.IsMain){
|
||||||
|
memoryUsageTracker.Stop();
|
||||||
|
|
||||||
|
if (Program.UserConfig.ZoomLevel != 100){
|
||||||
|
BrowserUtils.SetZoomLevel(browser.GetBrowser(), Program.UserConfig.ZoomLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TwitterUtils.IsTwitterWebsite(e.Frame)){
|
||||||
|
ScriptLoader.ExecuteFile(e.Frame, "twitter.js");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
|
||||||
|
if (e.Frame.IsMain && TwitterUtils.IsTweetDeckWebsite(e.Frame)){
|
||||||
|
e.Frame.ExecuteJavaScriptAsync(TwitterUtils.BackgroundColorFix);
|
||||||
|
|
||||||
|
UpdateProperties();
|
||||||
|
TweetDeckBridge.RestoreSessionData(e.Frame);
|
||||||
|
ScriptLoader.ExecuteFile(e.Frame, "code.js");
|
||||||
|
InjectBrowserCSS();
|
||||||
|
ReinjectCustomCSS(Program.UserConfig.CustomBrowserCSS);
|
||||||
|
plugins.ExecutePlugins(e.Frame, PluginEnvironment.Browser);
|
||||||
|
|
||||||
|
TweetDeckBridge.ResetStaticProperties();
|
||||||
|
|
||||||
|
if (Program.SystemConfig.EnableBrowserGCReload){
|
||||||
|
memoryUsageTracker.Start(browser, Program.SystemConfig.BrowserMemoryThreshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Program.UserConfig.FirstRun){
|
||||||
|
ScriptLoader.ExecuteFile(e.Frame, "introduction.js");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void browser_LoadError(object sender, LoadErrorEventArgs e){
|
||||||
|
if (e.ErrorCode == CefErrorCode.Aborted){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!e.FailedUrl.StartsWith("http://td/", StringComparison.Ordinal)){
|
||||||
|
string errorPage = ScriptLoader.LoadResource("pages/error.html", true);
|
||||||
|
|
||||||
|
if (errorPage != null){
|
||||||
|
browser.LoadHtml(errorPage.Replace("{err}", BrowserUtils.GetErrorName(e.ErrorCode)), "http://td/error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void plugins_PluginChangedState(object sender, PluginChangedStateEventArgs e){
|
||||||
|
browser.ExecuteScriptAsync("TDPF_setPluginState", e.Plugin, e.IsEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UserConfig_MuteToggled(object sender, EventArgs e){
|
||||||
|
UpdateProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UserConfig_ZoomLevelChanged(object sender, EventArgs e){
|
||||||
|
BrowserUtils.SetZoomLevel(browser.GetBrowser(), Program.UserConfig.ZoomLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// external handling
|
||||||
|
|
||||||
|
public UpdateHandler CreateUpdateHandler(UpdaterSettings settings){
|
||||||
|
return new UpdateHandler(browser, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RefreshMemoryTracker(){
|
||||||
|
if (Program.SystemConfig.EnableBrowserGCReload){
|
||||||
|
memoryUsageTracker.Start(browser, Program.SystemConfig.BrowserMemoryThreshold);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
memoryUsageTracker.Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HideVideoOverlay(bool focus){
|
||||||
|
if (focus){
|
||||||
|
browser.GetBrowser().GetHost().SendFocusEvent(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
browser.ExecuteScriptAsync("$('#td-video-player-overlay').remove()");
|
||||||
|
}
|
||||||
|
|
||||||
|
// javascript calls
|
||||||
|
|
||||||
|
public void ReloadToTweetDeck(){
|
||||||
|
browser.ExecuteScriptAsync($"if(window.TDGF_reload)window.TDGF_reload();else window.location.href='{TwitterUtils.TweetDeckURL}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateProperties(){
|
||||||
|
browser.ExecuteScriptAsync(PropertyBridge.GenerateScript(PropertyBridge.Environment.Browser));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InjectBrowserCSS(){
|
||||||
|
browser.ExecuteScriptAsync("TDGF_injectBrowserCSS", ScriptLoader.LoadResource("styles/browser.css").TrimEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReinjectCustomCSS(string css){
|
||||||
|
browser.ExecuteScriptAsync("TDGF_reinjectCustomCSS", css?.Replace(Environment.NewLine, " ") ?? string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnMouseClickExtra(IntPtr param){
|
||||||
|
browser.ExecuteScriptAsync("TDGF_onMouseClickExtra", (param.ToInt32() >> 16) & 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowTweetDetail(string columnId, string chirpId, string fallbackUrl){
|
||||||
|
browser.ExecuteScriptAsync("TDGF_showTweetDetail", columnId, chirpId, fallbackUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TriggerTweetScreenshot(){
|
||||||
|
browser.ExecuteScriptAsync("TDGF_triggerScreenshot()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -190,6 +190,7 @@
|
|||||||
<Compile Include="Core\Other\Settings\TabSettingsTray.Designer.cs">
|
<Compile Include="Core\Other\Settings\TabSettingsTray.Designer.cs">
|
||||||
<DependentUpon>TabSettingsTray.cs</DependentUpon>
|
<DependentUpon>TabSettingsTray.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Core\TweetDeckBrowser.cs" />
|
||||||
<Compile Include="Core\Utils\StringUtils.cs" />
|
<Compile Include="Core\Utils\StringUtils.cs" />
|
||||||
<Compile Include="Core\Utils\TwitterUtils.cs" />
|
<Compile Include="Core\Utils\TwitterUtils.cs" />
|
||||||
<Compile Include="Data\CombinedFileStream.cs" />
|
<Compile Include="Data\CombinedFileStream.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user