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:
parent
dda954285c
commit
8e1f87e062
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
45
Resources/Content/bootstrap.js
vendored
45
Resources/Content/bootstrap.js
vendored
@ -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).`);
|
||||
});
|
@ -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
50
Resources/Content/load.js
Normal 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
18
Resources/Scripts/bootstrap.js
vendored
Normal 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);
|
||||
})();
|
67
Resources/Scripts/bootstrap.tweetdeck.js
vendored
67
Resources/Scripts/bootstrap.tweetdeck.js
vendored
@ -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);
|
||||
})();
|
@ -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;
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user