mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-19 16:24:51 +00:00
Introduce genesis widget for dynamically creating widgets
See the "RedefineLet" test for a contrived example of usage
This commit is contained in:
parent
e1df50d981
commit
56c2242e4e
100
core/modules/widgets/genesis.js
Normal file
100
core/modules/widgets/genesis.js
Normal file
@ -0,0 +1,100 @@
|
||||
/*\
|
||||
title: $:/core/modules/widgets/genesis.js
|
||||
type: application/javascript
|
||||
module-type: widget
|
||||
|
||||
Genesis widget for dynamically creating widgets
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||
|
||||
var GenesisWidget = function(parseTreeNode,options) {
|
||||
this.initialise(parseTreeNode,options);
|
||||
};
|
||||
|
||||
/*
|
||||
Inherit from the base widget class
|
||||
*/
|
||||
GenesisWidget.prototype = new Widget();
|
||||
|
||||
/*
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
GenesisWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
this.renderChildren(parent,nextSibling);
|
||||
};
|
||||
|
||||
/*
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
GenesisWidget.prototype.execute = function() {
|
||||
var self = this;
|
||||
// Collect attributes
|
||||
this.genesisType = this.getAttribute("$type","element");
|
||||
this.genesisTag = this.getAttribute("$tag","div");
|
||||
this.genesisNames = this.getAttribute("$names","");
|
||||
this.genesisValues = this.getAttribute("$values","");
|
||||
// Construct parse tree
|
||||
var parseTreeNodes = [{
|
||||
type: this.genesisType,
|
||||
tag: this.genesisTag,
|
||||
attributes: {},
|
||||
orderedAttributes: [],
|
||||
children: this.parseTreeNode.children || []
|
||||
}];
|
||||
// Apply attributes in $names/$values
|
||||
this.attributeNames = [];
|
||||
this.attributeValues = [];
|
||||
if(this.genesisNames && this.genesisValues) {
|
||||
this.attributeNames = this.wiki.filterTiddlers(self.genesisNames,this);
|
||||
this.attributeValues = this.wiki.filterTiddlers(self.genesisValues,this);
|
||||
$tw.utils.each(this.attributeNames,function(varname,index) {
|
||||
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],varname,self.attributeValues[index] || "");
|
||||
});
|
||||
}
|
||||
// Apply explicit attributes
|
||||
$tw.utils.each(this.attributes,function(value,name) {
|
||||
if(name.charAt(0) === "$") {
|
||||
if(name.charAt(1) === "$") {
|
||||
// Double $$ is changed to a single $
|
||||
name = name.substr(1);
|
||||
} else {
|
||||
// Single dollar is ignored
|
||||
return;
|
||||
}
|
||||
}
|
||||
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],name,value);
|
||||
});
|
||||
// Construct the child widgets
|
||||
this.makeChildWidgets(parseTreeNodes);
|
||||
};
|
||||
|
||||
/*
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
GenesisWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes(),
|
||||
filterNames = this.getAttribute("$names",""),
|
||||
filterValues = this.getAttribute("$values",""),
|
||||
attributeNames = this.wiki.filterTiddlers(filterNames,this),
|
||||
attributeValues = this.wiki.filterTiddlers(filterValues,this);
|
||||
if($tw.utils.count(changedAttributes) > 0 || !$tw.utils.isArrayEqual(this.attributeNames,attributeNames) || !$tw.utils.isArrayEqual(this.attributeValues,attributeValues)) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
} else {
|
||||
return this.refreshChildren(changedTiddlers);
|
||||
}
|
||||
};
|
||||
|
||||
exports.genesis = GenesisWidget;
|
||||
|
||||
})();
|
@ -0,0 +1,14 @@
|
||||
title: Genesis/DollarSigns
|
||||
description: Usage of genesis widget with attributes starting with dollar signs
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
<$genesis $type="let" myvar="Kitten">(<$text text=<<myvar>>/>)</$genesis>
|
||||
<$genesis $type="let" $$myvar="Kitten">(<$text text=<<$myvar>>/>)</$genesis>
|
||||
_
|
||||
title: ExpectedResult
|
||||
|
||||
<p>(Kitten)(Kitten)</p>
|
@ -0,0 +1,14 @@
|
||||
title: Genesis/MultipleAttributes
|
||||
description: Usage of genesis widget with multiple attributes
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
<$genesis $type="let" $names="myvar other" $values="Kitten Donkey" myvar="Shark">(<$text text=<<myvar>>/>|<$text text=<<other>>/>)</$genesis>
|
||||
<$genesis $type="let" $names="$myvar $other" $values="Kitten Donkey" $$myvar="Shark">(<$text text=<<$myvar>>/>|<$text text=<<$other>>/>)</$genesis>
|
||||
_
|
||||
title: ExpectedResult
|
||||
|
||||
<p>(Shark|Donkey)(Shark|Donkey)</p>
|
@ -0,0 +1,33 @@
|
||||
title: Genesis/RedefineLet
|
||||
description: Using the genesis widget to override the let widget
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
\function <$let>
|
||||
\whitespace trim
|
||||
<$setmultiplevariables $names="[enlist<paramNames>]" $values="[enlist<paramValues>addprefix[--]addsuffix[--]]">
|
||||
<$slot $name="ts-body"/>
|
||||
</$setmultiplevariables>
|
||||
\end
|
||||
<$let
|
||||
one="Elephant"
|
||||
$two="Kangaroo"
|
||||
$$three="Giraffe"
|
||||
>
|
||||
(<$text text=<<one>>/>)
|
||||
(<$text text=<<$two>>/>)
|
||||
(<$text text=<<$$three>>/>)
|
||||
</$let>
|
||||
_
|
||||
title: Definition
|
||||
|
||||
\whitespace trim
|
||||
_
|
||||
title: ExpectedResult
|
||||
|
||||
<p>(--Elephant--)
|
||||
(--Kangaroo--)
|
||||
(--Giraffe--)</p>
|
14
editions/test/tiddlers/tests/data/genesis-widget/Simple.tid
Normal file
14
editions/test/tiddlers/tests/data/genesis-widget/Simple.tid
Normal file
@ -0,0 +1,14 @@
|
||||
title: Genesis/Simple
|
||||
description: Simple usage of genesis widget
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
<$genesis $tag="div">Mouse</$genesis>
|
||||
<$genesis $tag="div" class="tc-thing" label="Squeak">Mouse</$genesis>
|
||||
_
|
||||
title: ExpectedResult
|
||||
|
||||
<p><div>Mouse</div><div class="tc-thing" label="Squeak">Mouse</div></p>
|
34
editions/tw5.com/tiddlers/widgets/GenesisWidget.tid
Normal file
34
editions/tw5.com/tiddlers/widgets/GenesisWidget.tid
Normal file
@ -0,0 +1,34 @@
|
||||
caption: genesis
|
||||
created: 20220502144738010
|
||||
modified: 20220502144738010
|
||||
tags: Widgets
|
||||
title: GenesisWidget
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
! Introduction
|
||||
|
||||
<<.from-version "5.2.3">> The genesis widget allows the dynamic construction of widgets, where the name and attributes of the widget can be dynamically determined, and do not need to be known in advance.
|
||||
|
||||
! Content and Attributes
|
||||
|
||||
The content of the `<$genesis>` widget is used as the content of the dynamically created widget.
|
||||
|
||||
|!Attribute |!Description |
|
||||
|$type |The type of widget to create |
|
||||
|$tag |The HTML tag to be used for "element" widgets |
|
||||
|$names |An optional filter evaluating to the names of a list of variables to be applied to the widget |
|
||||
|$values |An optional filter evaluating to the values corresponding to the list of names specified in `$names` |
|
||||
|//{other attributes starting with $}// |Other attributes starting with a single dollar sign are reserved for future use |
|
||||
|//{attributes starting with $$}// |Attributes starting with two dollar signs are appplied as attributes to the output widget, but with the attribute name changed to use a single dollar sign |
|
||||
|//{attributes not starting with $}// |Any other attributes that do not start with a dollar are applied as attributes to the output widget |
|
||||
|
||||
Note that attributes explicitly specified take precedence over attributes with the same name specified in the `$names` filter.
|
||||
|
||||
! Examples
|
||||
|
||||
<$macrocall $name='wikitext-example-without-html'
|
||||
src='<$set name="myTiddler" value="HelloThere">
|
||||
<$set name="myVariable" tiddler=<<myTiddler>> field={{$:/docs/anyField!!field}}>
|
||||
<$text text=<<myVariable>>/>
|
||||
</$set>
|
||||
</$set>'/>
|
Loading…
Reference in New Issue
Block a user