diff --git a/js/Renderer.js b/js/Renderer.js index cc4a5a613..940ceb2fb 100644 --- a/js/Renderer.js +++ b/js/Renderer.js @@ -40,16 +40,46 @@ Node.prototype.refresh = function(changes) { Node.prototype.refreshInDom = function(changes) { }; -var MacroNode = function(macroName,paramFn,children,dependencies,store) { +/* +Construct a renderer node representing a macro invocation + macroName: name of the macro + params: a hashmap of parameters (each can be a string, or a fn(tiddler,store,utils) for evaluated parameters) + children: optional array of child nodes + store: reference to the WikiStore associated with this macro +*/ +var MacroNode = function(macroName,srcParams,children,store,dependencies) { if(this instanceof MacroNode) { + // Save the details this.macroName = macroName; this.macro = store.macros[macroName]; - this.paramFn = paramFn; // Can be a function yielding a hashmap, or a direct hashmap + this.srcParams = srcParams; this.children = children; - this.dependencies = dependencies; this.store = store; + // Evaluate the dependencies + if(dependencies) { + this.dependencies = dependencies; + } else { + this.dependencies = new Dependencies(); + if(srcParams && this.macro) { + if(this.macro.dependentAll) { + this.dependencies.dependentAll = true; + } + for(var m in this.macro.params) { + var paramInfo = this.macro.params[m]; + if(m in srcParams) { + if(paramInfo.type === "tiddler") { + if(typeof srcParams[m] === "function") { + this.dependencies.dependentAll = true; + } else { + this.dependencies.addDependency(srcParams[m],paramInfo.skinny); + } + } + } + } + } + } } else { - return new MacroNode(macroName,paramFn,children,dependencies,store); + return new MacroNode(macroName,srcParams,children,store,dependencies); } }; @@ -57,7 +87,7 @@ MacroNode.prototype = new Node(); MacroNode.prototype.constructor = MacroNode; MacroNode.prototype.clone = function() { - return new MacroNode(this.macroName,this.paramFn,this.cloneChildren(),this.dependencies,this.store); + return new MacroNode(this.macroName,this.srcParams,this.cloneChildren(),this.store,this.dependencies); }; MacroNode.prototype.cloneChildren = function() { @@ -72,11 +102,14 @@ MacroNode.prototype.cloneChildren = function() { }; MacroNode.prototype.execute = function(parents,tiddler) { - // Evaluate the macro parameters to get their values - if(typeof this.paramFn === "object") { - this.params = this.paramFn; - } else { - this.params = this.paramFn(tiddler,this.store,utils); + // Evaluate macro parameters to get their values + this.params = {}; + for(var p in this.srcParams) { + if(typeof this.srcParams[p] === "function") { + this.params[p] = this.srcParams[p](tiddler,this.store,utils); + } else { + this.params[p] = this.srcParams[p]; + } } // Save the context tiddler this.tiddlerTitle = tiddler ? tiddler.title : null; @@ -404,7 +437,6 @@ var Renderer = function(tiddlerTitle,templateTitle,store) { "tiddler", {target: tiddlerTitle, template: templateTitle}, null, - new Dependencies([],[tiddlerTitle,templateTitle]), store); this.macro.execute(); }; diff --git a/js/WikiStore.js b/js/WikiStore.js index 672d8e0e2..6bba96723 100755 --- a/js/WikiStore.js +++ b/js/WikiStore.js @@ -278,7 +278,6 @@ WikiStore.prototype.renderTiddler = function(targetType,tiddlerTitle,templateTit "tiddler", {target: tiddlerTitle, template: templateTitle}, null, - new Dependencies([],[tiddlerTitle,templateTitle]), this); macro.execute(); return macro.render(targetType); diff --git a/js/WikiTextRules.js b/js/WikiTextRules.js index eb441c023..8dd25d2a0 100755 --- a/js/WikiTextRules.js +++ b/js/WikiTextRules.js @@ -103,54 +103,11 @@ var enclosedTextHelper = function(w) { } }; -var compileMacroParams = function(w,params) { - // Slot the parameters into the macro call - var properties = [],n; - for(var p in params) { - if(params[p].type === "string") { - n = {type: "StringLiteral", value: params[p].value}; - } else { - n = w.store.jsParser.parse(params[p].value).tree.elements[0]; - } - properties.push({type: "PropertyAssignment",name: p,value: n}); - } - return w.store.jsParser.createTree([ - { - type: "Function", - name: null, - params: ["tiddler","store","utils"], // These are the parameters passed to the parameter expressions - elements: [ { - type: "ReturnStatement", - value: { - type: "ObjectLiteral", - properties: properties - } - } ] - } - ]).compile("application/javascript").render; -}; - var insertMacroCall = function(w,output,name,params,children) { - var macro = w.store.macros[name], - dependencies = new Dependencies(); - if(macro) { - if(macro.dependentAll) { - dependencies.dependentAll = true; - } - for(var m in macro.params) { - var param = macro.params[m]; - if(m in params) { - if(param.type === "tiddler") { - if(params[m].type === "eval") { - dependencies.dependentAll = true; - } else { - dependencies.addDependency(params[m].value,param.skinny); - } - } - } - } - w.dependencies.mergeDependencies(dependencies); - output.push(Renderer.MacroNode(name,compileMacroParams(w,params),children,dependencies,w.store)); + if(name in w.store.macros) { + var macroNode = Renderer.MacroNode(name,params,children,w.store); + w.dependencies.mergeDependencies(macroNode.dependencies); + output.push(macroNode); } }; @@ -160,7 +117,21 @@ var parseMacroParams = function(w,name,paramString) { if(macro) { var args = new ArgParser(paramString,{defaultName: "anon"}), insertParam = function(param,name,arg) { - params[name] = {type: arg.evaluated ? "eval" : "string", value: arg.string}; + if(arg.evaluated) { + params[name] = w.store.jsParser.createTree([ + { + type: "Function", + name: null, + params: ["tiddler","store","utils"], // These are the parameters passed to the parameter expressions + elements: [ { + type: "ReturnStatement", + value: w.store.jsParser.parse(arg.string).tree.elements[0] + } ] + } + ]).compile("application/javascript").render; + } else { + params[name] = arg.string; + } }; for(var m in macro.params) { var param = macro.params[m], @@ -509,9 +480,7 @@ var rules = [ // Pretty bracketted link link = lookaheadMatch[3]; } - insertMacroCall(w,w.output,"link",{ - target: {type: "string", value: link} - },[Renderer.TextNode(text)]); + insertMacroCall(w,w.output,"link",{target: link},[Renderer.TextNode(text)]); w.nextMatch = this.lookaheadRegExp.lastIndex; } } @@ -536,9 +505,7 @@ var rules = [ } } if(w.autoLinkWikiWords) { - insertMacroCall(w,w.output,"link",{ - target: {type: "string", value: w.matchText} - },[Renderer.TextNode(w.source.substring(w.matchStart,w.nextMatch))]); + insertMacroCall(w,w.output,"link",{target: w.matchText},[Renderer.TextNode(w.source.substring(w.matchStart,w.nextMatch))]); } else { w.outputText(w.output,w.matchStart,w.nextMatch); } @@ -550,9 +517,7 @@ var rules = [ match: textPrimitives.urlPattern, handler: function(w) { - insertMacroCall(w,w.output,"link",{ - target: {type: "string", value: w.matchText} - },[Renderer.TextNode(w.source.substring(w.matchStart,w.nextMatch))]); + insertMacroCall(w,w.output,"link",{target: w.matchText},[Renderer.TextNode(w.source.substring(w.matchStart,w.nextMatch))]); } }, @@ -565,24 +530,20 @@ var rules = [ { this.lookaheadRegExp.lastIndex = w.matchStart; var lookaheadMatch = this.lookaheadRegExp.exec(w.source), - imageParams = { - src: {type: "string", value: ""} - }, - linkParams = { - target: {type: "string", value: ""} - }; + imageParams = {}, + linkParams = {}; if(lookaheadMatch && lookaheadMatch.index == w.matchStart) { if(lookaheadMatch[1]) { - imageParams.alignment = {type: "string", value: "left"}; + imageParams.alignment = "left"; } else if(lookaheadMatch[2]) { - imageParams.alignment = {type: "string", value: "right"}; + imageParams.alignment = "right"; } if(lookaheadMatch[3]) { - imageParams.text = {type: "string", value: lookaheadMatch[3]}; + imageParams.text = lookaheadMatch[3]; } - imageParams.src.value = lookaheadMatch[4]; + imageParams.src = lookaheadMatch[4]; if(lookaheadMatch[5]) { - linkParams.target.value = lookaheadMatch[5]; + linkParams.target = lookaheadMatch[5]; var linkChildren = []; insertMacroCall(w,w.output,"link",linkParams,linkChildren); insertMacroCall(w,linkChildren,"image",imageParams); diff --git a/js/macros/slider.js b/js/macros/slider.js index b21e65c9a..9ae3b8a72 100644 --- a/js/macros/slider.js +++ b/js/macros/slider.js @@ -48,7 +48,6 @@ exports.macro = { "tiddler", {target: target}, null, - new Dependencies([],[target]), store) ]); content.execute(macroNode.parents,tiddler); diff --git a/js/macros/story.js b/js/macros/story.js index 6ad925103..4c6d23eb3 100644 --- a/js/macros/story.js +++ b/js/macros/story.js @@ -50,7 +50,6 @@ exports.macro = { var m = Renderer.MacroNode("tiddler", {target: tiddlers[t],template: macroNode.params.template}, null, - new Dependencies([],[tiddlers[t],macroNode.params.template]), store); m.execute(macroNode.parents,tiddler); content.push(m); @@ -83,7 +82,6 @@ exports.macro = { var m = Renderer.MacroNode("tiddler", {target: targetTiddlers[t],template: template}, null, - new Dependencies([],[targetTiddlers[t],template]), store); m.execute(macroNode.parents,store.getTiddler(targetTiddlers[t])); m.renderInDom(macroNode.domNode,macroNode.domNode.childNodes[t]); diff --git a/js/macros/view.js b/js/macros/view.js index bf4b0ba4e..c0e117e8a 100644 --- a/js/macros/view.js +++ b/js/macros/view.js @@ -34,7 +34,6 @@ exports.macro = { var link = Renderer.MacroNode("link", {target: v}, [Renderer.TextNode(v)], - new Dependencies([v]), store); link.execute(parents,tiddler); return [link];