From 1c529ddcd457821b2ce7aec466b1186217d72ed5 Mon Sep 17 00:00:00 2001 From: Jermolene Date: Fri, 20 Dec 2013 15:31:16 +0000 Subject: [PATCH] Refactored stylesheet implementation This way we reuse the refresh mechanism properly so that theme tweaks can be applied interactively. --- core/modules/startup.js | 16 ++++++- core/modules/utils/dom/styles.js | 75 -------------------------------- core/ui/PageStylesheet.tid | 5 +++ 3 files changed, 19 insertions(+), 77 deletions(-) delete mode 100644 core/modules/utils/dom/styles.js create mode 100644 core/ui/PageStylesheet.tid diff --git a/core/modules/startup.js b/core/modules/startup.js index 73a80c88e..2303b9849 100755 --- a/core/modules/startup.js +++ b/core/modules/startup.js @@ -59,8 +59,6 @@ exports.startup = function() { }); // Install the animator $tw.anim = new $tw.utils.Animator(); - // Kick off the stylesheet manager - $tw.stylesheetManager = new $tw.utils.StylesheetManager($tw.wiki); // Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers $tw.rootWidget = new widget.widget({ type: "widget", @@ -114,6 +112,20 @@ exports.startup = function() { $tw.rootWidget.addEventListener("tw-clear-password",function(event) { $tw.crypto.setPassword(null); }); + // Set up the styles + var styleTemplateTitle = "$:/core/ui/PageStylesheet", + styleParser = $tw.wiki.parseTiddler(styleTemplateTitle); + $tw.styleWidgetNode = $tw.wiki.makeWidget(styleParser,{document: $tw.document}); + $tw.styleContainer = $tw.document.createElement("style"); + $tw.styleWidgetNode.render($tw.styleContainer,null); + $tw.styleElement = document.createElement("style"); + $tw.styleElement.innerHTML = $tw.styleContainer.textContent; + document.head.insertBefore($tw.styleElement,document.head.firstChild); + $tw.wiki.addEventListener("change",function(changes) { + if($tw.styleWidgetNode.refresh(changes,$tw.styleContainer,null)) { + $tw.styleElement.innerHTML = $tw.styleContainer.textContent; + } + }); // Display the PageMacros, which includes the PageTemplate var templateTitle = "$:/core/ui/PageMacros", parser = $tw.wiki.parseTiddler(templateTitle); diff --git a/core/modules/utils/dom/styles.js b/core/modules/utils/dom/styles.js deleted file mode 100644 index 648e4c3d4..000000000 --- a/core/modules/utils/dom/styles.js +++ /dev/null @@ -1,75 +0,0 @@ -/*\ -title: $:/core/modules/utils/styles.js -type: application/javascript -module-type: utils - -The stylesheet manager automatically renders any tiddlers tagged "$:/tags/stylesheet" as HTML style elements. - -\*/ -(function(){ - -/*jslint node: true, browser: true */ -/*global $tw: false */ -"use strict"; - -var STYLESHEET_ID_PREFIX = "tw-tiddler-stylesheet-", - STYLESHEET_TAG = "$:/tags/stylesheet"; - -function StylesheetManager(wiki) { - this.wiki = wiki; - this.stylesheets = {}; // Hashmap of currently rendered stylesheets - // Apply initial stylesheets - var self = this, - stylesheetTiddlers = this.wiki.filterTiddlers("[is[shadow]!has[draft.of]tag[" + STYLESHEET_TAG + "]] [!is[shadow]!has[draft.of]tag[" + STYLESHEET_TAG + "]]"); - $tw.utils.each(stylesheetTiddlers,function(title,index) { - self.addStylesheet(title); - }); - // Listen out for changes - this.wiki.addEventListener("change",function(changes) { - self.handleTiddlerChanges(changes); - }); -} - -StylesheetManager.prototype.addStylesheet = function(title) { - // Record the stylesheet in the hashmap - this.stylesheets[title] = true; - // Parse the tiddler and render as plain text - var text = this.wiki.renderTiddler("text/plain",title); - // Create a style element and put it in the document - var styleNode = document.createElement("style"); - styleNode.setAttribute("type","text/css"); - styleNode.setAttribute("id",STYLESHEET_ID_PREFIX + title); - styleNode.appendChild(document.createTextNode(text)); - document.getElementsByTagName("head")[0].appendChild(styleNode); -}; - -StylesheetManager.prototype.removeStylesheet = function(title) { - // Remove the stylesheet from the hashmap - if($tw.utils.hop(this.stylesheets,title)) { - delete this.stylesheets[title]; - } - // Remove the stylesheet from the document - var styleNode = document.getElementById(STYLESHEET_ID_PREFIX + title); - if(styleNode) { - styleNode.parentNode.removeChild(styleNode); - } -}; - -StylesheetManager.prototype.handleTiddlerChanges = function(changes) { - var self = this; - $tw.utils.each(changes,function(change,title) { - // Remove any existing stylesheet for the changed tiddler - if($tw.utils.hop(self.stylesheets,title)) { - self.removeStylesheet(title); - } - // Add the stylesheet if it is tagged and not a draft - var tiddler = self.wiki.getTiddler(title); - if(tiddler && tiddler.hasTag(STYLESHEET_TAG) && !tiddler.hasField("draft.of")) { - self.addStylesheet(title); - } - }); -}; - -exports.StylesheetManager = StylesheetManager; - -})(); diff --git a/core/ui/PageStylesheet.tid b/core/ui/PageStylesheet.tid new file mode 100644 index 000000000..250490249 --- /dev/null +++ b/core/ui/PageStylesheet.tid @@ -0,0 +1,5 @@ +title: $:/core/ui/PageStylesheet + +<$list filter="[is[shadow]tag[$:/tags/stylesheet]] [!is[shadow]tag[$:/tags/stylesheet]]"> +<$transclude/> +