From b898afe3e502867bae4de05f4db6167607cea587 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 17 Jan 2012 13:01:55 +0000 Subject: [PATCH] Refactor the Tiddler object to enforce immutability And in the process move the fields out of the fields member --- js/BitmapParser.js | 2 +- js/Recipe.js | 24 +++++------ js/SVGParser.js | 2 +- js/Tiddler.js | 71 +++++++++++++++++++++++-------- js/TiddlerOutput.js | 37 ++++++++-------- js/WikiStore.js | 54 +++++++++++------------ js/macros/info.js | 2 +- js/macros/list.js | 4 +- js/macros/tiddler.js | 4 +- js/macros/view.js | 4 +- test/wikitests/SeventhTiddler.tid | 2 +- tiddlywiki.js | 2 +- 12 files changed, 120 insertions(+), 88 deletions(-) diff --git a/js/BitmapParser.js b/js/BitmapParser.js index 21690b2d4..1aaffe1fa 100644 --- a/js/BitmapParser.js +++ b/js/BitmapParser.js @@ -16,7 +16,7 @@ var BitmapParseTree = function() { BitmapParseTree.prototype.compile = function(type) { if(type === "text/html") { - return "(function (tiddler,store,utils) {return '';})"; + return "(function (tiddler,store,utils) {return '';})"; } else { return null; } diff --git a/js/Recipe.js b/js/Recipe.js index a97d1bdfc..4ffba500d 100755 --- a/js/Recipe.js +++ b/js/Recipe.js @@ -132,7 +132,7 @@ Recipe.prototype.loadTiddlerFiles = function(recipeLine) { filename = path.basename(filepath), // eg *.js posStar = filename.indexOf("*"); if(posStar !== -1) { - var fileRegExp = new RegExp("^" + filename.replace(/[-[\]{}()+?.,\\^$|#\s]/g, "\\$&").replace("*",".*") + "$"); + var fileRegExp = new RegExp("^" + filename.replace(/[\-\[\]{}()+?.,\\\^$|#\s]/g, "\\$&").replace("*",".*") + "$"); var files = fs.readdirSync(path.resolve(path.dirname(recipeLine.contextPath),filedir)); for(var f=0; f"); out.push("define(\"" + title + "\",function(require,exports,module) {"); - out.push(tid.fields.text); + out.push(tid.text); out.push("});"); out.push(""); } @@ -388,24 +388,24 @@ Recipe.prototype.cookRss = function() { return title.indexOf(" ") == -1 ? title : "[[" + title + "]]"; }, tiddlerToRssItem = function(tiddler,uri) { - var s = "" + utils.htmlEncode(tiddler.fields.title) + "\n"; - s += "" + utils.htmlEncode(me.store.renderTiddler("text/html",tiddler.fields.title)) + "\n"; + var s = "" + utils.htmlEncode(tiddler.title) + "\n"; + s += "" + utils.htmlEncode(me.store.renderTiddler("text/html",tiddler.title)) + "\n"; var i; - if(tiddler.fields.tags) { - for(i=0; i\n"; + if(tiddler.tags) { + for(i=0; i\n"; } } - s += "" + uri + "#" + encodeURIComponent(encodeTiddlyLink(tiddler.fields.title)) + "\n"; - if(tiddler.fields.modified) { - s +="" + tiddler.fields.modified.toUTCString() + "\n"; + s += "" + uri + "#" + encodeURIComponent(encodeTiddlyLink(tiddler.title)) + "\n"; + if(tiddler.modified) { + s +="" + tiddler.modified.toUTCString() + "\n"; } return s; }, getRssTiddlers = function(sortField,excludeTag) { var r = []; me.store.forEachTiddler(sortField,excludeTag,function(title,tiddler) { - if(!tiddler.hasTag(excludeTag) && tiddler.fields.modified !== undefined) { + if(!tiddler.hasTag(excludeTag) && tiddler.modified !== undefined) { r.push(tiddler); } }); diff --git a/js/SVGParser.js b/js/SVGParser.js index d2d95c09a..0aac9f5d2 100644 --- a/js/SVGParser.js +++ b/js/SVGParser.js @@ -16,7 +16,7 @@ var SVGParseTree = function() { SVGParseTree.prototype.compile = function(type) { if(type === "text/html") { - return "(function (tiddler,store,utils) {return tiddler.fields.text;})"; + return "(function (tiddler,store,utils) {return tiddler.text;})"; } else { return null; } diff --git a/js/Tiddler.js b/js/Tiddler.js index 48f9814e8..5e6146df7 100755 --- a/js/Tiddler.js +++ b/js/Tiddler.js @@ -21,25 +21,57 @@ var utils = require("./Utils.js"), ArgParser = require("./ArgParser.js").ArgParser; var Tiddler = function(/* tiddler,fields */) { - this.parseTree = null; // Caches the parse tree for the tiddler - this.renderers = {}; // Caches rendering functions for this tiddler (indexed by MIME type) - this.renditions = {}; // Caches the renditions produced by those functions (indexed by MIME type) - this.fields = {}; - for(var c=0; c bb) { + return 1; + } else { + return 0; } } - return false; }; -Tiddler.prototype.parseTiddlerField = function(name,value) { +Tiddler.parseTiddlerField = function(name,value) { var type = Tiddler.specialTiddlerFields[name]; if(type) { return Tiddler.specialTiddlerFieldParsers[type](value); diff --git a/js/TiddlerOutput.js b/js/TiddlerOutput.js index 9af6efcdd..15e92a821 100755 --- a/js/TiddlerOutput.js +++ b/js/TiddlerOutput.js @@ -34,29 +34,30 @@ var outputTiddler = function(tid) { var result = [], outputAttribute = function(name,value) { result.push(name + ": " + value + "\n"); - }; - for(var t in tid.fields) { + }, + fields = tid.getFields(); + for(var t in fields) { switch(t) { case "text": // Ignore the text field break; case "tags": // Output tags as a list - outputAttribute(t,tiddlerOutput.stringifyTags(tid.fields.tags)); + outputAttribute(t,tiddlerOutput.stringifyTags(fields.tags)); break; case "modified": case "created": // Output dates in YYYYMMDDHHMM - outputAttribute(t,utils.convertToYYYYMMDDHHMM(tid.fields[t])); + outputAttribute(t,utils.convertToYYYYMMDDHHMM(fields[t])); break; default: // Output other attributes raw - outputAttribute(t,tid.fields[t]); + outputAttribute(t,fields[t]); break; } } result.push("\n"); - result.push(tid.fields.text); + result.push(fields.text); return result.join(""); }; @@ -68,23 +69,19 @@ The fields are in the order title, creator, modifier, created, modified, tags, f */ var outputTiddlerDiv = function(tid) { var result = [], - attributes = {}, - outputAttribute = function(name,transform,dontDelete) { - if(name in attributes) { - var value = attributes[name]; + fields = tid.getFields(), + text = fields.text, + outputAttribute = function(name,transform) { + if(name in fields) { + var value = fields[name]; if(transform) value = transform(value); result.push(" " + name + "=\"" + value + "\""); - if(!dontDelete) { - delete attributes[name]; - } + delete fields[name]; } }; - for(var t in tid.fields) { - attributes[t] = tid.fields[t]; - } - if(attributes.text) { - delete attributes.text; + if(fields.text) { + delete fields.text; } result.push("\n
");
-	result.push(utils.htmlEncode(tid.fields.text));
+	result.push(utils.htmlEncode(text));
 	result.push("
\n"); return result.join(""); }; diff --git a/js/WikiStore.js b/js/WikiStore.js index 7d8306554..a4c9951e0 100755 --- a/js/WikiStore.js +++ b/js/WikiStore.js @@ -1,6 +1,12 @@ /*\ title: js/WikiStore.js +WikiStore uses the .cache member of tiddlers to store the following information: + + parseTree: Caches the parse tree for the tiddler + renderers: Caches rendering functions for this tiddler (indexed by MIME type) + renditions: Caches the renditions produced by those functions (indexed by MIME type) + \*/ (function(){ @@ -125,7 +131,7 @@ WikiStore.prototype.getTiddler = function(title) { WikiStore.prototype.getTiddlerText = function(title) { var t = this.getTiddler(title); - return t instanceof Tiddler ? t.fields.text : null; + return t instanceof Tiddler ? t.text : null; }; WikiStore.prototype.deleteTiddler = function(title) { @@ -143,8 +149,8 @@ WikiStore.prototype.tiddlerExists = function(title) { }; WikiStore.prototype.addTiddler = function(tiddler) { - this.tiddlers[tiddler.fields.title] = tiddler; - this.touchTiddler("modified",tiddler.fields.title); + this.tiddlers[tiddler.title] = tiddler; + this.touchTiddler("modified",tiddler.title); }; WikiStore.prototype.forEachTiddler = function(/* [sortField,[excludeTag,]]callback */) { @@ -159,22 +165,10 @@ WikiStore.prototype.forEachTiddler = function(/* [sortField,[excludeTag,]]callba for(t in this.tiddlers) { tiddlers.push(this.tiddlers[t]); } - tiddlers.sort(function (a,b) { - var aa = a.fields[sortField] || 0, - bb = b.fields[sortField] || 0; - if(aa < bb) { - return -1; - } else { - if(aa > bb) { - return 1; - } else { - return 0; - } - } - }); + tiddlers.sort(function (a,b) {return Tiddler.compareTiddlerFields(a,b,sortField);}); for(t=0; t> -<> +<> <> diff --git a/tiddlywiki.js b/tiddlywiki.js index e166f138b..a2b1c3de6 100644 --- a/tiddlywiki.js +++ b/tiddlywiki.js @@ -135,7 +135,7 @@ var commandLineSwitches = { handler: function(args,callback) { var recipe = []; app.store.forEachTiddler(function(title,tiddler) { - var filename = encodeURIComponent(tiddler.fields.title.replace(/ /g,"_")) + ".tid"; + var filename = encodeURIComponent(tiddler.title.replace(/ /g,"_")) + ".tid"; fs.writeFileSync(path.resolve(args[0],filename),tiddlerOutput.outputTiddler(tiddler),"utf8"); recipe.push("tiddler: " + filename + "\n"); });