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

Expand module bootstrapping mechanism

This commit is contained in:
chylex 2021-12-22 05:17:45 +01:00
parent dda954285c
commit 8e1f87e062
Signed by: chylex
GPG Key ID: 4DE42C8F19A80548
12 changed files with 106 additions and 126 deletions

View File

@ -1,4 +1,5 @@
using System.IO;
using System.Linq;
using CefSharp;
using TweetDuck.Utils;
using TweetLib.Core.Browser;
@ -38,5 +39,21 @@ public static bool RunFile(IFrame frame, string file) {
RunScript(frame, script, "root:" + Path.GetFileNameWithoutExtension(file));
return script != null;
}
public static void RunBootstrap(IFrame frame, string moduleNamespace, string stylesheetName) {
string script = Program.Resources.Load("bootstrap.js");
if (script == null) {
return;
}
string path = Path.Combine(Program.ResourcesPath, moduleNamespace);
string[] moduleNames = new DirectoryInfo(path).GetFiles().Select(o => Path.GetFileNameWithoutExtension(o.Name)).ToArray();
script = script.Replace("{namespace}", moduleNamespace);
script = script.Replace("{modules}", string.Join("|", moduleNames));
script = script.Replace("{stylesheet}", stylesheetName);
RunScript(frame, script, "bootstrap");
}
}
}

View File

