1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-05-09 05:34:05 +02:00

Rewrite plugins.js, plugin state handling and script execution (separate instead of combining)

This commit is contained in:
chylex 2016-06-30 16:31:02 +02:00
parent dc78c68f12
commit b6a683dfe1
5 changed files with 101 additions and 105 deletions

View File

@ -122,8 +122,9 @@ private void Browser_LoadingStateChanged(object sender, LoadingStateChangedEvent
private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
if (e.Frame.IsMain){
ScriptLoader.ExecuteFile(browser,"code.js");
plugins_Reloaded(plugins,new PluginLoadEventArgs(new string[0]));
ScriptLoader.ExecuteFile(e.Frame,"code.js");
ScriptLoader.ExecuteFile(e.Frame,PluginManager.PluginScriptFile);
plugins.ExecutePlugins(e.Frame,PluginEnvironment.Browser);
}
}
@ -191,11 +192,11 @@ private void trayIcon_ClickClose(object sender, EventArgs e){
}
private void plugins_Reloaded(object sender, PluginLoadEventArgs e){
browser.ExecuteScriptAsync(plugins.GenerateScript(PluginEnvironment.Browser));
browser.ExecuteScriptAsync("window.location.reload()");
}
private void plugins_PluginChangedState(object sender, PluginChangedStateEventArgs e){
ScriptLoader.ExecuteScript(browser,PluginScriptGenerator.GenerateSetPluginState(e.Plugin,e.IsEnabled),"gen:pluginstate:"+e.Plugin);
browser.ExecuteScriptAsync("window.TDPF_setPluginState",e.Plugin,e.IsEnabled ? 1 : 0); // ExecuteScriptAsync cannot handle boolean values as of yet
}
private void updates_UpdateAccepted(object sender, UpdateAcceptedEventArgs e){

View File

@ -115,7 +115,8 @@ private void Config_MuteToggled(object sender, EventArgs e){
private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
if (e.Frame.IsMain && notificationJS != null && browser.Address != "about:blank"){
ScriptLoader.ExecuteScript(e.Frame,notificationJS,"root:notification");
browser.ExecuteScriptAsync(plugins.GenerateScript(PluginEnvironment.Notification));
ScriptLoader.ExecuteFile(e.Frame,PluginManager.PluginScriptFile);
plugins.ExecutePlugins(e.Frame,PluginEnvironment.Notification);
}
}

View File

@ -2,12 +2,14 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using CefSharp;
using TweetDck.Plugins.Events;
using TweetDck.Resources;
namespace TweetDck.Plugins{
class PluginManager{
public const string PluginScriptFile = "plugins.js";
public string PathOfficialPlugins { get { return Path.Combine(rootPath,"official"); } }
public string PathCustomPlugins { get { return Path.Combine(rootPath,"user"); } }
@ -53,29 +55,24 @@ public void Reload(){
}
}
public string GenerateScript(PluginEnvironment environment){
string mainScript = ScriptLoader.LoadResource("plugins.js");
if (mainScript == null)return string.Empty;
StringBuilder build = new StringBuilder((1+plugins.Count)*512);
PluginScriptGenerator.AppendStart(build,environment);
build.Append(mainScript);
PluginScriptGenerator.AppendConfig(build,Config);
public void ExecutePlugins(IFrame frame, PluginEnvironment environment){
ScriptLoader.ExecuteScript(frame,PluginScriptGenerator.GenerateConfig(Config),"gen:pluginconfig");
foreach(Plugin plugin in Plugins){
string path = plugin.GetScriptPath(environment);
if (string.IsNullOrEmpty(path) || !plugin.CanRun)continue;
string script;
try{
PluginScriptGenerator.AppendPlugin(build,plugin.Identifier,File.ReadAllText(path));
script = File.ReadAllText(path);
}catch{
// TODO
continue;
}
ScriptLoader.ExecuteScript(frame,PluginScriptGenerator.GeneratePlugin(plugin.Identifier,script,environment),"plugin:"+plugin);
}
PluginScriptGenerator.AppendEnd(build,environment);
return build.ToString();
}
private IEnumerable<Plugin> LoadPluginsFrom(string path, PluginGroup group){

View File

@ -2,30 +2,23 @@
namespace TweetDck.Plugins{
static class PluginScriptGenerator{
public static void AppendStart(StringBuilder build, PluginEnvironment environment){
public static string GenerateConfig(PluginConfig config){
return config.AnyDisabled ? "window.TD_PLUGINS.disabled = [\""+string.Join("\",\"",config.DisabledPlugins)+"\"];" : string.Empty;
}
public static string GeneratePlugin(string pluginIdentifier, string pluginContents, PluginEnvironment environment){
StringBuilder build = new StringBuilder(pluginIdentifier.Length+pluginContents.Length+110);
build.Append("(function(").Append(environment.GetScriptVariables()).Append("){");
}
public static void AppendConfig(StringBuilder build, PluginConfig config){
if (config.AnyDisabled){
build.Append("PLUGINS.disabled = [\"").Append(string.Join("\",\"",config.DisabledPlugins)).Append("\"];");
}
}
public static void AppendPlugin(StringBuilder build, string pluginIdentifier, string pluginContents){
build.Append("PLUGINS.installed.push({");
build.Append("id: \"").Append(pluginIdentifier).Append("\",");
build.Append("obj: new class extends PluginBase{ ").Append(pluginContents).Append(" }");
build.Append("window.TD_PLUGINS.install({");
build.Append("id:\"").Append(pluginIdentifier).Append("\",");
build.Append("obj:new class extends PluginBase{").Append(pluginContents).Append("}");
build.Append("});");
}
public static void AppendEnd(StringBuilder build, PluginEnvironment environment){
build.Append("PLUGINS.load();");
build.Append("})(").Append(environment.GetScriptVariables()).Append(");");
}
public static string GenerateSetPluginState(Plugin plugin, bool enabled){
return new StringBuilder().Append("window.TD_PLUGINS.setState(\"").Append(plugin.Identifier).Append("\",").Append(enabled ? "true" : "false").Append(");").ToString();
return build.ToString();
}
}
}

View File

@ -1,76 +1,80 @@
var isReloading = "TD_PLUGINS" in window;
if (isReloading){
window.TD_PLUGINS.installed.forEach(plugin => {
if (!window.TD_PLUGINS.isDisabled(plugin)){
plugin.obj.disabled();
(function(){
//
// Class: Abstract plugin base class.
//
window.PluginBase = class{
constructor(pluginSettings){
this.$pluginSettings = pluginSettings || {};
}
});
}
class PluginBase{
constructor(pluginSettings){
this.$pluginSettings = pluginSettings || {};
}
enabled(){}
ready(){}
disabled(){}
}
var PLUGINS = {
installed: [],
disabled: [],
waiting: [],
isDisabled: plugin => PLUGINS.disabled.includes(plugin.id),
findObject: identifier => PLUGINS.installed.find(plugin => plugin.id === identifier),
load: function(){
PLUGINS.installed.forEach(plugin => {
if (!PLUGINS.isDisabled(plugin)){
enabled(){}
ready(){}
disabled(){}
};
//
// Variable: Main object for containing and managing plugins.
//
window.TD_PLUGINS = new class{
constructor(){
this.installed = [];
this.disabled = [];
this.waiting = [];
}
isDisabled(plugin){
return this.disabled.includes(plugin.id);
}
findObject(identifier){
return this.installed.find(plugin => plugin.id === identifier);
}
install(plugin){
this.installed.push(plugin);
if (!this.isDisabled(plugin)){
plugin.obj.enabled();
PLUGINS.runWhenReady(plugin);
this.runWhenReady(plugin);
}
});
},
onReady: function(){
PLUGINS.waiting.forEach(plugin => plugin.obj.ready());
PLUGINS.waiting = [];
},
runWhenReady: function(plugin){
if (window.TD_APP_READY){
plugin.obj.ready();
}
else{
PLUGINS.waiting.push(plugin);
runWhenReady(plugin){
if (window.TD_APP_READY){
plugin.obj.ready();
}
else{
this.waiting.push(plugin);
}
}
},
setState(plugin, enable){
if (enable && this.isDisabled(plugin)){
this.disabled.splice(this.disabled.indexOf(plugin.id),1);
plugin.obj.enabled();
this.runWhenReady(plugin);
}
else if (!enable && !this.isDisabled(plugin)){
this.disabled.push(plugin.id);
plugin.obj.disabled();
}
else return;
setState: function(identifier, enable){
var plugin = PLUGINS.findObject(identifier);
if (enable && PLUGINS.isDisabled(plugin)){
PLUGINS.disabled.splice(PLUGINS.disabled.indexOf(identifier),1);
plugin.obj.enabled();
PLUGINS.runWhenReady(plugin);
if (plugin.obj.$pluginSettings.requiresPageReload){
window.location.reload();
}
}
else if (!enable && !PLUGINS.isDisabled(plugin)){
PLUGINS.disabled.push(identifier);
plugin.obj.disabled();
onReady(){
this.waiting.forEach(plugin => plugin.obj.ready());
this.waiting = [];
}
else return;
if (plugin.obj.$pluginSettings.requiresPageReload){
window.location.reload();
}
}
};
window.TD_PLUGINS = PLUGINS;
if (isReloading){
window.location.reload();
}
};
//
// Block: Setup global function to change plugin state.
//
window.TDPF_setPluginState = function(identifier, enable){
window.TD_PLUGINS.setState(window.TD_PLUGINS.findObject(identifier),enable);
};
})();