From 523d70127bb84a5cd46cb6491e263e16c8e0a183 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 30 Apr 2013 22:57:10 +0100 Subject: [PATCH] Allow themes to be switched by changing the tiddler `$:/theme` --- core/modules/themes.js | 64 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/core/modules/themes.js b/core/modules/themes.js index a2df8a535..3059c1214 100644 --- a/core/modules/themes.js +++ b/core/modules/themes.js @@ -12,12 +12,72 @@ Manages themes and styling. /*global $tw: false */ "use strict"; +var THEME_PLUGIN_TITLE = "$:/theme", // This tiddler contains the title of the current theme plugin + DEFAULT_THEME_PLUGIN = "$:/themes/tiddlywiki/snowwhite"; + function ThemeManager(wiki) { this.wiki = wiki; - // Unpack the current theme tiddlers - $tw.wiki.unpackPluginTiddlers("theme"); + // There's no theme to start with + this.currentThemeTitle = undefined; + // Switch to the current theme + this.switchTheme(); + // Listen for changes to the theme + var self = this; + this.wiki.addEventListener("change",function(changes) { + if($tw.utils.hop(changes,THEME_PLUGIN_TITLE)) { + self.switchTheme(); + } + }); } +ThemeManager.prototype.switchTheme = function() { + // Get the name of the current theme + var themePluginTitle = this.wiki.getTiddlerText(THEME_PLUGIN_TITLE,DEFAULT_THEME_PLUGIN); + // Get the theme plugin + var themePluginTiddler = this.wiki.getTiddler(themePluginTitle); + // Complain if we don't have a theme + if(!themePluginTiddler || !themePluginTiddler.isPlugin()) { + return $tw.utils.error("Cannot load theme " + themePluginTitle); + } + // Accumulate the titles of the plugins that we need to load + var themePlugins = [], + self = this, + accumulatePlugin = function(title) { + var tiddler = self.wiki.getTiddler(title); + if(tiddler && tiddler.isPlugin() && themePlugins.indexOf(title) === -1) { + themePlugins.push(title); + var pluginInfo = JSON.parse(self.wiki.getTiddlerText(title)); + $tw.utils.each(pluginInfo.dependents,function(title) { + accumulatePlugin(title); + }); + } + }; + accumulatePlugin(themePluginTitle); + // Unregister any existing theme tiddlers + var unregisteredThemeTiddlers = $tw.wiki.unregisterPluginTiddlers("theme"); + // Accumulate the titles of shadow tiddlers that have changed as a result of this switch + var changedTiddlers = {}; + $tw.utils.each(this.wiki.shadowTiddlers,function(shadowInfo,title) { + if(unregisteredThemeTiddlers.indexOf(shadowInfo.source) !== -1) { + changedTiddlers[title] = true; // isDeleted? + } + }); + // Register any new theme tiddlers + var registeredThemeTiddlers = $tw.wiki.registerPluginTiddlers("theme",themePlugins); + // Unpack the current theme tiddlers + $tw.wiki.unpackPluginTiddlers(); + // Accumulate the affected shadow tiddlers + $tw.utils.each(this.wiki.shadowTiddlers,function(shadowInfo,title) { + if(registeredThemeTiddlers.indexOf(shadowInfo.source) !== -1) { + changedTiddlers[title] = false; // isDeleted? + } + }); + // Issue change events for the modified tiddlers + $tw.utils.each(changedTiddlers,function(status,title) { + self.wiki.enqueueTiddlerEvent(title,status); + }); +}; + exports.ThemeManager = ThemeManager; })();