@ -33,8 +33,8 @@ private TweetDeckBridge(FormBrowser form, FormNotificationMain notification) {
public sealed class Browser : TweetDeckBridge {
public Browser(FormBrowser form, FormNotificationMain notification) : base(form, notification) {}
public void OnFeaturesLoaded() {
form.InvokeAsyncSafe(form.OnFeaturesLoaded);
public void OnModulesLoaded(string moduleNamespace) {
form.InvokeAsyncSafe(() => form.OnModulesLoaded(moduleNamespace));
}
public void OpenContextMenu() {

View File

@ -368,8 +368,8 @@ protected override void WndProc(ref Message m) {
// bridge methods
public void OnFeaturesLoaded() {
browser.OnFeaturesLoaded();
public void OnModulesLoaded(string moduleNamespace) {
browser.OnModulesLoaded(moduleNamespace);
}
public void PauseNotification() {

View File

@ -24,6 +24,7 @@ sealed class TweetDeckBrowser : IDisposable {
private static UserConfig Config => Program.Config.User;
private const string ErrorUrl = "http://td/error";
private const string NamespaceFeatures = "features";
public bool Ready { get; private set; }
@ -152,7 +153,7 @@ private void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e) {
if (frame.IsMain) {
if (TwitterUrls.IsTweetDeck(url)) {
UpdateProperties();
CefScriptExecutor.RunFile(frame, "bootstrap.tweetdeck.js");
CefScriptExecutor.RunBootstrap(frame, NamespaceFeatures, "tweetdeck.css");
TweetDeckBridge.ResetStaticProperties();
@ -231,9 +232,11 @@ public void ReloadToTweetDeck() {
browser.ExecuteJsAsync($"if(window.TDGF_reload)window.TDGF_reload();else window.location.href='{TwitterUrls.TweetDeck}'");
}
public void OnFeaturesLoaded() {
ReinjectCustomCSS(Config.CustomBrowserCSS);
Config_SoundNotificationInfoChanged(null, EventArgs.Empty);
public void OnModulesLoaded(string moduleNamespace) {
if (moduleNamespace == NamespaceFeatures) {
ReinjectCustomCSS(Config.CustomBrowserCSS);
Config_SoundNotificationInfoChanged(null, EventArgs.Empty);
}
}
public void UpdateProperties() {

View File

@ -14,7 +14,7 @@ if (!("$TDX" in window)) {
* @property {function(tooltip: string|null)} displayTooltip
* @property {function} fixClipboard
* @property {function(fontSize: string, headLayout: string)} loadNotificationLayout
* @property {function} onFeaturesLoaded
* @property {function(namespace: string)} onModulesLoaded
* @property {function(columnId: string, chirpId: string, columnName: string, tweetHtml: string, tweetCharacters: int, tweetUrl: string, quoteUrl: string)} onTweetPopup
* @property {function} onTweetSound
* @property {function(url: string)} openBrowser

View File

@ -1,45 +0,0 @@
async function loadModule(path) {
let module;
try {
module = await import(path);
} catch (e) {
console.error(`[TweetDuck] Error loading '${path}': ${e}`);
return false;
}
try {
module.default();
console.info(`[TweetDuck] Successfully loaded '${path}'`);
return true;
} catch (e) {
console.error(`[TweetDuck] Error executing '${path}': ${e}`);
}
return false;
}
async function loadFeatures() {
const script = document.getElementById("tweetduck-bootstrap");
const features = script.getAttribute("data-features").split("|");
let successes = 0;
for (const feature of features) {
if (await loadModule(`./features/${feature}.js`)) {
++successes;
}
}
return [ successes, features.length ];
}
loadFeatures().then(([ successes, total ]) => {
if ("$TD" in window) {
window.$TD.onFeaturesLoaded();
}
if ("TD_PLUGINS" in window) {
window.TD_PLUGINS.onFeaturesLoaded();
}
console.info(`[TweetDuck] Successfully loaded ${successes} / ${total} feature(s).`);
});

View File

@ -8,6 +8,7 @@ import { reloadColumns } from "../globals/reload_columns.js";
import { showTweetDetail } from "../globals/show_tweet_detail.js";
export default function() {
window.jQuery = window.$;
window.TDGF_applyROT13 = applyROT13;
window.TDGF_getColumnName = getColumnName;
window.TDGF_injectMustache = injectMustache;

50
Resources/Content/load.js Normal file
View File

@ -0,0 +1,50 @@
(function() {
const script = document.currentScript;
const namespace = script.getAttribute("data-namespace");
const tag = `[TweetDuck:${namespace}]`;
async function loadModule(path) {
let module;
try {
module = await import(path);
} catch (e) {
console.error(`${tag} Error loading '${path}': ${e}`);
return false;
}
try {
module.default();
console.info(`${tag} Successfully loaded '${path}'`);
return true;
} catch (e) {
console.error(`${tag} Error executing '${path}': ${e}`);
}
return false;
}
async function loadModules() {
const modules = script.getAttribute("data-modules").split("|");
let successes = 0;
for (const feature of modules) {
if (await loadModule(`./${namespace}/${feature}.js`)) {
++successes;
}
}
return [ successes, modules.length ];
}
loadModules().then(([ successes, total ]) => {
if ("$TD" in window) {
window.$TD.onModulesLoaded(namespace);
}
if ("TD_PLUGINS" in window) {
window.TD_PLUGINS.onModulesLoaded(namespace);
}
console.info(`${tag} Successfully loaded ${successes} / ${total} module(s).`);
});
})();

18
Resources/Scripts/bootstrap.js vendored Normal file
View File

@ -0,0 +1,18 @@
(function() {
document.documentElement.id = "tduck";
const script = document.createElement("script");
script.async = false;
script.type = "text/javascript";
script.id = "tweetduck-bootstrap-{namespace}";
script.src = "td://resources/load.js";
script.setAttribute("data-namespace", "{namespace}");
script.setAttribute("data-modules", "{modules}");
document.head.appendChild(script);
const style = document.createElement("link");
style.id = "tweetduck-styles-{namespace}";
style.rel = "stylesheet";
style.href = "td://resources/styles/{stylesheet}";
document.head.appendChild(style);
})();

View File

@ -1,67 +0,0 @@
(function() {
const features = [
"add_tweetduck_to_settings_menu",
"bypass_t.co_links",
"clear_search_input",
"configure_first_day_of_week",
"configure_language_for_translations",
"disable_clipboard_formatting",
"disable_td_metrics",
"drag_links_onto_columns",
"expand_links_or_show_tooltip",
"fix_dm_input_box_focus",
"fix_horizontal_scrolling_of_column_container",
"fix_marking_dm_as_read_when_replying",
"fix_media_preview_urls",
"fix_missing_bing_translator_languages",
"fix_os_name",
"fix_scheduled_tweets_not_appearing",
"fix_youtube_previews",
"focus_composer_after_alt_tab",
"focus_composer_after_image_upload",
"focus_composer_after_switching_account",
"handle_extra_mouse_buttons",
"hook_theme_settings",
"inject_css",
"keep_like_follow_dialogs_open",
"limit_loaded_dm_count",
"make_retweets_lowercase",
"middle_click_tweet_icon_actions",
"move_accounts_above_hashtags_in_search",
"offline_notification",
"open_search_externally",
"open_search_in_first_column",
"paste_images_from_clipboard",
"perform_search",
"pin_composer_icon",
"ready_plugins",
"register_composer_active_event",
"register_global_functions",
"restore_cleared_column",
"screenshot_tweet",
"setup_column_type_attributes",
"setup_desktop_notifications",
"setup_link_context_menu",
"setup_sound_notifications",
"setup_tweet_context_menu",
"setup_tweetduck_account_bamboozle",
"setup_video_player",
"skip_pre_login_page",
];
document.documentElement.id = "tduck";
window.jQuery = window.$;
const script = document.createElement("script");
script.id = "tweetduck-bootstrap";
script.type = "text/javascript";
script.async = false;
script.src = "td://resources/bootstrap.js";
script.setAttribute("data-features", features.join("|"));
document.head.appendChild(script);
const style = document.createElement("link");
style.rel = "stylesheet";
style.href = "td://resources/styles/tweetdeck.css";
document.head.appendChild(style);
})();

View File

@ -40,12 +40,12 @@
}
if (!this.isDisabled(plugin)){
this.runWhenFeaturesLoaded(plugin);
this.runWhenModulesLoaded(plugin);
this.runWhenReady(plugin);
}
}
runWhenFeaturesLoaded(plugin){
runWhenModulesLoaded(plugin){
if (this.areFeaturesLoaded){
plugin.obj.enabled();
}
@ -93,7 +93,10 @@
}
}
onFeaturesLoaded(){
onModulesLoaded(namespace){
if (namespace !== "features") {
return;
}
window.TDPF_getColumnName = window.TDGF_getColumnName;
window.TDPF_reloadColumns = window.TDGF_reloadColumns;
window.TDPF_prioritizeNewestEvent = window.TDGF_prioritizeNewestEvent;

View File

@ -400,7 +400,7 @@
<Content Include="Resources\Content\api\jquery.js" />
<Content Include="Resources\Content\api\td.js" />
<Content Include="Resources\Content\api\utils.js" />
<Content Include="Resources\Content\bootstrap.js" />
<Content Include="Resources\Content\load.js" />
<Content Include="Resources\Content\features\perform_search.js" />
<Content Include="Resources\Content\features\screenshot_tweet.js" />
<Content Include="Resources\Content\features\bypass_t.co_links.js" />
@ -459,7 +459,7 @@
<Content Include="Resources\Content\globals\prioritize_newest_event.js" />
<Content Include="Resources\Content\globals\reload_columns.js" />
<Content Include="Resources\Content\globals\show_tweet_detail.js" />
<Content Include="Resources\Scripts\bootstrap.tweetdeck.js" />
<Content Include="Resources\Scripts\bootstrap.js" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>