/*\ title: js/WikiStore.js \*/ (function(){ /*jslint node: true */ "use strict"; var Tiddler = require("./Tiddler.js").Tiddler, utils = require("./Utils.js"); /* Creates a new WikiStore object Available options are: shadowStore: An existing WikiStore to use for shadow tiddler storage. Pass null to prevent a default shadow store from being created */ var WikiStore = function WikiStore(options) { options = options || {}; this.tiddlers = {}; this.parsers = {}; this.macros = {}; this.tiddlerSerializers = {}; this.tiddlerDeserializers = {}; this.eventListeners = []; // Array of {filter:,listener:} this.eventsTriggered = false; this.changedTiddlers = {}; // Hashmap of {title: "created|modified|deleted"} this.sandbox = options.sandbox; this.shadows = options.shadowStore !== undefined ? options.shadowStore : new WikiStore({ shadowStore: null }); }; WikiStore.prototype.registerParser = function(type,parser) { this.parsers[type] = parser; }; WikiStore.prototype.registerTiddlerSerializer = function(extension,mimeType,serializer) { this.tiddlerSerializers[extension] = serializer; this.tiddlerSerializers[mimeType] = serializer; }; WikiStore.prototype.registerTiddlerDeserializer = function(extension,mimeType,deserializer) { this.tiddlerDeserializers[extension] = deserializer; this.tiddlerDeserializers[mimeType] = deserializer; }; WikiStore.prototype.addEventListener = function(filter,listener) { this.eventListeners.push({ filter: filter, listener: listener }); }; WikiStore.prototype.removeEventListener = function(listener) { for(var c=this.eventListeners.length-1; c>=0; c--) { var l = this.eventListeners[c]; if(l.listener === listener) { this.eventListeners.splice(c,1); } } }; /* Causes a tiddler to be marked as changed, so that event listeners are triggered for it type: Type of change to be registered for the tiddler "created", "modified" or "deleted" If the tiddler is already touched, the resultant touch type is as follows: If the tiddler is already marked "created", ... attempts to mark it "modified" leave it "created" ... attempts to mark it "deleted" succeed If the tiddler is already marked "modified", ... attempts to mark it "deleted" succeed If the tiddler is already marked "deleted", ... attempts to mark it "created" succeed ... attempts to mark it "modified" fail */ WikiStore.prototype.touchTiddler = function(type,title) { var existingType = this.changedTiddlers[title]; if(existingType === undefined && type === "modified") { type = "created"; } if(existingType === "modified" && type === "created") { type = "modified"; } if(existingType === "deleted" && type === "created") { type = "modified"; } this.changedTiddlers[title] = type; this.triggerEvents(); }; /* Trigger the execution of the event dispatcher at the next tick, if it is not already triggered */ WikiStore.prototype.triggerEvents = function() { if(!this.eventsTriggered) { var me = this; utils.nextTick(function() { var changes = me.changedTiddlers; me.changedTiddlers = {}; me.eventsTriggered = false; for(var e=0; e 1 ? arguments[a++] : null, excludeTag = arguments.length > 2 ? arguments[a++] : null, callback = arguments[a++], t, tiddlers = [], tiddler; if(sortField) { 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; } } }); for(t=0; t