1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-06-25 06:43:15 +00:00

Change "index" attribute of list widget to "counter", and use 1-based counting

Extends #5611
This commit is contained in:
jeremy@jermolene.com 2021-04-26 14:41:26 +01:00
parent e2379b599e
commit 4a99e0cc7d
3 changed files with 27 additions and 27 deletions

View File

@ -61,7 +61,7 @@ ListWidget.prototype.execute = function() {
this.template = this.getAttribute("template"); this.template = this.getAttribute("template");
this.editTemplate = this.getAttribute("editTemplate"); this.editTemplate = this.getAttribute("editTemplate");
this.variableName = this.getAttribute("variable","currentTiddler"); this.variableName = this.getAttribute("variable","currentTiddler");
this.indexName = this.getAttribute("index"); this.counterName = this.getAttribute("counter");
this.storyViewName = this.getAttribute("storyview"); this.storyViewName = this.getAttribute("storyview");
this.historyTitle = this.getAttribute("history"); this.historyTitle = this.getAttribute("history");
// Compose the list elements // Compose the list elements
@ -130,9 +130,9 @@ ListWidget.prototype.makeItemTemplate = function(title,index) {
} }
// Return the list item // Return the list item
var parseTreeNode = {type: "listitem", itemTitle: title, variableName: this.variableName, children: templateTree}; var parseTreeNode = {type: "listitem", itemTitle: title, variableName: this.variableName, children: templateTree};
if(this.indexName) { if(this.counterName) {
parseTreeNode.index = index.toString(); parseTreeNode.counter = (index + 1).toString();
parseTreeNode.indexName = this.indexName; parseTreeNode.counterName = this.counterName;
parseTreeNode.isFirst = index === 0; parseTreeNode.isFirst = index === 0;
parseTreeNode.isLast = index === this.list.length - 1; parseTreeNode.isLast = index === this.list.length - 1;
} }
@ -150,7 +150,7 @@ ListWidget.prototype.refresh = function(changedTiddlers) {
this.storyview.refreshStart(changedTiddlers,changedAttributes); this.storyview.refreshStart(changedTiddlers,changedAttributes);
} }
// Completely refresh if any of our attributes have changed // Completely refresh if any of our attributes have changed
if(changedAttributes.filter || changedAttributes.variable || changedAttributes.index || changedAttributes.template || changedAttributes.editTemplate || changedAttributes.emptyMessage || changedAttributes.storyview || changedAttributes.history) { if(changedAttributes.filter || changedAttributes.variable || changedAttributes.counter || changedAttributes.template || changedAttributes.editTemplate || changedAttributes.emptyMessage || changedAttributes.storyview || changedAttributes.history) {
this.refreshSelf(); this.refreshSelf();
result = true; result = true;
} else { } else {
@ -219,9 +219,9 @@ ListWidget.prototype.handleListChanges = function(changedTiddlers) {
this.removeChildDomNodes(); this.removeChildDomNodes();
this.children = []; this.children = [];
} }
// If we are providing an index variable then we must refresh the items, otherwise we can rearrange them // If we are providing an counter variable then we must refresh the items, otherwise we can rearrange them
var hasRefreshed = false,t; var hasRefreshed = false,t;
if(this.indexName) { if(this.counterName) {
// Cycle through the list and remove and re-insert the first item that has changed, and all the remaining items // Cycle through the list and remove and re-insert the first item that has changed, and all the remaining items
for(t=0; t<this.list.length; t++) { for(t=0; t<this.list.length; t++) {
if(hasRefreshed || !this.children[t] || this.children[t].parseTreeNode.itemTitle !== this.list[t]) { if(hasRefreshed || !this.children[t] || this.children[t].parseTreeNode.itemTitle !== this.list[t]) {
@ -337,10 +337,10 @@ Compute the internal state of the widget
ListItemWidget.prototype.execute = function() { ListItemWidget.prototype.execute = function() {
// Set the current list item title // Set the current list item title
this.setVariable(this.parseTreeNode.variableName,this.parseTreeNode.itemTitle); this.setVariable(this.parseTreeNode.variableName,this.parseTreeNode.itemTitle);
if(this.parseTreeNode.indexName) { if(this.parseTreeNode.counterName) {
this.setVariable(this.parseTreeNode.indexName,this.parseTreeNode.index); this.setVariable(this.parseTreeNode.counterName,this.parseTreeNode.counter);
this.setVariable(this.parseTreeNode.indexName + "-first",this.parseTreeNode.isFirst ? "yes" : "no"); this.setVariable(this.parseTreeNode.counterName + "-first",this.parseTreeNode.isFirst ? "yes" : "no");
this.setVariable(this.parseTreeNode.indexName + "-last",this.parseTreeNode.isLast ? "yes" : "no"); this.setVariable(this.parseTreeNode.counterName + "-last",this.parseTreeNode.isLast ? "yes" : "no");
} }
// Construct the child widgets // Construct the child widgets
this.makeChildWidgets(); this.makeChildWidgets();

View File

@ -351,7 +351,7 @@ describe("Widget module", function() {
}); });
it("should deal with the list widget using an index variable", function() { it("should deal with the list widget using a counter variable", function() {
var wiki = new $tw.Wiki(); var wiki = new $tw.Wiki();
// Add some tiddlers // Add some tiddlers
wiki.addTiddlers([ wiki.addTiddlers([
@ -361,12 +361,12 @@ describe("Widget module", function() {
{title: "TiddlerFour", text: "Lemon Squash"} {title: "TiddlerFour", text: "Lemon Squash"}
]); ]);
// Construct the widget node // Construct the widget node
var text = "<$list index='index'><$view field='text'/><$text text=<<index>>/><$text text=<<index-first>>/><$text text=<<index-last>>/></$list>"; var text = "<$list counter='index'><$view field='text'/><$text text=<<index>>/><$text text=<<index-first>>/><$text text=<<index-last>>/></$list>";
var widgetNode = createWidgetNode(parseText(text,wiki),wiki); var widgetNode = createWidgetNode(parseText(text,wiki),wiki);
// Render the widget node to the DOM // Render the widget node to the DOM
var wrapper = renderWidgetNode(widgetNode); var wrapper = renderWidgetNode(widgetNode);
// Test the rendering // Test the rendering
expect(wrapper.innerHTML).toBe("<p>Lemon Squash0yesnoJolly Old World1nonoGolly Gosh2nonoWorldly Old Jelly3noyes</p>"); expect(wrapper.innerHTML).toBe("<p>Lemon Squash1yesnoJolly Old World2nonoGolly Gosh3nonoWorldly Old Jelly4noyes</p>");
// Test the sequence numbers in the DOM // Test the sequence numbers in the DOM
expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.sequenceNumber).toBe(0);
expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].sequenceNumber).toBe(1);
@ -391,7 +391,7 @@ describe("Widget module", function() {
// Refresh // Refresh
refreshWidgetNode(widgetNode,wrapper,["TiddlerFive"]); refreshWidgetNode(widgetNode,wrapper,["TiddlerFive"]);
// Test the refreshing // Test the refreshing
expect(wrapper.innerHTML).toBe("<p>Jalapeno Peppers0yesnoLemon Squash1nonoJolly Old World2nonoGolly Gosh3nonoWorldly Old Jelly4noyes</p>"); expect(wrapper.innerHTML).toBe("<p>Jalapeno Peppers1yesnoLemon Squash2nonoJolly Old World3nonoGolly Gosh4nonoWorldly Old Jelly5noyes</p>");
// Test the sequence numbers in the DOM // Test the sequence numbers in the DOM
expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.sequenceNumber).toBe(0);
expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].sequenceNumber).toBe(1);
@ -420,7 +420,7 @@ describe("Widget module", function() {
// Refresh // Refresh
refreshWidgetNode(widgetNode,wrapper,["TiddlerThree"]); refreshWidgetNode(widgetNode,wrapper,["TiddlerThree"]);
// Test the refreshing // Test the refreshing
expect(wrapper.innerHTML).toBe("<p>Jalapeno Peppers0yesnoLemon Squash1nonoJolly Old World2nonoWorldly Old Jelly3noyes</p>"); expect(wrapper.innerHTML).toBe("<p>Jalapeno Peppers1yesnoLemon Squash2nonoJolly Old World3nonoWorldly Old Jelly4noyes</p>");
// Test the sequence numbers in the DOM // Test the sequence numbers in the DOM
expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.sequenceNumber).toBe(0);
expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].sequenceNumber).toBe(1);
@ -445,7 +445,7 @@ describe("Widget module", function() {
// Refresh // Refresh
refreshWidgetNode(widgetNode,wrapper,["TiddlerThree"]); refreshWidgetNode(widgetNode,wrapper,["TiddlerThree"]);
// Test the refreshing // Test the refreshing
expect(wrapper.innerHTML).toBe("<p>Jalapeno Peppers0yesnoLemon Squash1nonoJolly Old World2nonoSomething3nonoWorldly Old Jelly4noyes</p>"); expect(wrapper.innerHTML).toBe("<p>Jalapeno Peppers1yesnoLemon Squash2nonoJolly Old World3nonoSomething4nonoWorldly Old Jelly5noyes</p>");
// Test the sequence numbers in the DOM // Test the sequence numbers in the DOM
expect(wrapper.sequenceNumber).toBe(0); expect(wrapper.sequenceNumber).toBe(0);
expect(wrapper.children[0].sequenceNumber).toBe(1); expect(wrapper.children[0].sequenceNumber).toBe(1);

View File

@ -82,27 +82,27 @@ The action of the list widget depends on the results of the filter combined with
|template |The title of a template tiddler for transcluding each tiddler in the list. When no template is specified, the body of the ListWidget serves as the item template. With no body, a simple link to the tiddler is returned. | |template |The title of a template tiddler for transcluding each tiddler in the list. When no template is specified, the body of the ListWidget serves as the item template. With no body, a simple link to the tiddler is returned. |
|editTemplate |An alternative template to use for [[DraftTiddlers|DraftMechanism]] in edit mode | |editTemplate |An alternative template to use for [[DraftTiddlers|DraftMechanism]] in edit mode |
|variable |The name for a [[variable|Variables]] in which the title of each listed tiddler is stored. Defaults to ''currentTiddler'' | |variable |The name for a [[variable|Variables]] in which the title of each listed tiddler is stored. Defaults to ''currentTiddler'' |
|index |<<.from-version "5.1.24">> Optional name for a [[variable|Variables]] in which the numeric index of each listed tiddler is stored (see below) | |counter |<<.from-version "5.1.24">> Optional name for a [[variable|Variables]] in which the 1-based numeric index of each listed tiddler is stored (see below) |
|emptyMessage |Message to be displayed when the list is empty | |emptyMessage |Message to be displayed when the list is empty |
|storyview |Optional name of module responsible for animating/processing the list | |storyview |Optional name of module responsible for animating/processing the list |
|history |The title of the tiddler containing the navigation history | |history |The title of the tiddler containing the navigation history |
!! `index` attribute !! `counter` attribute
The optional `index` attribute specifies the name of a variable to hold the numeric index of the current item in the list. The optional `counter` attribute specifies the name of a variable to hold the 1-based numeric index of the current item in the list.
Two additional variables are also set to indicate the first and last items in the list: Two additional variables are also set to indicate the first and last items in the list:
* `<index-variable-name>-first` is set to `yes` for the first entry in the list, `no` for the others * `<counter-variable-name>-first` is set to `yes` for the first entry in the list, `no` for the others
* `<index-variable-name>-last` is set to `yes` for the last entry in the list, `no` for the others * `<counter-variable-name>-last` is set to `yes` for the last entry in the list, `no` for the others
For example: For example:
``` ```
<$list filter="[tag[About]sort[title]]" index="index"> <$list filter="[tag[About]sort[title]]" counter="counter">
<div> <div>
<<index>>: ''<$text text=<<currentTiddler>>/>'' (is first: <<index-first>>, is last: <<index-last>>) <<counter>>: ''<$text text=<<currentTiddler>>/>'' (is first: <<counter-first>>, is last: <<counter-last>>)
</div> </div>
</$list> </$list>
``` ```
@ -110,14 +110,14 @@ For example:
Displays as: Displays as:
<<< <<<
<$list filter="[tag[About]sort[title]]" index="index"> <$list filter="[tag[About]sort[title]]" counter="counter">
<div> <div>
<<index>>: ''<$text text=<<currentTiddler>>/>'' (is first: <<index-first>>, is last: <<index-last>>) <<counter>>: ''<$text text=<<currentTiddler>>/>'' (is first: <<counter-first>>, is last: <<counter-last>>)
</div> </div>
</$list> </$list>
<<< <<<
Note that using the `index` attribute degrades the performance of the list widget because it prevents the optimisation of refreshes by moving list items around instead of rerendering them. Note that using the `counter` attribute degrades the performance of the list widget because it prevents the optimisation of refreshes by moving list items around instead of rerendering them.
!! Edit mode !! Edit mode