From baca2703f11021649c2487e8247d0191e9257ddf Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Mon, 26 Jan 2015 13:39:04 +0100 Subject: [PATCH 01/16] added list suffix for each filter implements #1369 when the suffix is `list`, interprets the field as a list of individual tiddler titles and returns all titles referenced in the list field of the source list, existing or not --- core/modules/filters/each.js | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/core/modules/filters/each.js b/core/modules/filters/each.js index 591dfeae0..8126d5821 100644 --- a/core/modules/filters/each.js +++ b/core/modules/filters/each.js @@ -3,7 +3,8 @@ title: $:/core/modules/filters/each.js type: application/javascript module-type: filteroperator -Filter operator that selects one tiddler for each unique value of the specified field +Filter operator that selects one tiddler for each unique value of the specified field. +With suffix "list", selects all tiddlers that are values in a specified list field. \*/ (function(){ @@ -17,19 +18,23 @@ Export our filter function */ exports.each = function(source,operator,options) { var results = [], - values = {}; + values = {}, + list = "list" === operator.suffix; source(function(tiddler,title) { if(tiddler) { - var value; - if((operator.operand === "") || (operator.operand === "title")) { - value = title; - } else { - value = tiddler.getFieldString(operator.operand); - } - if(!$tw.utils.hop(values,value)) { - values[value] = true; - results.push(title); - } + var value, + field = operator.operand || "title"; + $tw.utils.each( + list ? + options.wiki.getTiddlerList(title,field) : + [ "title" === field ? title : tiddler.getFieldString(operator.operand)], + function(value){ + if(!$tw.utils.hop(values,value)) { + values[value] = true; + results.push(list ? value : title); + } + } + ) } }); return results; From f9464dfaf8151adfff3c028182236340fe267ce0 Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Mon, 26 Jan 2015 18:58:08 +0100 Subject: [PATCH 02/16] using variable declaration for readability --- core/modules/filters/each.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/modules/filters/each.js b/core/modules/filters/each.js index 8126d5821..7458eab2c 100644 --- a/core/modules/filters/each.js +++ b/core/modules/filters/each.js @@ -22,12 +22,12 @@ exports.each = function(source,operator,options) { list = "list" === operator.suffix; source(function(tiddler,title) { if(tiddler) { - var value, - field = operator.operand || "title"; + var field = operator.operand || "title", + value = list ? + options.wiki.getTiddlerList(title,field) : + [ "title" === field ? title : tiddler.getFieldString(operator.operand)]; $tw.utils.each( - list ? - options.wiki.getTiddlerList(title,field) : - [ "title" === field ? title : tiddler.getFieldString(operator.operand)], + value, function(value){ if(!$tw.utils.hop(values,value)) { values[value] = true; From c3cbbc3f66a08e67ca2c833bb960839daea614b1 Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Mon, 26 Jan 2015 19:00:49 +0100 Subject: [PATCH 03/16] renamed value to items --- core/modules/filters/each.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/core/modules/filters/each.js b/core/modules/filters/each.js index 7458eab2c..b492ed1e1 100644 --- a/core/modules/filters/each.js +++ b/core/modules/filters/each.js @@ -23,18 +23,15 @@ exports.each = function(source,operator,options) { source(function(tiddler,title) { if(tiddler) { var field = operator.operand || "title", - value = list ? + items = list ? options.wiki.getTiddlerList(title,field) : [ "title" === field ? title : tiddler.getFieldString(operator.operand)]; - $tw.utils.each( - value, - function(value){ - if(!$tw.utils.hop(values,value)) { - values[value] = true; - results.push(list ? value : title); - } + $tw.utils.each(items,function(value){ + if(!$tw.utils.hop(values,value)) { + values[value] = true; + results.push(list ? value : title); } - ) + }); } }); return results; From a88ead9c0f857c34ae5d9ee27146386aee133b81 Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Tue, 27 Jan 2015 01:17:14 +0100 Subject: [PATCH 04/16] removed conditional from iterator I'd really like to see a profiler run against the two to see the performance impact of one over the other --- core/modules/filters/each.js | 40 ++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/core/modules/filters/each.js b/core/modules/filters/each.js index b492ed1e1..79a3981b9 100644 --- a/core/modules/filters/each.js +++ b/core/modules/filters/each.js @@ -19,21 +19,31 @@ Export our filter function exports.each = function(source,operator,options) { var results = [], values = {}, - list = "list" === operator.suffix; - source(function(tiddler,title) { - if(tiddler) { - var field = operator.operand || "title", - items = list ? - options.wiki.getTiddlerList(title,field) : - [ "title" === field ? title : tiddler.getFieldString(operator.operand)]; - $tw.utils.each(items,function(value){ - if(!$tw.utils.hop(values,value)) { - values[value] = true; - results.push(list ? value : title); - } - }); - } - }); + field = operator.operand || "title", + add = function(v) { + if(!$tw.utils.hop(values,v)) { + values[v] = true; + results.push(v); + } + }; + if("list" !== operator.suffix) { + source(function(tiddler,title) { + if(tiddler) { + add("title" === field ? title : tiddler.getFieldString(operator.operand)); + } + }); + } else { + source(function(tiddler,title) { + if(tiddler) { + $tw.utils.each( + options.wiki.getTiddlerList(title,field), + function(value) { + add(value); + } + ); + } + }); + } return results; }; From f684a6beb030092caf0eb55f2b7cd6bdd708e739 Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Tue, 27 Jan 2015 02:02:15 +0100 Subject: [PATCH 05/16] fixed helper function and added tests tests: ok --- bin/test.cmd | 4 ++-- core/modules/filters/each.js | 12 ++++++------ editions/test/tiddlers/tests/test-filters.js | 4 ++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/bin/test.cmd b/bin/test.cmd index 554277b57..4733f200e 100644 --- a/bin/test.cmd +++ b/bin/test.cmd @@ -4,8 +4,8 @@ rem test TiddlyWiki5 for tiddlywiki.com rem Run the test edition to run the node.js tests and to generate test.html for tests in the browser -node .\tiddlywiki.js ^ - .\editions\test ^ +node ..\tiddlywiki.js ^ + ..\editions\test ^ --verbose ^ --rendertiddler $:/core/save/all test.html text/plain ^ || exit 1 diff --git a/core/modules/filters/each.js b/core/modules/filters/each.js index 79a3981b9..a046923ad 100644 --- a/core/modules/filters/each.js +++ b/core/modules/filters/each.js @@ -20,16 +20,16 @@ exports.each = function(source,operator,options) { var results = [], values = {}, field = operator.operand || "title", - add = function(v) { - if(!$tw.utils.hop(values,v)) { - values[v] = true; - results.push(v); + add = function(val,title) { + if(!$tw.utils.hop(values,val)) { + values[val] = true; + results.push(title); } }; if("list" !== operator.suffix) { source(function(tiddler,title) { if(tiddler) { - add("title" === field ? title : tiddler.getFieldString(operator.operand)); + add("title" === field ? title : tiddler.getFieldString(field),title); } }); } else { @@ -38,7 +38,7 @@ exports.each = function(source,operator,options) { $tw.utils.each( options.wiki.getTiddlerList(title,field), function(value) { - add(value); + add(value,value); } ); } diff --git a/editions/test/tiddlers/tests/test-filters.js b/editions/test/tiddlers/tests/test-filters.js index 45ea8919e..1b16b117c 100644 --- a/editions/test/tiddlers/tests/test-filters.js +++ b/editions/test/tiddlers/tests/test-filters.js @@ -51,12 +51,14 @@ describe("Filter tests", function() { title: "TiddlerOne", text: "The quick brown fox in $:/TiddlerTwo", tags: ["one"], + authors: "Joe Bloggs", modifier: "JoeBloggs", modified: "201304152222"}); wiki.addTiddler({ title: "$:/TiddlerTwo", text: "The rain in Spain\nfalls mainly on the plain and [[a fourth tiddler]]", tags: ["two"], + authors: "[[John Doe]]", modifier: "JohnDoe", modified: "201304152211"}); wiki.addTiddler({ @@ -217,6 +219,8 @@ describe("Filter tests", function() { it("should handle the each operator", function() { expect(wiki.filterTiddlers("[each[modifier]sort[title]]").join(",")).toBe("$:/TiddlerTwo,TiddlerOne"); + expect(wiki.filterTiddlers("[each:list[tags]sort[title]]").join(",")).toBe("one,two"); + expect(wiki.filterTiddlers("[each:list[authors]sort[title]]").join(",")).toBe("Bloggs,Joe,John Doe"); }); it("should handle the eachday operator", function() { From 4788725ccf4e05ee0d3d7416f7a62fa9ad5a0a6a Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Tue, 27 Jan 2015 02:05:13 +0100 Subject: [PATCH 06/16] reverted test.cmd not sure how handling these files in the console works, reverted back to previous version, to be run from repo folder --- bin/test.cmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/test.cmd b/bin/test.cmd index 4733f200e..554277b57 100644 --- a/bin/test.cmd +++ b/bin/test.cmd @@ -4,8 +4,8 @@ rem test TiddlyWiki5 for tiddlywiki.com rem Run the test edition to run the node.js tests and to generate test.html for tests in the browser -node ..\tiddlywiki.js ^ - ..\editions\test ^ +node .\tiddlywiki.js ^ + .\editions\test ^ --verbose ^ --rendertiddler $:/core/save/all test.html text/plain ^ || exit 1 From d0a24bd9f093e52afe6159f042d758c537943665 Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Tue, 27 Jan 2015 19:31:23 +0100 Subject: [PATCH 07/16] added $tw.utils.pushOnce retained check for basic each nonetheless tests pass --- boot/boot.js | 9 +++++++++ core/modules/filters/each.js | 20 +++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/boot/boot.js b/boot/boot.js index acdfa0327..68eb80799 100644 --- a/boot/boot.js +++ b/boot/boot.js @@ -84,6 +84,15 @@ $tw.utils.each = function(object,callback) { } }; +/* +Pushes a value to an array only when not yet contained. +*/ +$tw.utils.pushOnce = function(array,value) { + if(0 > array.indexOf(value)){ + array.push(value); + } +} + /* Helper for making DOM elements tag: tag name diff --git a/core/modules/filters/each.js b/core/modules/filters/each.js index a046923ad..8307ee31b 100644 --- a/core/modules/filters/each.js +++ b/core/modules/filters/each.js @@ -17,19 +17,17 @@ With suffix "list", selects all tiddlers that are values in a specified list fie Export our filter function */ exports.each = function(source,operator,options) { - var results = [], - values = {}, - field = operator.operand || "title", - add = function(val,title) { - if(!$tw.utils.hop(values,val)) { - values[val] = true; - results.push(title); - } - }; + var results =[] , + value,values = {}, + field = operator.operand || "title"; if("list" !== operator.suffix) { source(function(tiddler,title) { if(tiddler) { - add("title" === field ? title : tiddler.getFieldString(field),title); + value = "title" === field ? title : tiddler.getFieldString(field); + if(!$tw.utils.hop(values,value)) { + values[value] = true; + results.push(title); + } } }); } else { @@ -38,7 +36,7 @@ exports.each = function(source,operator,options) { $tw.utils.each( options.wiki.getTiddlerList(title,field), function(value) { - add(value,value); + $tw.utils.pushOnce(results,value); } ); } From 91b5547cdf5c1cd52797bed246a3eb35fbefa65b Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Thu, 29 Jan 2015 00:45:58 +0100 Subject: [PATCH 08/16] adopted style recommendations --- boot/boot.js | 2 +- core/modules/filters/each.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/boot/boot.js b/boot/boot.js index 68eb80799..56742c89d 100644 --- a/boot/boot.js +++ b/boot/boot.js @@ -88,7 +88,7 @@ $tw.utils.each = function(object,callback) { Pushes a value to an array only when not yet contained. */ $tw.utils.pushOnce = function(array,value) { - if(0 > array.indexOf(value)){ + if(array.indexOf(value) == -1) { array.push(value); } } diff --git a/core/modules/filters/each.js b/core/modules/filters/each.js index 8307ee31b..cd7584323 100644 --- a/core/modules/filters/each.js +++ b/core/modules/filters/each.js @@ -20,10 +20,10 @@ exports.each = function(source,operator,options) { var results =[] , value,values = {}, field = operator.operand || "title"; - if("list" !== operator.suffix) { + if(operator.suffix !== "list") { source(function(tiddler,title) { if(tiddler) { - value = "title" === field ? title : tiddler.getFieldString(field); + value = (field === "title") ? title : tiddler.getFieldString(field); if(!$tw.utils.hop(values,value)) { values[value] = true; results.push(title); From 95eb8810b66d2c9e9caf5c5ebb83936867a46ed7 Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Wed, 11 Feb 2015 19:35:05 +0100 Subject: [PATCH 09/16] removed pushOnce --- boot/boot.js | 9 --------- core/modules/filters/each.js | 7 +++++-- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/boot/boot.js b/boot/boot.js index 56742c89d..acdfa0327 100644 --- a/boot/boot.js +++ b/boot/boot.js @@ -84,15 +84,6 @@ $tw.utils.each = function(object,callback) { } }; -/* -Pushes a value to an array only when not yet contained. -*/ -$tw.utils.pushOnce = function(array,value) { - if(array.indexOf(value) == -1) { - array.push(value); - } -} - /* Helper for making DOM elements tag: tag name diff --git a/core/modules/filters/each.js b/core/modules/filters/each.js index cd7584323..c60447446 100644 --- a/core/modules/filters/each.js +++ b/core/modules/filters/each.js @@ -29,14 +29,17 @@ exports.each = function(source,operator,options) { results.push(title); } } - }); + }); } else { source(function(tiddler,title) { if(tiddler) { $tw.utils.each( options.wiki.getTiddlerList(title,field), function(value) { - $tw.utils.pushOnce(results,value); + if(!$tw.utils.hop(values,value)) { + values[value] = true; + results.push(value); + } } ); } From 32c41479ccc6433dd4ede4e471d1e4f331251bff Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Mon, 26 Jan 2015 18:58:08 +0100 Subject: [PATCH 10/16] using variable declaration for readability --- core/modules/filters/each.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/filters/each.js b/core/modules/filters/each.js index c60447446..a1e233a94 100644 --- a/core/modules/filters/each.js +++ b/core/modules/filters/each.js @@ -48,4 +48,4 @@ exports.each = function(source,operator,options) { return results; }; -})(); +})(); \ No newline at end of file From 8b74706e359b0f1ab69cd40d799dee194179b682 Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Tue, 27 Jan 2015 02:02:15 +0100 Subject: [PATCH 11/16] fixed helper function and added tests tests: ok --- bin/test.cmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/test.cmd b/bin/test.cmd index 554277b57..4733f200e 100644 --- a/bin/test.cmd +++ b/bin/test.cmd @@ -4,8 +4,8 @@ rem test TiddlyWiki5 for tiddlywiki.com rem Run the test edition to run the node.js tests and to generate test.html for tests in the browser -node .\tiddlywiki.js ^ - .\editions\test ^ +node ..\tiddlywiki.js ^ + ..\editions\test ^ --verbose ^ --rendertiddler $:/core/save/all test.html text/plain ^ || exit 1 From 843f18dc7ed10b2c90ae6db54ffee6f9030a6f7d Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Tue, 27 Jan 2015 02:05:13 +0100 Subject: [PATCH 12/16] reverted test.cmd not sure how handling these files in the console works, reverted back to previous version, to be run from repo folder --- bin/test.cmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/test.cmd b/bin/test.cmd index 4733f200e..554277b57 100644 --- a/bin/test.cmd +++ b/bin/test.cmd @@ -4,8 +4,8 @@ rem test TiddlyWiki5 for tiddlywiki.com rem Run the test edition to run the node.js tests and to generate test.html for tests in the browser -node ..\tiddlywiki.js ^ - ..\editions\test ^ +node .\tiddlywiki.js ^ + .\editions\test ^ --verbose ^ --rendertiddler $:/core/save/all test.html text/plain ^ || exit 1 From 71968e09733753ce0e7d8a03f51ffeed768437d7 Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Tue, 27 Jan 2015 19:31:23 +0100 Subject: [PATCH 13/16] added $tw.utils.pushOnce retained check for basic each nonetheless tests pass --- boot/boot.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/boot/boot.js b/boot/boot.js index acdfa0327..68eb80799 100644 --- a/boot/boot.js +++ b/boot/boot.js @@ -84,6 +84,15 @@ $tw.utils.each = function(object,callback) { } }; +/* +Pushes a value to an array only when not yet contained. +*/ +$tw.utils.pushOnce = function(array,value) { + if(0 > array.indexOf(value)){ + array.push(value); + } +} + /* Helper for making DOM elements tag: tag name From b34e4f628d5c1f4ebd83c4bde0daf9ae4d7765af Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Thu, 29 Jan 2015 00:45:58 +0100 Subject: [PATCH 14/16] adopted style recommendations --- boot/boot.js | 2 +- core/modules/filters/each.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/boot/boot.js b/boot/boot.js index 68eb80799..56742c89d 100644 --- a/boot/boot.js +++ b/boot/boot.js @@ -88,7 +88,7 @@ $tw.utils.each = function(object,callback) { Pushes a value to an array only when not yet contained. */ $tw.utils.pushOnce = function(array,value) { - if(0 > array.indexOf(value)){ + if(array.indexOf(value) == -1) { array.push(value); } } diff --git a/core/modules/filters/each.js b/core/modules/filters/each.js index a1e233a94..c60447446 100644 --- a/core/modules/filters/each.js +++ b/core/modules/filters/each.js @@ -48,4 +48,4 @@ exports.each = function(source,operator,options) { return results; }; -})(); \ No newline at end of file +})(); From 26114eb3ff4a3039aad9ca4f203a256b7dd37968 Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Wed, 11 Feb 2015 19:35:05 +0100 Subject: [PATCH 15/16] removed pushOnce --- boot/boot.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/boot/boot.js b/boot/boot.js index 56742c89d..acdfa0327 100644 --- a/boot/boot.js +++ b/boot/boot.js @@ -84,15 +84,6 @@ $tw.utils.each = function(object,callback) { } }; -/* -Pushes a value to an array only when not yet contained. -*/ -$tw.utils.pushOnce = function(array,value) { - if(array.indexOf(value) == -1) { - array.push(value); - } -} - /* Helper for making DOM elements tag: tag name From 2acea55711c76675c3122adc82554df7c2b2fbd4 Mon Sep 17 00:00:00 2001 From: Tobias Beer Date: Thu, 8 Oct 2015 13:31:09 +0200 Subject: [PATCH 16/16] added example documentation the documentation for the feature seems already there / merged --- editions/tw5.com/tiddlers/filters/examples/each.tid | 1 + 1 file changed, 1 insertion(+) diff --git a/editions/tw5.com/tiddlers/filters/examples/each.tid b/editions/tw5.com/tiddlers/filters/examples/each.tid index 0b5017957..091e1bc37 100644 --- a/editions/tw5.com/tiddlers/filters/examples/each.tid +++ b/editions/tw5.com/tiddlers/filters/examples/each.tid @@ -6,5 +6,6 @@ type: text/vnd.tiddlywiki <<.operator-example 1 "[each[color]]">> <<.operator-example 2 "[sort[title]each[type]]" "the alphabetically first tiddler of each type">> +<<.operator-example 3 "[each:list[list]]" "all tiddlers listed anywhere in the core list field">> For an example of using the <<.op each>> operator to generate a two-tier list of groups and members, see [[GroupedLists]].