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:
@@ -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();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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]);
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
Reference in New Issue
Block a user