1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-04-02 00:36:56 +00:00

Start responding to dynamic stylesheet changes

This mechanism will only be triggered by changes to the stylesheet
tiddlers themselves, and not to any dependencies that they might have.
It'll stay that way for a while.

The next thing is making the theme manager actually switch themes,
forcing the right wiki change events to make the stylesheet manager
update itself
This commit is contained in:
Jeremy Ruston 2013-04-29 12:07:39 +01:00
parent c3e14a85a6
commit 152fb798eb
3 changed files with 104 additions and 15 deletions
core/modules

@ -89,21 +89,9 @@ exports.startup = function() {
document.addEventListener("tw-clear-password",function(event) {
$tw.crypto.setPassword(null);
});
// Unpack the current theme tiddlers
$tw.wiki.unpackPluginTiddlers("theme");
// Apply stylesheets
var stylesheetTiddlers = $tw.wiki.filterTiddlers("[is[shadow]tag[$:/tags/stylesheet]]");
$tw.utils.each(stylesheetTiddlers,function(title,index) {
// Stylesheets don't refresh, yet
var parser = $tw.wiki.parseTiddler(title),
renderTree = new $tw.WikiRenderTree(parser,{wiki: $tw.wiki});
renderTree.execute({tiddlerTitle: title});
var styleNode = document.createElement("style");
styleNode.type = "text/css";
var text = renderTree.render("text/plain");
styleNode.appendChild(document.createTextNode(text));
document.getElementsByTagName("head")[0].appendChild(styleNode);
});
// Kick off the theme and the stylesheet manager
$tw.themeManager = new $tw.ThemeManager($tw.wiki);
$tw.stylesheetManager = new $tw.utils.StylesheetManager($tw.wiki);
// If we're being viewed on a data: URI then give instructions for how to save
if(document.location.protocol === "data:") {
$tw.utils.dispatchCustomEvent(document,"tw-modal",{

23
core/modules/themes.js Normal file

@ -0,0 +1,23 @@
/*\
title: $:/core/modules/themes.js
type: application/javascript
module-type: global
Manages themes and styling.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
function ThemeManager(wiki) {
this.wiki = wiki;
// Unpack the current theme tiddlers
$tw.wiki.unpackPluginTiddlers("theme");
}
exports.ThemeManager = ThemeManager;
})();

@ -0,0 +1,78 @@
/*\
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 + "]]");
$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 parser = this.wiki.parseTiddler(title),
renderTree = new $tw.WikiRenderTree(parser,{wiki: this.wiki});
renderTree.execute({tiddlerTitle: title});
var text = renderTree.render("text/plain");
// 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;
})();