/*\ title: $:/core/modules/wiki.js type: application/javascript module-type: wikimethod Extension methods for the $tw.Wiki object Adds the following properties to the wiki object: * `eventListeners` is an array of {filter: , listener: fn} * `changedTiddlers` is a hashmap describing changes to named tiddlers since wiki change events were last dispatched. Each entry is a hashmap containing two fields: modified: true/false deleted: true/false * `changeCount` is a hashmap by tiddler title containing a numerical index that starts at zero and is incremented each time a tiddler is created changed or deleted * `caches` is a hashmap by tiddler title containing a further hashmap of named cache objects. Caches are automatically cleared when a tiddler is modified or deleted * `macros` is a hashmap by macro name containing an object class inheriting from the Macro tree node \*/ (function(){ /*jslint node: true, browser: true */ /*global $tw: false */ "use strict"; /* Get the value of a text reference */ exports.getTextReference = function(textRef,defaultText,currTiddlerTitle) { var tr = this.parseTextReference(textRef), title = tr.title || currTiddlerTitle, field = tr.field || "text", tiddler = this.getTiddler(title); if(tiddler && $tw.utils.hop(tiddler.fields,field)) { return tiddler.fields[field]; } else { return defaultText; } }; exports.setTextReference = function(textRef,value,currTiddlerTitle) { }; exports.deleteTextReference = function(textRef) { }; /* Parse a text reference into its constituent parts */ exports.parseTextReference = function(textRef,currTiddlerTitle) { // Look for a metadata field separator var pos = textRef.indexOf("!!"); if(pos !== -1) { if(pos === 0) { return { field: textRef }; } else { return { title: textRef.substring(0,pos - 1), field: textRef.substring(pos + 2) }; } } else { // Otherwise, we've just got a title return { title: textRef }; } }; exports.addEventListener = function(filter,listener) { this.eventListeners = this.eventListeners || []; this.eventListeners.push({ filter: filter, listener: listener }); }; exports.removeEventListener = function(filter,listener) { for(var c=this.eventListeners.length-1; c>=0; c--) { var l = this.eventListeners[c]; if(l.filter === filter && l.listener === listener) { this.eventListeners.splice(c,1); } } }; /* Causes a tiddler to be marked as changed, incrementing the change count, and triggers event handlers. This method should be called after the changes it describes have been made to the wiki.tiddlers[] array. title: Title of tiddler isDeleted: defaults to false (meaning the tiddler has been created or modified), true if the tiddler has been created */ exports.touchTiddler = function(title,isDeleted) { // Record the touch in the list of changed tiddlers this.changedTiddlers = this.changedTiddlers || {}; this.changedTiddlers[title] = this.changedTiddlers[title] || []; this.changedTiddlers[title][isDeleted ? "deleted" : "modified"] = true; // Increment the change count this.changeCount = this.changeCount || {}; if($tw.utils.hop(this.changeCount,title)) { this.changeCount[title]++; } else { this.changeCount[title] = 1; } // Trigger events this.eventListeners = this.eventListeners || []; if(!this.eventsTriggered) { var me = this; $tw.utils.nextTick(function() { var changes = me.changedTiddlers; me.changedTiddlers = {}; me.eventsTriggered = false; for(var e=0; e bb) { return 1; } else { return 0; } } }); for(t=0; t bb) { return isDescending ? -1 : +1; } else { return 0; } } }); }; exports.forEachTiddler = function(/* [sortField,[excludeTag,]]callback */) { var arg = 0, sortField = arguments.length > 1 ? arguments[arg++] : null, excludeTag = arguments.length > 2 ? arguments[arg++] : null, callback = arguments[arg++], titles = this.getTiddlers(sortField,excludeTag), t, tiddler; for(t=0; t