mirror of
				https://github.com/Jermolene/TiddlyWiki5
				synced 2025-10-31 15:42:59 +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) { | ||||
| }; | ||||
|  | ||||
| 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 { | ||||
| 		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.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;	 | ||||
| 	// 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 = this.paramFn(tiddler,this.store,utils); | ||||
| 			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(); | ||||
| }; | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -48,7 +48,6 @@ exports.macro = { | ||||
| 												"tiddler", | ||||
| 												{target: target}, | ||||
| 												null, | ||||
| 												new Dependencies([],[target]), | ||||
| 												store) | ||||
| 										]); | ||||
| 			content.execute(macroNode.parents,tiddler); | ||||
|   | ||||
| @@ -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]); | ||||
|   | ||||
| @@ -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]; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jeremy Ruston
					Jeremy Ruston