1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-02-24 15:00:03 +00:00

Basic loading of bundled subplugins

Very basic. Doesn't cope with any changes to the plugins after startup, and doesn't remove sub-plugins when the parent plugin is removed.
This commit is contained in:
Jeremy Ruston 2025-02-18 09:14:54 +00:00
parent c142bfc50d
commit 6b0a13b8cc

View File

@ -1170,7 +1170,7 @@ $tw.Wiki = function(options) {
} }
return tiddlerTitles; return tiddlerTitles;
}, },
pluginTiddlers = [], // Array of tiddlers containing registered plugins, ordered by priority pluginTiddlersInfo = [], // Array of {tiddler:<tiddler object>,parentPluginTitle:<title>} for all plugins and sub-plugins, ordered by priority
pluginContents = Object.create(null), // Hashmap of parsed plugin content pluginContents = Object.create(null), // Hashmap of parsed plugin content
shadowTiddlerInfo = Object.create(null), // Hashmap by title of {source:, tiddler:} shadowTiddlerInfo = Object.create(null), // Hashmap by title of {source:, tiddler:}
shadowTiddlerTitles = null, // Array of tiddler titles, calculated and cached when needed shadowTiddlerTitles = null, // Array of tiddler titles, calculated and cached when needed
@ -1389,8 +1389,8 @@ $tw.Wiki = function(options) {
// Get an array of all the currently recognised plugin types // Get an array of all the currently recognised plugin types
this.getPluginTypes = function() { this.getPluginTypes = function() {
var types = []; var types = [];
$tw.utils.each(pluginTiddlers,function(pluginTiddler) { $tw.utils.each(pluginTiddlersInfo,function(pluginTiddlerInfo) {
var pluginType = pluginTiddler.fields["plugin-type"]; var pluginType = pluginTiddlerInfo.tiddler.fields["plugin-type"];
if(pluginType && types.indexOf(pluginType) === -1) { if(pluginType && types.indexOf(pluginType) === -1) {
types.push(pluginType); types.push(pluginType);
} }
@ -1430,20 +1430,10 @@ $tw.Wiki = function(options) {
// Register the plugin tiddlers of a particular type, or null/undefined for any type, optionally restricting registration to an array of tiddler titles. Return the array of titles affected // Register the plugin tiddlers of a particular type, or null/undefined for any type, optionally restricting registration to an array of tiddler titles. Return the array of titles affected
this.registerPluginTiddlers = function(pluginType,titles) { this.registerPluginTiddlers = function(pluginType,titles) {
var self = this, var self = this,
registeredTitles = [], registeredTitles = [];
checkTiddler = function(tiddler,title) {
if(tiddler && tiddler.fields.type === "application/json" && tiddler.fields["plugin-type"] && (!pluginType || tiddler.fields["plugin-type"] === pluginType)) {
var disablingTiddler = self.getTiddler("$:/config/Plugins/Disabled/" + title);
if(title === "$:/core" || !disablingTiddler || (disablingTiddler.fields.text || "").trim() !== "yes") {
self.unregisterPluginTiddlers(null,[title]); // Unregister the plugin if it's already registered
pluginTiddlers.push(tiddler);
registeredTitles.push(tiddler.fields.title);
}
}
};
if(titles) { if(titles) {
$tw.utils.each(titles,function(title) { $tw.utils.each(titles,function(title) {
checkTiddler(self.getTiddler(title),title); checkTiddler(null,title);
}); });
} else { } else {
this.each(function(tiddler,title) { this.each(function(tiddler,title) {
@ -1451,6 +1441,38 @@ $tw.Wiki = function(options) {
}); });
} }
return registeredTitles; return registeredTitles;
function checkTiddler(tiddler,title) {
if(!tiddler) {
tiddler = self.getTiddler(title);
}
if(tiddler && tiddler.fields.type === "application/json" && tiddler.fields["plugin-type"] && (!pluginType || tiddler.fields["plugin-type"] === pluginType)) {
var disablingTiddler = self.getTiddler("$:/config/Plugins/Disabled/" + title);
if(title === "$:/core" || !disablingTiddler || (disablingTiddler.fields.text || "").trim() !== "yes") {
self.unregisterPluginTiddlers(null,[title]); // Unregister the plugin if it's already registered
pluginTiddlersInfo.push({tiddler: tiddler});
registeredTitles.push(tiddler.fields.title);
// Register any sub-plugins
var contents = pluginContents[tiddler.fields.title];
if(contents) {
$tw.utils.each(contents.tiddlers,function(subPluginFields,subPluginTitle) {
checkSubTiddler(title,subPluginTitle);
});
}
}
}
}
function checkSubTiddler(parentPluginTitle,title) {
var tiddler = new $tw.Tiddler(pluginContents[parentPluginTitle].tiddlers[title]);
if(tiddler && tiddler.fields.type === "application/json" && tiddler.fields["plugin-type"] && (!pluginType || tiddler.fields["plugin-type"] === pluginType)) {
var disablingTiddler = self.getTiddler("$:/config/Plugins/Disabled/" + title);
if(title === "$:/core" || !disablingTiddler || (disablingTiddler.fields.text || "").trim() !== "yes") {
self.unregisterPluginTiddlers(null,[title]); // Unregister the plugin if it's already registered
pluginTiddlersInfo.push({tiddler: tiddler,parentPluginTitle: parentPluginTitle});
registeredTitles.push(tiddler.fields.title);
}
}
}
}; };
// Unregister the plugin tiddlers of a particular type, or null/undefined for any type, optionally restricting unregistering to an array of tiddler titles. Returns an array of the titles affected // Unregister the plugin tiddlers of a particular type, or null/undefined for any type, optionally restricting unregistering to an array of tiddler titles. Returns an array of the titles affected
@ -1458,11 +1480,12 @@ $tw.Wiki = function(options) {
var self = this, var self = this,
unregisteredTitles = []; unregisteredTitles = [];
// Remove any previous registered plugins of this type // Remove any previous registered plugins of this type
for(var t=pluginTiddlers.length-1; t>=0; t--) { for(var t=pluginTiddlersInfo.length-1; t>=0; t--) {
var tiddler = pluginTiddlers[t]; var pluginInfo = pluginTiddlersInfo[t],
tiddler = pluginInfo.tiddler;
if(tiddler.fields["plugin-type"] && (!pluginType || tiddler.fields["plugin-type"] === pluginType) && (!titles || titles.indexOf(tiddler.fields.title) !== -1)) { if(tiddler.fields["plugin-type"] && (!pluginType || tiddler.fields["plugin-type"] === pluginType) && (!titles || titles.indexOf(tiddler.fields.title) !== -1)) {
unregisteredTitles.push(tiddler.fields.title); unregisteredTitles.push(tiddler.fields.title);
pluginTiddlers.splice(t,1); pluginTiddlersInfo.splice(t,1);
} }
} }
return unregisteredTitles; return unregisteredTitles;
@ -1472,14 +1495,16 @@ $tw.Wiki = function(options) {
this.unpackPluginTiddlers = function() { this.unpackPluginTiddlers = function() {
var self = this; var self = this;
// Sort the plugin titles by the `plugin-priority` field, if this field is missing, default to 1 // Sort the plugin titles by the `plugin-priority` field, if this field is missing, default to 1
pluginTiddlers.sort(function(a, b) { pluginTiddlersInfo.sort(function(a, b) {
var priorityA = "plugin-priority" in a.fields ? a.fields["plugin-priority"] : 1; var fieldsA = a.tiddler.fields,
var priorityB = "plugin-priority" in b.fields ? b.fields["plugin-priority"] : 1; fieldsB = b.tiddler.fields,
priorityA = "plugin-priority" in fieldsA ? fieldsA["plugin-priority"] : 1,
priorityB = "plugin-priority" in fieldsB ? fieldsB["plugin-priority"] : 1;
if (priorityA !== priorityB) { if (priorityA !== priorityB) {
return priorityA - priorityB; return priorityA - priorityB;
} else if (a.fields.title < b.fields.title) { } else if (fieldsA.title < fieldsB.title) {
return -1; return -1;
} else if (a.fields.title === b.fields.title) { } else if (fieldsA.title === fieldsB.title) {
return 0; return 0;
} else { } else {
return +1; return +1;
@ -1487,10 +1512,17 @@ $tw.Wiki = function(options) {
}); });
// Now go through the plugins in ascending order and assign the shadows // Now go through the plugins in ascending order and assign the shadows
shadowTiddlerInfo = Object.create(null); shadowTiddlerInfo = Object.create(null);
$tw.utils.each(pluginTiddlers,function(tiddler) { $tw.utils.each(pluginTiddlersInfo,function(tiddlerInfo) {
var tiddler = tiddlerInfo.tiddler,
contents;
if(tiddlerInfo.parentPluginTitle) {
contents = $tw.utils.parseJSONSafe(pluginContents[tiddlerInfo.parentPluginTitle].tiddlers[tiddler.fields.title].text || "null");
} else {
contents = pluginContents[tiddler.fields.title];
}
// Extract the constituent tiddlers // Extract the constituent tiddlers
if($tw.utils.hop(pluginContents,tiddler.fields.title)) { if(contents) {
$tw.utils.each(pluginContents[tiddler.fields.title].tiddlers,function(constituentTiddler,constituentTitle) { $tw.utils.each(contents.tiddlers,function(constituentTiddler,constituentTitle) {
// Save the tiddler object // Save the tiddler object
if(constituentTitle) { if(constituentTitle) {
shadowTiddlerInfo[constituentTitle] = { shadowTiddlerInfo[constituentTitle] = {