mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-12-24 17:10:29 +00:00
Refactor $parameters widget
The objective is to add a $depth attribute so that it is possible to reach up to retrieve the parameters of ancestor transclusions. However, doing so requires changing the encoding of parameter names so that it is not possible for a user parameter to clash with an attribute like $depth. So now we have to double up dollars on any attribute names seen by the parameters widget, just like with the transclude widget itself.
This commit is contained in:
parent
150266c731
commit
006ae6e759
@ -40,8 +40,13 @@ exports.parse = function() {
|
||||
var attributes = Object.create(null),
|
||||
orderedAttributes = [];
|
||||
$tw.utils.each(params,function(param) {
|
||||
var attribute = {name: param.name, type: "string", value: param["default"] || ""};
|
||||
attributes[param.name] = attribute;
|
||||
var name = param.name;
|
||||
// Parameter names starting with dollar must be escaped to double dollars for the parameters widget
|
||||
if(name.charAt(0) === "$") {
|
||||
name = "$" + name;
|
||||
}
|
||||
var attribute = {name: name, type: "string", value: param["default"] || ""};
|
||||
attributes[name] = attribute;
|
||||
orderedAttributes.push(attribute);
|
||||
});
|
||||
// Save the macro definition
|
||||
|
@ -42,21 +42,41 @@ Compute the internal state of the widget
|
||||
*/
|
||||
ParametersWidget.prototype.execute = function() {
|
||||
var self = this;
|
||||
// Find the parent transclusion
|
||||
var transclusionWidget = this.parentWidget;
|
||||
while(transclusionWidget && !(transclusionWidget instanceof TranscludeWidget)) {
|
||||
transclusionWidget = transclusionWidget.parentWidget;
|
||||
this.parametersDepth = parseInt(this.getAttribute("$depth","1"),10) || 1;
|
||||
// Find the parent transclusions
|
||||
var pointer = this.parentWidget,
|
||||
depth = this.parametersDepth;
|
||||
while(pointer) {
|
||||
if(pointer instanceof TranscludeWidget) {
|
||||
depth--;
|
||||
if(depth === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
pointer = pointer.parentWidget;
|
||||
}
|
||||
// Process each parameter
|
||||
if(transclusionWidget) {
|
||||
if(pointer instanceof TranscludeWidget) {
|
||||
// Get the value for each defined parameter
|
||||
$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(self.parseTreeNode),function(attr,index) {
|
||||
var name = attr.name,
|
||||
value = transclusionWidget.getTransclusionParameter(name,index,self.getAttribute(name,""));
|
||||
self.setVariable(name,value);
|
||||
});
|
||||
$tw.utils.each(transclusionWidget.getTransclusionMetaVariables(),function(value,name) {
|
||||
var name = attr.name;
|
||||
// If the attribute name starts with $$ then reduce to a single dollar
|
||||
if(name.substr(0,2) === "$$") {
|
||||
name = name.substr(1);
|
||||
}
|
||||
var value = pointer.getTransclusionParameter(name,index,self.getAttribute(attr.name,""));
|
||||
self.setVariable(name,value);
|
||||
});
|
||||
// Assign any metaparameters
|
||||
var assignMetaParameter = function(name) {
|
||||
var variableName = self.getAttribute("$" + name);
|
||||
if(variableName !== undefined) {
|
||||
self.setVariable(variableName,pointer.getTransclusionMetaParameter(name));
|
||||
}
|
||||
};
|
||||
assignMetaParameter("parseAsInline");
|
||||
assignMetaParameter("parseTreeNodes");
|
||||
assignMetaParameter("params");
|
||||
}
|
||||
// Construct the child widgets
|
||||
this.makeChildWidgets();
|
||||
|
@ -198,7 +198,12 @@ TranscludeWidget.prototype.getTransclusionTarget = function() {
|
||||
type: parser.type
|
||||
}
|
||||
$tw.utils.each(srcVariable.params,function(param) {
|
||||
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],param.name,param["default"])
|
||||
var name = param.name;
|
||||
// Parameter names starting with dollar must be escaped to double dollars
|
||||
if(name.charAt(0) === "$") {
|
||||
name = "$" + name;
|
||||
}
|
||||
$tw.utils.addAttributeToParseTreeNode(parser.tree[0],name,param["default"])
|
||||
});
|
||||
} else {
|
||||
// For macros and ordinary variables, wrap the parse tree in a vars widget assigning the parameters to variables named "__paramname__"
|
||||
@ -299,14 +304,19 @@ TranscludeWidget.prototype.getTransclusionParameter = function(name,index,defaul
|
||||
};
|
||||
|
||||
/*
|
||||
Get a hashmap of the special variables to be provided by the parameters widget
|
||||
Get one of the special parameters to be provided by the parameters widget
|
||||
*/
|
||||
TranscludeWidget.prototype.getTransclusionMetaVariables = function() {
|
||||
var variables = {
|
||||
"@parseAsInline": this.parseAsInline ? "yes" : "no",
|
||||
"@params": JSON.stringify(this.stringParametersByName)
|
||||
};
|
||||
return variables;
|
||||
TranscludeWidget.prototype.getTransclusionMetaParameter = function(name) {
|
||||
switch(name) {
|
||||
case "parseAsInline":
|
||||
return this.parseAsInline ? "yes" : "no";
|
||||
case "parseTreeNodes":
|
||||
return JSON.stringify(this.parseTreeNode);
|
||||
case "params":
|
||||
return JSON.stringify(this.stringParametersByName);
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -5,41 +5,44 @@ Import this component to make all the child transclusions visible.
|
||||
|
||||
Block transclusions are shown in red, and inline transclusions are shown in green.
|
||||
-->
|
||||
\widget $transclude(tiddler,$tiddler,mode,$mode)
|
||||
<!-- Replicate the logic of the transclude widget to determine the output mode, and hence the tag and colour to use for output -->
|
||||
<$let
|
||||
mode={{{ [[$mode]is[variable]then<$mode>!is[blank]] :else[[mode]is[variable]then<mode>!is[blank]] :else[<parseAsInline>match[yes]then[inline]else[block]] }}}
|
||||
outputTag={{{ [<mode>match[inline]then[span]else[div]] }}}
|
||||
outputColour={{{ [<mode>match[inline]then[green]else[red]] }}}
|
||||
>
|
||||
<!-- Use divs or spans according to the mode -->
|
||||
<$genesis $type="element" $tag=<<outputTag>> style="color:white;padding:4px;" style.background=<<outputColour>>>
|
||||
<$genesis $type="element" $tag=<<outputTag>> style="display: inline-block;">
|
||||
<div style="background:white;color:black;font-size: 12px;line-height:1.2;text-align:left;font-weight:normal;padding:4px;margin:4px;">
|
||||
<!-- Render the parameters to the transclusion -->
|
||||
<$list filter="[<@params>jsonindexes[]]" emptyMessage="(none)">
|
||||
<div>
|
||||
<$text text=<<currentTiddler>>/><$text text=": "/><$text text={{{ [<@params>jsonget<currentTiddler>] }}}/>
|
||||
</div>
|
||||
\widget $transclude
|
||||
<!-- Use a parameters widget so that we can access the `$params` data -->
|
||||
<$parameters tiddler="" $$tiddler="" mode="" $$mode="" $params="@params">
|
||||
<!-- Replicate the logic of the transclude widget to determine the output mode, and hence the tag and colour to use for output -->
|
||||
<$let
|
||||
mode={{{ [[$mode]is[variable]then<$mode>!is[blank]] :else[[mode]is[variable]then<mode>!is[blank]] :else[<parseAsInline>match[yes]then[inline]else[block]] }}}
|
||||
outputTag={{{ [<mode>match[inline]then[span]else[div]] }}}
|
||||
outputColour={{{ [<mode>match[inline]then[green]else[red]] }}}
|
||||
>
|
||||
<!-- Use divs or spans according to the mode -->
|
||||
<$genesis $type="element" $tag=<<outputTag>> style="color:white;padding:4px;" style.background=<<outputColour>>>
|
||||
<$genesis $type="element" $tag=<<outputTag>> style="display: inline-block;">
|
||||
<div style="background:white;color:black;font-size: 12px;line-height:1.2;text-align:left;font-weight:normal;padding:4px;margin:4px;">
|
||||
<!-- Render the parameters to the transclusion -->
|
||||
<$list filter="[<@params>jsonindexes[]]" emptyMessage="(none)">
|
||||
<div>
|
||||
<$text text=<<currentTiddler>>/><$text text=": "/><$text text={{{ [<@params>jsonget<currentTiddler>] }}}/>
|
||||
</div>
|
||||
</$list>
|
||||
</div>
|
||||
</$genesis>
|
||||
<$genesis $type="element" $tag=<<outputTag>> style="background:white;color:black;padding:4px;">
|
||||
<!-- Look for a parameter starting with $ to determine if we are in legacy mode -->
|
||||
<$list filter="[<@params>jsonindexes[]] :filter[<currentTiddler>prefix[$]] +[limit[1]]" variable="ignore" emptyMessage="""
|
||||
<!-- Legacy mode: we render the transclusion without a dollar sign for recursionMarker and mode -->
|
||||
<$genesis $type="transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" recursionMarker="no" mode=<<mode>>>
|
||||
<!-- Reach back up to the grandparent transclusion to get the correct slot value -->
|
||||
<$slot $name="ts-raw" $depth="2"/>
|
||||
</$genesis>
|
||||
""">
|
||||
<!-- Non-legacy mode: we use dollar signs for the recursionMarker and mode -->
|
||||
<$genesis $type="transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" $$recursionMarker="no" $$mode=<<mode>>>
|
||||
<!-- Reach back up to the grandparent transclusion to get the correct slot fill value -->
|
||||
<$slot $name="ts-raw" $depth="2"/>
|
||||
</$genesis>
|
||||
</$list>
|
||||
</div>
|
||||
</$genesis>
|
||||
</$genesis>
|
||||
<$genesis $type="element" $tag=<<outputTag>> style="background:white;color:black;padding:4px;">
|
||||
<!-- Look for a parameter starting with $ to determine if we are in legacy mode -->
|
||||
<$list filter="[<@params>jsonindexes[]] :filter[<currentTiddler>prefix[$]] +[limit[1]]" variable="ignore" emptyMessage="""
|
||||
<!-- Legacy mode: we render the transclusion without a dollar sign for recursionMarker and mode -->
|
||||
<$genesis $type="transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" recursionMarker="no" mode=<<mode>>>
|
||||
<!-- Reach back up to the grandparent transclusion to get the correct slot value -->
|
||||
<$slot $name="ts-raw" $depth="2"/>
|
||||
</$genesis>
|
||||
""">
|
||||
<!-- Non-legacy mode: we use dollar signs for the recursionMarker and mode -->
|
||||
<$genesis $type="transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>]" $$recursionMarker="no" $$mode=<<mode>>>
|
||||
<!-- Reach back up to the grandparent transclusion to get the correct slot fill value -->
|
||||
<$slot $name="ts-raw" $depth="2"/>
|
||||
</$genesis>
|
||||
</$list>
|
||||
</$genesis>
|
||||
</$genesis>
|
||||
<$let>
|
||||
</$let>
|
||||
</$parameters>
|
||||
\end
|
||||
|
@ -8,9 +8,11 @@ title: Output
|
||||
\whitespace trim
|
||||
\widget $let
|
||||
\whitespace trim
|
||||
<$parameters $params="@params">
|
||||
<$setmultiplevariables $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget<currentTiddler>addprefix[--]addsuffix[--]]">
|
||||
<$slot $name="ts-body"/>
|
||||
</$setmultiplevariables>
|
||||
</$parameters>
|
||||
\end
|
||||
<$let
|
||||
one="Elephant"
|
||||
|
@ -0,0 +1,34 @@
|
||||
title: Transclude/Parameterised/Depth
|
||||
description: Parameterised transclusion using the $depth attribute
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
<$transclude $tiddler='TiddlerOne' one='Ferret'/>
|
||||
|
|
||||
<$transclude $tiddler='TiddlerOne'/>
|
||||
|
|
||||
<$transclude $tiddler='TiddlerOne' one='Ferret' $$two="Osprey"/>
|
||||
|
|
||||
<$transclude $tiddler='TiddlerOne' $$two="Falcon"/>
|
||||
+
|
||||
title: TiddlerOne
|
||||
|
||||
\whitespace trim
|
||||
{{TiddlerTwo}}
|
||||
+
|
||||
title: TiddlerTwo
|
||||
|
||||
\whitespace trim
|
||||
<$parameters one='Jaguar' $$two='Piranha' $depth="2">
|
||||
<$text text=<<one>>/>:<$text text=<<$two>>/>
|
||||
</$parameters>
|
||||
<$parameters one='Leopard' $$two='Coelacanth'>
|
||||
(<$text text=<<one>>/>|<$text text=<<$two>>/>)
|
||||
</$parameters>
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>Ferret:Piranha(Leopard|Coelacanth)|Jaguar:Piranha(Leopard|Coelacanth)|Ferret:Osprey(Leopard|Coelacanth)|Jaguar:Falcon(Leopard|Coelacanth)</p>
|
@ -17,17 +17,18 @@ title: Output
|
||||
title: TiddlerOne
|
||||
|
||||
\whitespace trim
|
||||
\parameters(zero:'Jaguar',one:'Lizard',two:'Mole')
|
||||
<$parameters zero='Jaguar' $$one='Lizard' two='Mole' $params="@params">
|
||||
<$list filter="[<@params>jsonindexes[]]">
|
||||
{<$text text=<<currentTiddler>>/>: <$text text={{{ [<@params>jsonget<currentTiddler>] }}}/>}
|
||||
</$list>
|
||||
</$parameters>
|
||||
+
|
||||
title: TiddlerTwo
|
||||
|
||||
\whitespace trim
|
||||
\parameters(zero:'Mouse',one:'Horse',two:'Owl')
|
||||
(<$transclude $tiddler=<<currentTiddler>> zero=<<zero>> one=<<one>> two=<<two>>/>)
|
||||
\parameters(zero:'Mouse',$one:'Horse',two:'Owl')
|
||||
(<$transclude $tiddler=<<currentTiddler>> zero=<<zero>> $$one=<<$one>> two=<<two>>/>)
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>{0:}{1:}{2:}</p><p></p><p>{0:Ferret}</p><p>{0:Butterfly}{1:Moth}</p><p>{0:Beetle}{1:Scorpion}{2:Snake}</p><p>({one:Scorpion}{two:Snake}{zero:Beetle})</p>
|
||||
<p>{0:}{1:}{2:}</p><p></p><p>{0:Ferret}</p><p>{0:Butterfly}{1:Moth}</p><p>{0:Beetle}{1:Scorpion}{2:Snake}</p><p>({$one:Scorpion}{two:Snake}{zero:Beetle})</p>
|
@ -7,15 +7,20 @@ title: Output
|
||||
|
||||
\whitespace trim
|
||||
<$transclude $tiddler='TiddlerOne' one='Ferret'/>
|
||||
|
|
||||
<$transclude $tiddler='TiddlerOne'/>
|
||||
|
|
||||
<$transclude $tiddler='TiddlerOne' one='Ferret' $$two="Osprey"/>
|
||||
|
|
||||
<$transclude $tiddler='TiddlerOne' $$two="Falcon"/>
|
||||
+
|
||||
title: TiddlerOne
|
||||
|
||||
\whitespace trim
|
||||
<$parameters one='Jaguar'>
|
||||
<$text text=<<one>>/>
|
||||
<$parameters one='Jaguar' $$two='Piranha'>
|
||||
<$text text=<<one>>/>:<$text text=<<$two>>/>
|
||||
</$parameters>
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>FerretJaguar</p>
|
||||
<p>Ferret:Piranha|Jaguar:Piranha|Ferret:Osprey|Jaguar:Falcon</p>
|
Loading…
Reference in New Issue
Block a user