1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-10-29 06:37:39 +00:00

Refactored evaluation of macro dependencies

Now the dependencies are evaluated in the constructor for the
Renderer.MacroNode
This commit is contained in:
Jeremy Ruston
2012-02-20 19:27:37 +00:00
parent b37d3b6670
commit 53f652bf2a
6 changed files with 72 additions and 84 deletions

View File

@@ -40,16 +40,46 @@ Node.prototype.refresh = function(changes) {
Node.prototype.refreshInDom = 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) { if(this instanceof MacroNode) {
// Save the details
this.macroName = macroName; this.macroName = macroName;
this.macro = store.macros[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.children = children;
this.dependencies = dependencies;
this.store = store; this.store = store;
// Evaluate the dependencies
if(dependencies) {
this.dependencies = dependencies;
} else { } else {
return new MacroNode(macroName,paramFn,children,dependencies,store); 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,srcParams,children,store,dependencies);
} }
}; };
@@ -57,7 +87,7 @@ MacroNode.prototype = new Node();
MacroNode.prototype.constructor = MacroNode; MacroNode.prototype.constructor = MacroNode;
MacroNode.prototype.clone = function() { 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() { MacroNode.prototype.cloneChildren = function() {
@@ -72,11 +102,14 @@ MacroNode.prototype.cloneChildren = function() {
}; };
MacroNode.prototype.execute = function(parents,tiddler) { MacroNode.prototype.execute = function(parents,tiddler) {
// Evaluate the macro parameters to get their values // Evaluate macro parameters to get their values
if(typeof this.paramFn === "object") { this.params = {};
this.params = this.paramFn; for(var p in this.srcParams) {
if(typeof this.srcParams[p] === "function") {
this.params[p] = this.srcParams[p](tiddler,this.store,utils);
} else { } else {
this.params = this.paramFn(tiddler,this.store,utils); this.params[p] = this.srcParams[p];
}
} }
// Save the context tiddler // Save the context tiddler
this.tiddlerTitle = tiddler ? tiddler.title : null; this.tiddlerTitle = tiddler ? tiddler.title : null;
@@ -404,7 +437,6 @@ var Renderer = function(tiddlerTitle,templateTitle,store) {
"tiddler", "tiddler",
{target: tiddlerTitle, template: templateTitle}, {target: tiddlerTitle, template: templateTitle},
null, null,
new Dependencies([],[tiddlerTitle,templateTitle]),
store); store);
this.macro.execute(); this.macro.execute();
}; };

View File

@@ -278,7 +278,6 @@ WikiStore.prototype.renderTiddler = function(targetType,tiddlerTitle,templateTit
"tiddler", "tiddler",
{target: tiddlerTitle, template: templateTitle}, {target: tiddlerTitle, template: templateTitle},
null, null,
new Dependencies([],[tiddlerTitle,templateTitle]),
this); this);
macro.execute(); macro.execute();
return macro.render(targetType); return macro.render(targetType);

View File

