mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-12-28 11:00:27 +00:00
Refactor function evaluation code to avoid adding evaluateVariable method
Adding the new widget method was causing backwards compatibility issues. For example, see this discussion: https://talk.tiddlywiki.org/t/tw-v5-3-0-pre-problem-with-autocomplete-plugin/6958
This commit is contained in:
parent
98e72558d0
commit
cc383e6d1e
@ -269,7 +269,8 @@ exports.compileFilter = function(filterString) {
|
||||
operand.value = self.getTextReference(operand.text,"",currTiddlerTitle);
|
||||
} else if(operand.variable) {
|
||||
var varTree = $tw.utils.parseFilterVariable(operand.text);
|
||||
operand.value = widget.evaluateVariable(varTree.name,{params: varTree.params, source: source})[0] || "";
|
||||
var variableInfo = widget.getVariableInfo(varTree.name,{params: varTree.params, source: source});
|
||||
operand.value = (variableInfo.resultList ? variableInfo.resultList[0] : variableInfo.text) || "";
|
||||
} else {
|
||||
operand.value = operand.text;
|
||||
}
|
||||
|
@ -17,9 +17,13 @@ Export our filter function
|
||||
*/
|
||||
exports.function = function(source,operator,options) {
|
||||
var functionName = operator.operands[0],
|
||||
variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(functionName);
|
||||
params = [];
|
||||
$tw.utils.each(operator.operands.slice(1),function(param) {
|
||||
params.push({value: param});
|
||||
});
|
||||
var variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(functionName,{params: params, source: source});
|
||||
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
|
||||
return options.widget.evaluateVariable(functionName,{params: operator.operands.slice(1), source: source});
|
||||
return variableInfo.resultList ? variableInfo.resultList : [variableInfo.text];
|
||||
}
|
||||
// Return the input list if the function wasn't found
|
||||
var results = [];
|
||||
|
@ -22,9 +22,13 @@ Export our filter function
|
||||
exports["[unknown]"] = function(source,operator,options) {
|
||||
// Check for a user defined filter operator
|
||||
if(operator.operator.indexOf(".") !== -1) {
|
||||
var variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(operator.operator);
|
||||
if(variableInfo && variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
|
||||
var list = options.widget.evaluateVariable(operator.operator,{params: operator.operands, source: source});
|
||||
var params = [];
|
||||
$tw.utils.each(operator.operands,function(param) {
|
||||
params.push({value: param});
|
||||
});
|
||||
var variableInfo = options.widget && options.widget.getVariableInfo && options.widget.getVariableInfo(operator.operator,{params: params, source: source});
|
||||
if(variableInfo && variableInfo.srcVariable) {
|
||||
var list = variableInfo.resultList ? variableInfo.resultList : [variableInfo.text];
|
||||
if(operator.prefix === "!") {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
|
@ -179,22 +179,7 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
|
||||
if(variableInfo.text) {
|
||||
if(srcVariable.isFunctionDefinition) {
|
||||
// Function to return parameters by name or position
|
||||
var fnGetParam = function(name,index) {
|
||||
// Parameter names starting with dollar must be escaped to double dollars
|
||||
if(name.charAt(0) === "$") {
|
||||
name = "$" + name;
|
||||
}
|
||||
// Look for the parameter by name
|
||||
if(self.hasAttribute(name)) {
|
||||
return self.getAttribute(name);
|
||||
// Look for the parameter by index
|
||||
} else if(self.hasAttribute(index + "")) {
|
||||
return self.getAttribute(index + "");
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
result = this.evaluateVariable(this.transcludeVariable,{params: fnGetParam})[0] || "";
|
||||
var result = (variableInfo.resultList ? variableInfo.resultList[0] : variableInfo.text) || "";
|
||||
parser = {
|
||||
tree: [{
|
||||
type: "text",
|
||||
|
@ -112,14 +112,18 @@ Get the prevailing value of a context variable
|
||||
name: name of variable
|
||||
options: see below
|
||||
Options include
|
||||
|
||||
params: array of {name:, value:} for each parameter
|
||||
defaultValue: default value if the variable is not defined
|
||||
source: optional source iterator for evaluating function invocations
|
||||
allowSelfAssigned: if true, includes the current widget in the context chain instead of just the parent
|
||||
|
||||
Returns an object with the following fields:
|
||||
|
||||
params: array of {name:,value:} of parameters passed to wikitext variables
|
||||
params: array of {name:,value:} or {value:} of parameters to be applied
|
||||
text: text of variable, with parameters properly substituted
|
||||
resultList: result of variable evaluation as an array
|
||||
srcVariable: reference to the object defining the variable
|
||||
*/
|
||||
Widget.prototype.getVariableInfo = function(name,options) {
|
||||
options = options || {};
|
||||
@ -135,7 +139,8 @@ Widget.prototype.getVariableInfo = function(name,options) {
|
||||
if(variable) {
|
||||
var originalValue = variable.value,
|
||||
value = originalValue,
|
||||
params = [];
|
||||
params = [],
|
||||
resultList = [value];
|
||||
// Only substitute parameter and variable references if this variable was defined with the \define pragma
|
||||
if(variable.isMacroDefinition) {
|
||||
params = self.resolveVariableParameters(variable.params,actualParams);
|
||||
@ -144,10 +149,28 @@ Widget.prototype.getVariableInfo = function(name,options) {
|
||||
value = $tw.utils.replaceString(value,new RegExp("\\$" + $tw.utils.escapeRegExp(param.name) + "\\$","mg"),param.value);
|
||||
});
|
||||
value = self.substituteVariableReferences(value,options);
|
||||
resultList = [value];
|
||||
} else if(variable.isFunctionDefinition) {
|
||||
// Function evaluations
|
||||
params = self.resolveVariableParameters(variable.params,actualParams);
|
||||
var variables = Object.create(null);
|
||||
// Apply default parameter values
|
||||
$tw.utils.each(variable.params,function(param,index) {
|
||||
if(param["default"]) {
|
||||
variables[param.name] = param["default"];
|
||||
}
|
||||
});
|
||||
// Parameters are an array of {value:} or {name:, value:} pairs
|
||||
$tw.utils.each(params,function(param) {
|
||||
variables[param.name] = param.value;
|
||||
});
|
||||
resultList = this.wiki.filterTiddlers(value,this.makeFakeWidgetWithVariables(variables),options.source);
|
||||
value = resultList[0] || "";
|
||||
}
|
||||
return {
|
||||
text: value,
|
||||
params: params,
|
||||
resultList: resultList,
|
||||
srcVariable: variable,
|
||||
isCacheable: originalValue === value
|
||||
};
|
||||
@ -159,6 +182,7 @@ Widget.prototype.getVariableInfo = function(name,options) {
|
||||
}
|
||||
return {
|
||||
text: text,
|
||||
resultList: [text],
|
||||
srcVariable: {}
|
||||
};
|
||||
};
|
||||
@ -317,62 +341,11 @@ Widget.prototype.makeFakeWidgetWithVariables = function(variables) {
|
||||
};
|
||||
},
|
||||
makeFakeWidgetWithVariables: self.makeFakeWidgetWithVariables,
|
||||
evaluateVariable: self.evaluateVariable,
|
||||
resolveVariableParameters: self.resolveVariableParameters,
|
||||
wiki: self.wiki
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
Evaluate a variable and associated actual parameters and return the resulting array.
|
||||
The way that the variable is evaluated depends upon its type:
|
||||
* Functions are evaluated as parameterised filter strings
|
||||
* Macros are returned as plain text with substitution of parameters
|
||||
* Procedures and widgets are returned as plain text
|
||||
|
||||
Options are:
|
||||
params - the actual parameters – may be one of:
|
||||
* an array of values that may be an anonymous string value, or a {name:, value:} pair
|
||||
* a hashmap of {name: value} pairs
|
||||
* a function invoked with parameters (name,index) that returns a parameter value by name or position
|
||||
source - iterator for source tiddlers
|
||||
*/
|
||||
Widget.prototype.evaluateVariable = function(name,options) {
|
||||
options = options || {};
|
||||
var params = options.params || [];
|
||||
// Get the details of the variable (includes processing text substitution for macros
|
||||
var variableInfo = this.getVariableInfo(name,{params: params,defaultValue: ""});
|
||||
// Process function parameters
|
||||
var variables = Object.create(null);
|
||||
if(variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
|
||||
// Apply default parameter values
|
||||
$tw.utils.each(variableInfo.srcVariable.params,function(param,index) {
|
||||
if(param["default"]) {
|
||||
variables[param.name] = param["default"];
|
||||
}
|
||||
});
|
||||
if($tw.utils.isArray(params)) {
|
||||
// Parameters are an array of values or {name:, value:} pairs
|
||||
$tw.utils.each(this.resolveVariableParameters(variableInfo.srcVariable.params,params),function(param) {
|
||||
variables[param.name] = param.value;
|
||||
});
|
||||
} else if(typeof params === "function") {
|
||||
// Parameters are passed via a function
|
||||
$tw.utils.each(variableInfo.srcVariable.params,function(param,index) {
|
||||
variables[param.name] = params(param.name,index) || param["default"] || "";
|
||||
});
|
||||
} else {
|
||||
// Parameters are a hashmap
|
||||
$tw.utils.each(params,function(value,name) {
|
||||
variables[name] = value;
|
||||
});
|
||||
}
|
||||
return this.wiki.filterTiddlers(variableInfo.text,this.makeFakeWidgetWithVariables(variables),options.source);
|
||||
} else {
|
||||
return [variableInfo.text];
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Compute the current values of the attributes of the widget. Returns a hashmap of the names of the attributes that have changed.
|
||||
Options include:
|
||||
@ -406,13 +379,7 @@ Widget.prototype.computeAttribute = function(attribute) {
|
||||
value = this.wiki.getTextReference(attribute.textReference,"",this.getVariable("currentTiddler")) || "";
|
||||
} else if(attribute.type === "macro") {
|
||||
var variableInfo = this.getVariableInfo(attribute.value.name,{params: attribute.value.params});
|
||||
if(variableInfo.srcVariable && variableInfo.srcVariable.isFunctionDefinition) {
|
||||
// It is a function definition. Go through each of the defined parameters, and make a variable with the value of the corresponding provided parameter
|
||||
var paramArray = this.resolveVariableParameters(variableInfo.srcVariable.params,attribute.value.params);
|
||||
value = this.evaluateVariable(attribute.value.name,{params: paramArray})[0] || "";
|
||||
} else {
|
||||
value = variableInfo.text;
|
||||
}
|
||||
value = variableInfo.text;
|
||||
} else { // String attribute
|
||||
value = attribute.value;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user