diff --git a/js/Dependencies.js b/js/Dependencies.js new file mode 100644 index 000000000..3793a581f --- /dev/null +++ b/js/Dependencies.js @@ -0,0 +1,57 @@ +/*\ +title: js/Dependencies.js + +Represents the dependencies of a tiddler or a parser node as two fields: + + tiddlers: A hashmap of explicitly tiddler titles, with the value `false` if the dependency is skinny, and `true` if it is fat + dependentAll: True if there is an implicit skinny dependency on all available tiddlers + +\*/ +(function(){ + +/*jslint node: true */ +"use strict"; + +var utils = require("./Utils.js"); + +var Dependencies = function(tiddlers,dependentAll) { + this.tiddlers = tiddlers || {}; + this.dependentAll = dependentAll; +}; + +/* +Adds a dependency to a given tiddler. Note how setting a dependency of fat=false on a tiddler that already has +a dependency of fat=true will leave the fat setting as true +*/ +Dependencies.prototype.addDependency = function(tiddlerTitle,fat) { + if(!this.tiddlers[tiddlerTitle]) { + this.tiddlers[tiddlerTitle] = fat; + } +}; + +Dependencies.prototype.mergeDependencies = function(dep) { + this.dependentAll = dep.dependentAll || this.dependentAll; + for(var t in dep.tiddlers) { + this.addDependency(t,dep.tiddlers[t]); + } +}; + +/* +Determine if these dependencies are impacted by the specified array of changes + changes: Hashmap of {title: "created|modified|deleted"} +*/ +Dependencies.prototype.hasChanged = function(changes) { + if(this.dependentAll) { + return true; + } + for(var c in changes) { + if(this.tiddlers.hasOwnProperty(c)) { + return true; + } + } + return false; +}; + +exports.Dependencies = Dependencies; + +})(); diff --git a/js/ImageParser.js b/js/ImageParser.js index 6b9d1a21e..efe424a02 100644 --- a/js/ImageParser.js +++ b/js/ImageParser.js @@ -11,6 +11,7 @@ Compiles images into JavaScript functions that render them in HTML var WikiTextParseTree = require("./WikiTextParseTree.js").WikiTextParseTree, Renderer = require("./Renderer.js").Renderer, + Dependencies = require("./Dependencies.js").Dependencies, utils = require("./Utils.js"); var ImageParser = function(options) { @@ -24,7 +25,7 @@ ImageParser.prototype.parse = function(type,text) { } else { src = "data:" + type + ";base64," + text; } - return new WikiTextParseTree([Renderer.ElementNode("img",{src: src})],{},this.store); + return new WikiTextParseTree([Renderer.ElementNode("img",{src: src})],new Dependencies(),this.store); }; exports.ImageParser = ImageParser; diff --git a/js/JSONParser.js b/js/JSONParser.js index c8f599d27..95f078fb9 100644 --- a/js/JSONParser.js +++ b/js/JSONParser.js @@ -11,6 +11,7 @@ Compiles JSON objects into JavaScript functions that render them in HTML and pla var WikiTextParseTree = require("./WikiTextParseTree.js").WikiTextParseTree, Renderer = require("./Renderer.js").Renderer, + Dependencies = require("./Dependencies.js").Dependencies, utils = require("./Utils.js"); var renderObject = function(obj) { @@ -43,7 +44,7 @@ var JSONParser = function(options) { }; JSONParser.prototype.parse = function(type,text) { - return new WikiTextParseTree([renderObject(JSON.parse(text))],{},this.store); + return new WikiTextParseTree([renderObject(JSON.parse(text))],new Dependencies(),this.store); }; exports.JSONParser = JSONParser; diff --git a/js/Renderer.js b/js/Renderer.js index 1d98a31cf..c60a04c6d 100644 --- a/js/Renderer.js +++ b/js/Renderer.js @@ -87,24 +87,9 @@ MacroNode.prototype.renderInDom = function(domNode,insertBefore) { MacroNode.prototype.refresh = function(changes) { var t, - self = this, - hasDependencyChanged = function() { - if(self.dependencies.dependentAll) { - return true; - } - for(var rel in self.dependencies) { - if(rel !== "dependentAll") { - for(var t in self.dependencies[rel]) { - if(changes.hasOwnProperty(t)) { - return true; - } - } - } - } - return false; - }; + self = this; // Check if any of the dependencies of this macro node have changed - if(hasDependencyChanged()) { + if(this.dependencies.hasChanged(changes)) { // Re-execute the macro if so var tiddler = this.store.getTiddler(this.tiddlerTitle); this.execute(tiddler); @@ -118,24 +103,9 @@ MacroNode.prototype.refresh = function(changes) { MacroNode.prototype.refreshInDom = function(changes) { var t, - self = this, - hasDependencyChanged = function() { - if(self.dependencies.dependentAll) { - return true; - } - for(var rel in self.dependencies) { - if(rel !== "dependentAll") { - for(var t in self.dependencies[rel]) { - if(changes.hasOwnProperty(t)) { - return true; - } - } - } - } - return false; - }; + self = this; // Check if any of the dependencies of this macro node have changed - if(hasDependencyChanged()) { + if(this.dependencies.hasChanged(changes)) { // Ask the macro to rerender itself if it can var tiddler = this.store.getTiddler(this.tiddlerTitle); if(this.macro.refresh) { diff --git a/js/WikiTextParser.js b/js/WikiTextParser.js index 450912b64..b9952ef24 100644 --- a/js/WikiTextParser.js +++ b/js/WikiTextParser.js @@ -33,6 +33,7 @@ HTML nodes look like this: var WikiTextRules = require("./WikiTextRules.js"), WikiTextParseTree = require("./WikiTextParseTree.js").WikiTextParseTree, + Dependencies = require("./Dependencies.js").Dependencies, Renderer = require("./Renderer.js").Renderer, utils = require("./Utils.js"), util = require("util"); @@ -67,7 +68,7 @@ WikiTextParser.prototype.parse = function(type,text) { this.source = text; this.nextMatch = 0; this.children = []; - this.dependencies = {}; + this.dependencies = new Dependencies(); this.output = null; this.subWikify(this.children); var tree = new WikiTextParseTree(this.children,this.dependencies,this.store); @@ -76,25 +77,6 @@ WikiTextParser.prototype.parse = function(type,text) { return tree; }; -WikiTextParser.prototype.mergeDependencies = function(newDependencies) { - for(var rel in newDependencies) { - if(rel === "dependentAll") { - this.dependencies.dependentAll = newDependencies.dependentAll; - } else { - if(!(rel in this.dependencies)) { - this.dependencies[rel] = {}; - } - for(var t in newDependencies[rel]) { - if(this.dependencies[rel][t]) { - this.dependencies[rel][t]++; - } else { - this.dependencies[rel][t] = 1; - } - } - } - } -}; - WikiTextParser.prototype.outputText = function(place,startPos,endPos) { if(startPos < endPos) { place.push(Renderer.TextNode(this.source.substring(startPos,endPos))); diff --git a/js/WikiTextRules.js b/js/WikiTextRules.js index 2152a0051..eb441c023 100755 --- a/js/WikiTextRules.js +++ b/js/WikiTextRules.js @@ -9,6 +9,7 @@ title: js/WikiTextRules.js var ArgParser = require("./ArgParser.js").ArgParser, Renderer = require("./Renderer.js").Renderer, + Dependencies = require("./Dependencies.js").Dependencies, util = require("util"); var textPrimitives = { @@ -131,7 +132,7 @@ var compileMacroParams = function(w,params) { var insertMacroCall = function(w,output,name,params,children) { var macro = w.store.macros[name], - dependencies = {}; + dependencies = new Dependencies(); if(macro) { if(macro.dependentAll) { dependencies.dependentAll = true; @@ -143,21 +144,12 @@ var insertMacroCall = function(w,output,name,params,children) { if(params[m].type === "eval") { dependencies.dependentAll = true; } else { - var rel = param.rel || "include", - target = params[m].value; - if(!(rel in dependencies)) { - dependencies[rel] = {}; - } - if(dependencies[rel][target]) { - dependencies[rel][target]++; - } else { - dependencies[rel][target] = 1; - } + dependencies.addDependency(params[m].value,param.skinny); } } } } - w.mergeDependencies(dependencies); + w.dependencies.mergeDependencies(dependencies); output.push(Renderer.MacroNode(name,compileMacroParams(w,params),children,dependencies,w.store)); } }; diff --git a/js/macros/link.js b/js/macros/link.js index f9f9c21a2..56d89fc42 100644 --- a/js/macros/link.js +++ b/js/macros/link.js @@ -18,7 +18,7 @@ exports.macro = { name: "link", types: ["text/html","text/plain"], params: { - target: {byName: "default", type: "tiddler", rel: "link", optional: false} + target: {byName: "default", type: "tiddler", skinny: true, optional: false} }, events: { click: function(event,macroNode) { diff --git a/js/macros/slider.js b/js/macros/slider.js index 65105e2ca..4fc553196 100644 --- a/js/macros/slider.js +++ b/js/macros/slider.js @@ -8,6 +8,7 @@ title: js/macros/slider.js "use strict"; var Renderer = require("../Renderer.js").Renderer, + Dependencies = require("../Dependencies.js").Dependencies, Tiddler = require("../Tiddler.js").Tiddler, utils = require("../Utils.js"); @@ -35,8 +36,8 @@ exports.macro = { var stateTiddler = macroNode.params.state ? store.getTiddler(macroNode.params.state) : {text: ""}, isOpen = stateTiddler.text.trim() === "open", target = macroNode.params.targetTiddler, - dependencies = {include: {}}; - dependencies.include[target] = 1; + dependencies = new Dependencies(); + dependencies.addDependency(target,true); var content = Renderer.SliderNode(macroNode.params.state, macroNode.params.label, macroNode.params.tooltip, diff --git a/js/macros/story.js b/js/macros/story.js index 16f5ae174..02f0ce3ce 100644 --- a/js/macros/story.js +++ b/js/macros/story.js @@ -9,6 +9,7 @@ title: js/macros/story.js var Tiddler = require("../Tiddler.js").Tiddler, Renderer = require("../Renderer.js").Renderer, + Dependencies = require("../Dependencies.js").Dependencies, utils = require("../Utils.js"); // Parse the text of a story tiddler into an array of tiddler titles @@ -47,10 +48,10 @@ exports.macro = { content = []; for(var t=0; t