@@ -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 insertMacroCall = function(w,output,name,params,children) {
var macro = w.store.macros[name], if(name in w.store.macros) {
dependencies = new Dependencies(); var macroNode = Renderer.MacroNode(name,params,children,w.store);
if(macro) { w.dependencies.mergeDependencies(macroNode.dependencies);
if(macro.dependentAll) { output.push(macroNode);
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));
} }
}; };
@@ -160,7 +117,21 @@ var parseMacroParams = function(w,name,paramString) {
if(macro) { if(macro) {
var args = new ArgParser(paramString,{defaultName: "anon"}), var args = new ArgParser(paramString,{defaultName: "anon"}),
insertParam = function(param,name,arg) { 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) { for(var m in macro.params) {
var param = macro.params[m], var param = macro.params[m],
@@ -509,9 +480,7 @@ var rules = [
// Pretty bracketted link // Pretty bracketted link
link = lookaheadMatch[3]; link = lookaheadMatch[3];
} }
insertMacroCall(w,w.output,"link",{ insertMacroCall(w,w.output,"link",{target: link},[Renderer.TextNode(text)]);
target: {type: "string", value: link}
},[Renderer.TextNode(text)]);
w.nextMatch = this.lookaheadRegExp.lastIndex; w.nextMatch = this.lookaheadRegExp.lastIndex;
} }
} }
@@ -536,9 +505,7 @@ var rules = [
} }
} }
if(w.autoLinkWikiWords) { if(w.autoLinkWikiWords) {
insertMacroCall(w,w.output,"link",{ insertMacroCall(w,w.output,"link",{target: w.matchText},[Renderer.TextNode(w.source.substring(w.matchStart,w.nextMatch))]);
target: {type: "string", value: w.matchText}
},[Renderer.TextNode(w.source.substring(w.matchStart,w.nextMatch))]);
} else { } else {
w.outputText(w.output,w.matchStart,w.nextMatch); w.outputText(w.output,w.matchStart,w.nextMatch);
} }
@@ -550,9 +517,7 @@ var rules = [
match: textPrimitives.urlPattern, match: textPrimitives.urlPattern,
handler: function(w) handler: function(w)
{ {
insertMacroCall(w,w.output,"link",{ insertMacroCall(w,w.output,"link",{target: w.matchText},[Renderer.TextNode(w.source.substring(w.matchStart,w.nextMatch))]);
target: {type: "string", value: w.matchText}
},[Renderer.TextNode(w.source.substring(w.matchStart,w.nextMatch))]);
} }
}, },
@@ -565,24 +530,20 @@ var rules = [
{ {
this.lookaheadRegExp.lastIndex = w.matchStart; this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source), var lookaheadMatch = this.lookaheadRegExp.exec(w.source),
imageParams = { imageParams = {},
src: {type: "string", value: ""} linkParams = {};
},
linkParams = {
target: {type: "string", value: ""}
};
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) { if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
if(lookaheadMatch[1]) { if(lookaheadMatch[1]) {
imageParams.alignment = {type: "string", value: "left"}; imageParams.alignment = "left";
} else if(lookaheadMatch[2]) { } else if(lookaheadMatch[2]) {
imageParams.alignment = {type: "string", value: "right"}; imageParams.alignment = "right";
} }
if(lookaheadMatch[3]) { 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]) { if(lookaheadMatch[5]) {
linkParams.target.value = lookaheadMatch[5]; linkParams.target = lookaheadMatch[5];
var linkChildren = []; var linkChildren = [];
insertMacroCall(w,w.output,"link",linkParams,linkChildren); insertMacroCall(w,w.output,"link",linkParams,linkChildren);
insertMacroCall(w,linkChildren,"image",imageParams); insertMacroCall(w,linkChildren,"image",imageParams);

View File

@@ -48,7 +48,6 @@ exports.macro = {
"tiddler", "tiddler",
{target: target}, {target: target},
null, null,
new Dependencies([],[target]),
store) store)
]); ]);
content.execute(macroNode.parents,tiddler); content.execute(macroNode.parents,tiddler);

View File

@@ -50,7 +50,6 @@ exports.macro = {
var m = Renderer.MacroNode("tiddler", var m = Renderer.MacroNode("tiddler",
{target: tiddlers[t],template: macroNode.params.template}, {target: tiddlers[t],template: macroNode.params.template},
null, null,
new Dependencies([],[tiddlers[t],macroNode.params.template]),
store); store);
m.execute(macroNode.parents,tiddler); m.execute(macroNode.parents,tiddler);
content.push(m); content.push(m);
@@ -83,7 +82,6 @@ exports.macro = {
var m = Renderer.MacroNode("tiddler", var m = Renderer.MacroNode("tiddler",
{target: targetTiddlers[t],template: template}, {target: targetTiddlers[t],template: template},
null, null,
new Dependencies([],[targetTiddlers[t],template]),
store); store);
m.execute(macroNode.parents,store.getTiddler(targetTiddlers[t])); m.execute(macroNode.parents,store.getTiddler(targetTiddlers[t]));
m.renderInDom(macroNode.domNode,macroNode.domNode.childNodes[t]); m.renderInDom(macroNode.domNode,macroNode.domNode.childNodes[t]);

View File

@@ -34,7 +34,6 @@ exports.macro = {
var link = Renderer.MacroNode("link", var link = Renderer.MacroNode("link",
{target: v}, {target: v},
[Renderer.TextNode(v)], [Renderer.TextNode(v)],
new Dependencies([v]),
store); store);
link.execute(parents,tiddler); link.execute(parents,tiddler);
return [link]; return [link];