From 4fb68364811b96e028044db5e3963fea051c07fd Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Sat, 14 Sep 2013 16:28:46 +0100 Subject: [PATCH] Add an untagged filter operator and sidebar tab --- core/modules/filters/untagged.js | 44 +++++++++++++++++++ core/ui/MoreSideBar.tid | 5 +++ editions/test/tiddlers/tests/test-filters.js | 6 ++- .../tiddlers/concepts/TiddlerFilters.tid | 3 +- 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 core/modules/filters/untagged.js diff --git a/core/modules/filters/untagged.js b/core/modules/filters/untagged.js new file mode 100644 index 000000000..d43de5bb8 --- /dev/null +++ b/core/modules/filters/untagged.js @@ -0,0 +1,44 @@ +/*\ +title: $:/core/modules/filters/untagged.js +type: application/javascript +module-type: filteroperator + +Filter operator returning all the selected tiddlers that are untagged + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +/* +Export our filter function +*/ +exports.untagged = function(source,operator,options) { + var results = []; + // Function to check an individual title + function checkTiddler(title) { + var tiddler = options.wiki.getTiddler(title), + match = tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0; + if(operator.prefix !== "!") { + match = !match; + } + if(match) { + $tw.utils.pushTop(results,title); + } + } + // Iterate through the source tiddlers + if($tw.utils.isArray(source)) { + $tw.utils.each(source,function(title) { + checkTiddler(title); + }); + } else { + $tw.utils.each(source,function(element,title) { + checkTiddler(title); + }); + } + return results; +}; + +})(); diff --git a/core/ui/MoreSideBar.tid b/core/ui/MoreSideBar.tid index fb92f05ad..fc90ebf81 100644 --- a/core/ui/MoreSideBar.tid +++ b/core/ui/MoreSideBar.tid @@ -8,6 +8,8 @@ title: $:/core/ui/MoreSideBar <$button type="set" set="$:/state/moreSideBarTabSet" setTo="tagsTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">Tags +<$button type="set" set="$:/state/moreSideBarTabSet" setTo="untaggedTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">Untagged + <$button type="set" set="$:/state/moreSideBarTabSet" setTo="missingTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">Missing <$button type="set" set="$:/state/moreSideBarTabSet" setTo="draftsTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">Drafts @@ -32,6 +34,9 @@ title: $:/core/ui/MoreSideBar <$transclude title="$:/core/ui/TagTemplate"/> <$count filter="[is[current]tagging[]]"/> +<$reveal type="match" state="$:/state/moreSideBarTabSet" text="untaggedTab" qualifyTiddlerTitles="yes"> +<$list filter="[untagged[]!is[system]sort[title]]" itemClass="tw-menu-list-item"/> + <$reveal type="match" state="$:/state/moreSideBarTabSet" text="missingTab" qualifyTiddlerTitles="yes"> <$list filter="[is[missing]sort[title]]" itemClass="tw-menu-list-item" template="$:/core/ui/MissingTemplate"/> diff --git a/editions/test/tiddlers/tests/test-filters.js b/editions/test/tiddlers/tests/test-filters.js index 50410e764..861655e71 100644 --- a/editions/test/tiddlers/tests/test-filters.js +++ b/editions/test/tiddlers/tests/test-filters.js @@ -50,7 +50,6 @@ describe("Filter tests", function() { wiki.addTiddler({ title: "one", text: "This is the text of tiddler [[one]]", - tags: [], list: "[[Tiddler Three]] [[TiddlerOne]]", modifier: "JohnDoe"}); // And some shadows @@ -119,6 +118,11 @@ describe("Filter tests", function() { expect(wiki.filterTiddlers("[is[current]tagging[]sort[title]]","one").join(",")).toBe("Tiddler Three,TiddlerOne"); }); + it("should handle the untagged operator", function() { + expect(wiki.filterTiddlers("[untagged[]sort[title]]").join(",")).toBe("a fourth tiddler,one"); + expect(wiki.filterTiddlers("[!untagged[]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne"); + }); + it("should handle the links operator", function() { expect(wiki.filterTiddlers("[!is[shadow]links[]sort[title]]").join(",")).toBe("a fourth tiddler,one,Tiddler Three,TiddlerSix,TiddlerTwo,TiddlerZero"); expect(wiki.filterTiddlers("[is[shadow]links[]sort[title]]").join(",")).toBe("TiddlerOne"); diff --git a/editions/tw5.com/tiddlers/concepts/TiddlerFilters.tid b/editions/tw5.com/tiddlers/concepts/TiddlerFilters.tid index 3ef68102c..1e74fa99f 100644 --- a/editions/tw5.com/tiddlers/concepts/TiddlerFilters.tid +++ b/editions/tw5.com/tiddlers/concepts/TiddlerFilters.tid @@ -1,6 +1,6 @@ created: 201308270800 creator: JeremyRuston -modified: 201308300906 +modified: 201309141606 modifier: JeremyRuston tags: concepts title: TiddlerFilters @@ -44,6 +44,7 @@ A filter string consists of one or more runs of filter operators that each look * ''{field}'': tests whether a tiddler field has a specified value (`[modifier[Jeremy]]`) or not (`[!modifier[Jeremy]]`) * ''tags'': selects the tags on the currently selected tiddlers * ''tagging'': selects the tiddlers tagged with the currently selected tiddlers +* ''untagged'': selects the any of the selected tiddlers that do not have at least one tag * ''links'': selects the outgoing links on the currently selected tiddlers * ''backlinks'': selects the tiddlers that link to the currently selected tiddlers * ''list'': selects the tiddlers listed in a specified [[TiddlerList|TiddlerLists]]