mirror of
				https://github.com/Jermolene/TiddlyWiki5
				synced 2025-10-31 15:42:59 +00:00 
			
		
		
		
	Refactor the filter mechanism
Long overdue rewrite to make it simpler, and break the filter operators out into individual modules.
This commit is contained in:
		| @@ -12,274 +12,6 @@ Adds tiddler filtering to the $tw.Wiki object. | |||||||
| /*global $tw: false */ | /*global $tw: false */ | ||||||
| "use strict"; | "use strict"; | ||||||
|  |  | ||||||
| exports.filterTiddlers = function(filterString,currTiddlerTitle,tiddlerList) { |  | ||||||
| 	var fn = this.compileFilter(filterString); |  | ||||||
| 	return fn.call(this,tiddlerList || this.tiddlers,currTiddlerTitle); |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /* |  | ||||||
| Compiling a filter gives a JavaScript function that is invoked as `this.filter(source)`, where `source` is a hashmap of source tiddler titles (the values don't matter, so it is possible to use a store or a changes object). It returns an array of tiddler titles that satisfy the filter |  | ||||||
| */ |  | ||||||
| exports.compileFilter = function(filterString) { |  | ||||||
| 	var filter = this.parseFilter(filterString), |  | ||||||
| 		output = [], |  | ||||||
| 		t,operation,operationInfo,type,p,operator,operatorInfo,fn; |  | ||||||
| 	output.push(this.filterFragments.prologue); |  | ||||||
| 	for(t=0; t<filter.length; t++) { |  | ||||||
| 		operation = filter[t]; |  | ||||||
| 		operationInfo = this.filterFragments.operation.prefix[operation.prefix || ""]; |  | ||||||
| 		output.push(operationInfo.prologue); |  | ||||||
| 		type = "selector"; |  | ||||||
| 		if(operation.prefix === "+") { |  | ||||||
| 			type = "filter"; |  | ||||||
| 		} |  | ||||||
| 		for(p=0; p<operation.operators.length; p++) { |  | ||||||
| 			operator = operation.operators[p]; |  | ||||||
| 			operatorInfo = this.operators[operator.operator]; |  | ||||||
| 			if(!operatorInfo) { // Check for it being a field operator |  | ||||||
| 				operatorInfo = this.operators.field; |  | ||||||
| 			} |  | ||||||
| 			output.push(operatorInfo[type](operator)); |  | ||||||
| 			type = "filter"; |  | ||||||
| 		} |  | ||||||
| 		output.push(operationInfo.epilogue); |  | ||||||
| 	} |  | ||||||
| 	output.push(this.filterFragments.epilogue); |  | ||||||
| 	try { |  | ||||||
| 		/*jslint evil: true */ |  | ||||||
| 		fn = eval(output.join("\n")); |  | ||||||
| 	} catch(ex) { |  | ||||||
| 		throw "Error in filter expression: " + ex; |  | ||||||
| 	} |  | ||||||
| 	return fn; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| exports.filterFragments = { |  | ||||||
| 	prologue: "(function(source,currTiddlerTitle) {\nvar results = [], subResults, subResultsTemp, title, r, t;", |  | ||||||
| 	epilogue: "return results;\n})", |  | ||||||
| 	operation: { |  | ||||||
| 		prefix: { |  | ||||||
| 			"": { |  | ||||||
| 				prologue: "subResults = [];", |  | ||||||
| 				epilogue: "$tw.utils.pushTop(results,subResults);" |  | ||||||
| 			}, |  | ||||||
| 			"+": { |  | ||||||
| 				prologue: "subResults = results.slice(0);\nresults.splice(0,results.length);", |  | ||||||
| 				epilogue: "$tw.utils.pushTop(results,subResults);" |  | ||||||
| 			}, |  | ||||||
| 			"-": { |  | ||||||
| 				prologue: "subResults = [];", |  | ||||||
| 				epilogue: "$tw.utils.removeArrayEntries(results,subResults);" |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| exports.operators = { |  | ||||||
| 	"title": { // Filter by title |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			if(operator.prefix === "!") { |  | ||||||
| 				return "for(title in source) {if(title !== \"" + $tw.utils.stringify(operator.operand) + "\") {$tw.utils.pushTop(subResults,title);}}"; |  | ||||||
| 			} else { |  | ||||||
| 				return "$tw.utils.pushTop(subResults,\"" + $tw.utils.stringify(operator.operand) + "\");"; |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "!" : "="; |  | ||||||
| 			return "if(subResults.indexOf(\"" + $tw.utils.stringify(operator.operand) + "\") " + op + "== -1) {subResults = [\"" + $tw.utils.stringify(operator.operand) + "\"];} else {subResults = [];}"; |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"prefix": { // Filter by title prefix |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "!" : "="; |  | ||||||
| 			return "for(title in source) {if(title.substr(0," + operator.operand.length + ")" + op + "==\"" + $tw.utils.stringify(operator.operand) + "\") {$tw.utils.pushTop(subResults,title);}}"; |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "=" : "!"; |  | ||||||
| 			return "for(r=subResults.length-1; r>=0; r--) {if(title.substr(0," + operator.operand.length + ")" + op + "==\"" + $tw.utils.stringify(operator.operand) + "\") {subResults.splice(r,1);}}"; |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"is": { // Filter by status |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "!" : ""; |  | ||||||
| 			switch(operator.operand) { |  | ||||||
| 				case "current": |  | ||||||
| 					if(operator.prefix === "!") { |  | ||||||
| 						return "for(title in source) {if(title !== currTiddlerTitle) {$tw.utils.pushTop(subResults,title);}}"; |  | ||||||
| 					} else { |  | ||||||
| 						return "$tw.utils.pushTop(subResults,currTiddlerTitle);"; |  | ||||||
| 					} |  | ||||||
| 					break; |  | ||||||
| 				case "system": |  | ||||||
| 					return "for(title in source) {if(" + op + "this.isSystemTiddler(title)) {$tw.utils.pushTop(subResults,title);}}"; |  | ||||||
| 				case "shadow": |  | ||||||
| 					if(operator.prefix === "!") { |  | ||||||
| 						return "for(title in source) {if(!this.isShadowTiddler(title)) {$tw.utils.pushTop(subResults,title);}}"; |  | ||||||
| 					} else { |  | ||||||
| 						return "for(title in this.shadowTiddlers) {$tw.utils.pushTop(subResults,title);}"; |  | ||||||
| 					} |  | ||||||
| 				case "missing": |  | ||||||
| 					if(operator.prefix === "!") { |  | ||||||
| 						return "for(title in source) {$tw.utils.pushTop(subResults,title);}"; |  | ||||||
| 					} else { |  | ||||||
| 						return "var m = this.getMissingTitles(); for(t=0; t<m.length; t++) {$tw.utils.pushTop(subResults,m[t]);}"; |  | ||||||
| 					} |  | ||||||
| 				case "orphan": |  | ||||||
| 					if(operator.prefix === "!") { |  | ||||||
| 						return "var m = this.getOrphanTitles(); for(title in source) {if(m.indexOf(title) === -1) {$tw.utils.pushTop(subResults,title);}}"; |  | ||||||
| 					} else { |  | ||||||
| 						return "var m = this.getOrphanTitles(); for(t=0; t<m.length; t++) {$tw.utils.pushTop(subResults,m[t]);}"; |  | ||||||
| 					} |  | ||||||
| 				default: |  | ||||||
| 					throw "Unknown operand for 'is' filter operator"; |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "" : "!"; |  | ||||||
| 			switch(operator.operand) { |  | ||||||
| 				case "current": |  | ||||||
| 					if(operator.prefix === "!") { |  | ||||||
| 						return "for(r=subResults.length-1; r>=0; r--) {if(subResults[r] === currTiddlerTitle) {subResults.splice(r,1);}}"; |  | ||||||
| 					} else { |  | ||||||
| 						return "r = subResults.indexOf(currTiddlerTitle);\nif(r !== -1) {subResults = [currTiddlerTitle];} else {subResults = [];}"; |  | ||||||
| 					} |  | ||||||
| 					break; |  | ||||||
| 				case "system": |  | ||||||
| 					return "for(r=subResults.length-1; r>=0; r--) {if(" + op + "this.isSystemTiddler(subResults[r])) {subResults.splice(r,1);}}"; |  | ||||||
| 				case "shadow": |  | ||||||
| 					return "for(r=subResults.length-1; r>=0; r--) {if(" + op + "this.isShadowTiddler(subResults[r])) {subResults.splice(r,1);}}"; |  | ||||||
| 				case "missing": |  | ||||||
| 					return "t = this.getMissingTitles(); for(r=subResults.length-1; r>=0; r--) {if(" + op + "!$tw.utils.hop(t,subResults[r])) {subResults.splice(r,1);}}"; |  | ||||||
| 				case "orphan": |  | ||||||
| 					if(operator.prefix === "!") { |  | ||||||
| 						return "t = this.getOrphanTitles(); for(r=subResults.length-1; r>=0; r--) {if(t.indexOf(subResults[r]) === -1) {subResults.splice(r,1);}}"; |  | ||||||
| 					} else { |  | ||||||
| 						return "t = this.getOrphanTitles(); for(r=subResults.length-1; r>=0; r--) {if(t.indexOf(subResults[r]) !== -1) {subResults.splice(r,1);}}"; |  | ||||||
| 					} |  | ||||||
| 				default: |  | ||||||
| 					throw "Unknown operand for 'is' filter operator"; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"tag": { // Filter by tag |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "!" : ""; |  | ||||||
| 			return "for(title in source) {if(" + op + "this.getTiddler(title).hasTag(\"" + $tw.utils.stringify(operator.operand) + "\")) {$tw.utils.pushTop(subResults,title);}}"; |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "" : "!"; |  | ||||||
| 			return "for(r=subResults.length-1; r>=0; r--) {if(" + op + "this.getTiddler(subResults[r]).hasTag(\"" + $tw.utils.stringify(operator.operand) + "\")) {subResults.splice(r,1);}}"; |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"tags": { // Return all tags used on selected tiddlers |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			return "for(title in source) {r = this.getTiddler(title); if(r && r.fields.tags) {$tw.utils.pushTop(subResults,r.fields.tags);}}"; |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			return "subResultsTemp = subResults;\nsubResults = [];for(t=subResultsTemp.length-1; t>=0; t--) {r = this.getTiddler(subResultsTemp[t]); if(r && r.fields.tags) {$tw.utils.pushTop(subResults,r.fields.tags);}}"; |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"tagging": { // Return all tiddlers tagged with any of the selected tags |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			return "for(title in source) {$tw.utils.pushTop(subResults,this.getTiddlersWithTag(title));}"; |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			return "subResultsTemp = subResults;\nsubResults = [];for(t=subResultsTemp.length-1; t>=0; t--) {$tw.utils.pushTop(subResults,this.getTiddlersWithTag(subResultsTemp[t]));}"; |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"links": { // Return outgoing links on selected tiddlers |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			return "for(title in source) {r = this.getTiddlerLinks(title); $tw.utils.pushTop(subResults,r);}"; |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			return "subResultsTemp = subResults;\nsubResults = [];for(t=subResultsTemp.length-1; t>=0; t--) {r = this.getTiddlerLinks(subResultsTemp[t]); $tw.utils.pushTop(subResults,r);}"; |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"backlinks": { // Return incoming links on selected tiddlers |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			return "for(title in source) {r = this.getTiddlerBacklinks(title); $tw.utils.pushTop(subResults,r);}"; |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			return "subResultsTemp = subResults;\nsubResults = [];for(t=subResultsTemp.length-1; t>=0; t--) {r = this.getTiddlerBacklinks(subResultsTemp[t]); $tw.utils.pushTop(subResults,r);}"; |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"has": { // Filter by presence of a particular field |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "=" : "!"; |  | ||||||
| 			return "for(title in source) {if(this.getTiddler(title).fields[\"" + $tw.utils.stringify(operator.operand) + "\"] " + op + "== undefined) {$tw.utils.pushTop(subResults,title);}}"; |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "!" : "="; |  | ||||||
| 			return "for(r=subResults.length-1; r>=0; r--) {if(this.getTiddler(subResults[r]).fields[\"" + $tw.utils.stringify(operator.operand) + "\"] " + op + "== undefined) {subResults.splice(r,1);}}"; |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"sort": { // Sort selected tiddlers |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			throw "Cannot use sort operator at the start of a filter operation"; |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			var desc = operator.prefix === "!" ? "true" : "false"; |  | ||||||
| 			return "this.sortTiddlers(subResults,\"" + $tw.utils.stringify(operator.operand) + "\"," + desc + ");"; |  | ||||||
| 		} |  | ||||||
| 	}, // Case insensitive sort of selected tiddlers |  | ||||||
| 	"sort-case-sensitive": { |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			throw "Cannot use sort operator at the start of a filter operation"; |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			var desc = operator.prefix === "!" ? "true" : "false"; |  | ||||||
| 			return "this.sortTiddlers(subResults,\"" + $tw.utils.stringify(operator.operand) + "\"," + desc + ",true);"; |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"limit": { // Limit number of members of selection |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			throw "Cannot use limit operator at the start of a filter operation"; |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			var limit = parseInt(operator.operand,10), |  | ||||||
| 				base = operator.prefix === "!" ? 0 : limit; |  | ||||||
| 			return "if(subResults.length > " + limit + ") {subResults.splice(" + base + ",subResults.length-" + limit + ");}"; |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"list": { // Select all tiddlers that are listed (or not listed) in the specified tiddler |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			if(operator.prefix === "!") { |  | ||||||
| 				return "var list = this.getTiddlerList(\"" + $tw.utils.stringify(operator.operand) + "\");" + |  | ||||||
| 					"for(title in source) {if(list.indexOf(title) === -1) {$tw.utils.pushTop(subResults,title);}}"; |  | ||||||
| 			} else { |  | ||||||
| 				return "$tw.utils.pushTop(subResults,this.getTiddlerList(\"" + $tw.utils.stringify(operator.operand) + "\"));"; |  | ||||||
| 			} |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "!==" : "==="; |  | ||||||
| 			return "var list = this.getTiddlerList(\"" + $tw.utils.stringify(operator.operand) + "\");" + |  | ||||||
| 				"for(r=subResults.length-1; r>=0; r--) {if(list.indexOf(title) " + op + " -1) {subResults.splice(r,1);}}"; |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"searchVia": { // Search for the string in the operand tiddler |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "true" : "false"; |  | ||||||
| 			return "var term = this.getTiddler(\"" + $tw.utils.stringify(operator.operand) + "\").fields.text;" + |  | ||||||
| 				"$tw.utils.pushTop(subResults,this.search(term,{titles: source, invert: " + op + ", exclude: [\"" + $tw.utils.stringify(operator.operand) + "\"]}));"; |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "true" : "false"; |  | ||||||
| 			return "var term = this.getTiddler(\"" + $tw.utils.stringify(operator.operand) + "\").fields.text;" + |  | ||||||
| 				"subResults = this.search(term,{titles: subResults, invert: " + op + ", exclude: [\"" + $tw.utils.stringify(operator.operand) + "\"]});"; |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"field": { // Special handler for field comparisons |  | ||||||
| 		selector: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "!" : "="; |  | ||||||
| 			return "for(title in source) {if(this.getTiddler(title).fields[\"" + $tw.utils.stringify(operator.operator) + "\"] " + op + "== \"" + operator.operand + "\") {$tw.utils.pushTop(subResults,title);}}"; |  | ||||||
| 		}, |  | ||||||
| 		filter: function(operator) { |  | ||||||
| 			var op = operator.prefix === "!" ? "=" : "!"; |  | ||||||
| 			return "for(r=subResults.length-1; r>=0; r--) {if(this.getTiddler(subResults[r]).fields[\"" + $tw.utils.stringify(operator.operator) + "\"] " + op + "== \"" + operator.operand + "\") {subResults.splice(r,1);}}"; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /* | /* | ||||||
| Parses an operation within a filter string | Parses an operation within a filter string | ||||||
| 	results: Array of array of operator nodes into which results should be inserted | 	results: Array of array of operator nodes into which results should be inserted | ||||||
| @@ -376,4 +108,70 @@ exports.parseFilter = function(filterString) { | |||||||
| 	return results; | 	return results; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | exports.getFilterOperators = function() { | ||||||
|  | 	if(!this.filterOperators) { | ||||||
|  | 		$tw.Wiki.prototype.filterOperators = {}; | ||||||
|  | 		$tw.modules.applyMethods("filteroperator",this.filterOperators); | ||||||
|  | 	} | ||||||
|  | 	return this.filterOperators; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | exports.filterTiddlers = function(filterString,currTiddlerTitle,tiddlerList) { | ||||||
|  | 	var fn = this.compileFilter(filterString); | ||||||
|  | 	return fn.call(this,tiddlerList || this.tiddlers,currTiddlerTitle); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | exports.compileFilter = function(filterString) { | ||||||
|  | 	var filterParseTree = this.parseFilter(filterString); | ||||||
|  | 	// Get the hashmap of filter operator functions | ||||||
|  | 	var filterOperators = this.getFilterOperators(); | ||||||
|  | 	// Assemble array of functions, one for each operation | ||||||
|  | 	var operationFunctions = []; | ||||||
|  | 	// Step through the operations | ||||||
|  | 	var self = this; | ||||||
|  | 	$tw.utils.each(filterParseTree,function(operation) { | ||||||
|  | 		// Create a function for the chain of operators in the operation | ||||||
|  | 		var operationSubFunction = function(source,currTiddlerTitle) { | ||||||
|  | 			var accumulator = source, | ||||||
|  | 				results = []; | ||||||
|  | 			$tw.utils.each(operation.operators,function(operator) { | ||||||
|  | 				var operatorFunction = filterOperators[operator.operator] || filterOperators.field || function(source,operator,operations) { | ||||||
|  | 					return ["Filter Error: unknown operator '" + operator.operator + "'"]; | ||||||
|  | 				}; | ||||||
|  | 				results = operatorFunction(accumulator,operator,{wiki: self, currTiddlerTitle: currTiddlerTitle}); | ||||||
|  | 				accumulator = results; | ||||||
|  | 			}); | ||||||
|  | 			return results; | ||||||
|  | 		}; | ||||||
|  | 		// Wrap the operator functions in a wrapper function that depends on the prefix | ||||||
|  | 		operationFunctions.push((function() { | ||||||
|  | 			switch(operation.prefix || "") { | ||||||
|  | 				case "": // No prefix means that the operation is unioned into the result | ||||||
|  | 					return function(results,source,currTiddlerTitle) { | ||||||
|  | 						$tw.utils.pushTop(results,operationSubFunction(source,currTiddlerTitle)); | ||||||
|  | 					}; | ||||||
|  | 				case "-": // The results of this operation are removed from the main result | ||||||
|  | 					return function(results,source,currTiddlerTitle) { | ||||||
|  | 						$tw.utils.removeArrayEntries(results,operationSubFunction(source,currTiddlerTitle)); | ||||||
|  | 					}; | ||||||
|  | 				case "+": // This operation is applied to the main results so far | ||||||
|  | 					return function(results,source,currTiddlerTitle) { | ||||||
|  | 						// This replaces all the elements of the array, but keeps the actual array so that references to it are preserved | ||||||
|  | 						source = results.slice(0); | ||||||
|  | 						results.splice(0,results.length); | ||||||
|  | 						$tw.utils.pushTop(results,operationSubFunction(source,currTiddlerTitle)); | ||||||
|  | 					}; | ||||||
|  | 			} | ||||||
|  | 		})()); | ||||||
|  | 	}); | ||||||
|  | 	// Return a function that applies the operations to a source array/hashmap of tiddler titles | ||||||
|  | 	return function(source,currTiddlerTitle) { | ||||||
|  | 		var results = []; | ||||||
|  | 		$tw.utils.each(operationFunctions,function(operationFunction) { | ||||||
|  | 			operationFunction(results,source,currTiddlerTitle); | ||||||
|  | 		}); | ||||||
|  | 		return results; | ||||||
|  | 	}; | ||||||
|  | }; | ||||||
|  |  | ||||||
| })(); | })(); | ||||||
|   | |||||||
							
								
								
									
										37
									
								
								core/modules/filters/backlinks.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								core/modules/filters/backlinks.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/backlinks.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator for returning all the backlinks from a tiddler | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.backlinks = function(source,operator,options) { | ||||||
|  | 	var results = []; | ||||||
|  | 	// Function to check an individual title | ||||||
|  | 	function checkTiddler(title) { | ||||||
|  | 		$tw.utils.pushTop(results,options.wiki.getTiddlerBacklinks(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; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										46
									
								
								core/modules/filters/field.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								core/modules/filters/field.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/field.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator for comparing fields for equality | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.field = function(source,operator,options) { | ||||||
|  | 	var results = []; | ||||||
|  | 	// Function to check an individual title | ||||||
|  | 	function checkTiddler(title) { | ||||||
|  | 		var tiddler = options.wiki.getTiddler(title); | ||||||
|  | 		if(tiddler) { | ||||||
|  | 			var match = tiddler.fields[operator.operator] === operator.operand; | ||||||
|  | 			if(operator.prefix === "!") { | ||||||
|  | 				match = !match; | ||||||
|  | 			} | ||||||
|  | 			if(match) { | ||||||
|  | 				results.push(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; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										46
									
								
								core/modules/filters/has.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								core/modules/filters/has.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/has.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator for checking if a tiddler has the specified field | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.has = function(source,operator,options) { | ||||||
|  | 	var results = []; | ||||||
|  | 	// Function to check an individual title | ||||||
|  | 	function checkTiddler(title) { | ||||||
|  | 		var tiddler = options.wiki.getTiddler(title); | ||||||
|  | 		if(tiddler) { | ||||||
|  | 			var match = $tw.utils.hop(tiddler.fields,operator.operand); | ||||||
|  | 			if(operator.prefix === "!") { | ||||||
|  | 				match = !match; | ||||||
|  | 			} | ||||||
|  | 			if(match) { | ||||||
|  | 				results.push(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; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										39
									
								
								core/modules/filters/is.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								core/modules/filters/is.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/is.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator for checking tiddler properties | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | var isFilterOperators; | ||||||
|  |  | ||||||
|  | function getIsFilterOperators() { | ||||||
|  | 	if(!isFilterOperators) { | ||||||
|  | 		isFilterOperators = {}; | ||||||
|  | 		$tw.modules.applyMethods("isfilteroperator",isFilterOperators); | ||||||
|  | 	} | ||||||
|  | 	return isFilterOperators; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.is = function(source,operator,options) { | ||||||
|  | 	// Dispatch to the correct isfilteroperator | ||||||
|  | 	var isFilterOperators = getIsFilterOperators(); | ||||||
|  | 	var isFilterOperator = isFilterOperators[operator.operand]; | ||||||
|  | 	if(isFilterOperator) { | ||||||
|  | 		return isFilterOperator(source,operator.prefix,options); | ||||||
|  | 	} else { | ||||||
|  | 		return ["Filter Error: Unknown operand for the 'is' filter operator"]; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										49
									
								
								core/modules/filters/is/current.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								core/modules/filters/is/current.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/is/current.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: isfilteroperator | ||||||
|  |  | ||||||
|  | Filter function for [is[current]] | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.current = function(source,prefix,options) { | ||||||
|  | 	var results = []; | ||||||
|  | 	// Function to check a tiddler | ||||||
|  | 	function checkTiddler(title) { | ||||||
|  | 		if(title !== options.currTiddlerTitle) { | ||||||
|  | 			results.push(title); | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  | 	// Iterate through the source tiddlers | ||||||
|  | 	if($tw.utils.isArray(source)) { | ||||||
|  | 		if(prefix === "!") { | ||||||
|  | 			$tw.utils.each(source,function(title) { | ||||||
|  | 				checkTiddler(title); | ||||||
|  | 			}); | ||||||
|  | 		} else { | ||||||
|  | 			if(source.indexOf(options.currTiddlerTitle) !== -1) { | ||||||
|  | 				results.push(options.currTiddlerTitle); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		if(prefix === "!") { | ||||||
|  | 			$tw.utils.each(source,function(element,title) { | ||||||
|  | 				checkTiddler(title); | ||||||
|  | 			}); | ||||||
|  | 		} else { | ||||||
|  | 			results.push(options.currTiddlerTitle); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return results; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										48
									
								
								core/modules/filters/is/missing.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								core/modules/filters/is/missing.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/is/missing.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: isfilteroperator | ||||||
|  |  | ||||||
|  | Filter function for [is[missing]] | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.missing = function(source,prefix,options) { | ||||||
|  | 	var results = [], | ||||||
|  | 		missingTitles; | ||||||
|  | 	// Iterate through the source tiddlers | ||||||
|  | 	if($tw.utils.isArray(source)) { | ||||||
|  | 		missingTitles = options.wiki.getMissingTitles(); | ||||||
|  | 		$tw.utils.each(source,function(title) { | ||||||
|  | 			var match = missingTitles.indexOf(title) !== -1; | ||||||
|  | 			if(prefix === "!") { | ||||||
|  | 				match = !match; | ||||||
|  | 			} | ||||||
|  | 			if(match) { | ||||||
|  | 				results.push(title); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	} else { | ||||||
|  | 		if(prefix !== "!") { | ||||||
|  | 			missingTitles = options.wiki.getMissingTitles(); | ||||||
|  | 			$tw.utils.each(missingTitles,function(title) { | ||||||
|  | 				results.push(title); | ||||||
|  | 			}); | ||||||
|  | 		} else { | ||||||
|  | 			$tw.utils.each(source,function(element,title) { | ||||||
|  | 				results.push(title); | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return results; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										46
									
								
								core/modules/filters/is/orphan.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								core/modules/filters/is/orphan.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/is/orphan.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: isfilteroperator | ||||||
|  |  | ||||||
|  | Filter function for [is[orphan]] | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.orphan = function(source,prefix,options) { | ||||||
|  | 	var results = [], | ||||||
|  | 		orphanTitles = options.wiki.getOrphanTitles(); | ||||||
|  | 	// Iterate through the source tiddlers | ||||||
|  | 	if($tw.utils.isArray(source)) { | ||||||
|  | 		$tw.utils.each(source,function(title) { | ||||||
|  | 			var match = orphanTitles.indexOf(title) !== -1; | ||||||
|  | 			if(prefix === "!") { | ||||||
|  | 				match = !match; | ||||||
|  | 			} | ||||||
|  | 			if(match) { | ||||||
|  | 				results.push(title); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	} else { | ||||||
|  | 		$tw.utils.each(source,function(element,title) { | ||||||
|  | 			var match = orphanTitles.indexOf(title) !== -1; | ||||||
|  | 			if(prefix === "!") { | ||||||
|  | 				match = !match; | ||||||
|  | 			} | ||||||
|  | 			if(match) { | ||||||
|  | 				results.push(title); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | 	return results; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										49
									
								
								core/modules/filters/is/shadow.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								core/modules/filters/is/shadow.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/is/shadow.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: isfilteroperator | ||||||
|  |  | ||||||
|  | Filter function for [is[shadow]] | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.shadow = function(source,prefix,options) { | ||||||
|  | 	var results = []; | ||||||
|  | 	// Function to check a tiddler | ||||||
|  | 	function checkTiddler(title) { | ||||||
|  | 		var match = options.wiki.isShadowTiddler(title); | ||||||
|  | 		if(prefix === "!") { | ||||||
|  | 			match = !match; | ||||||
|  | 		} | ||||||
|  | 		if(match) { | ||||||
|  | 			results.push(title); | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  | 	// Iterate through the source tiddlers | ||||||
|  | 	if($tw.utils.isArray(source)) { | ||||||
|  | 		$tw.utils.each(source,function(title) { | ||||||
|  | 			checkTiddler(title); | ||||||
|  | 		}); | ||||||
|  | 	} else { | ||||||
|  | 		if(prefix !== "!") { | ||||||
|  | 			$tw.utils.each(options.wiki.shadowTiddlers,function(tiddler,title) { | ||||||
|  | 				results.push(title); | ||||||
|  | 			}); | ||||||
|  | 		} else { | ||||||
|  | 			$tw.utils.each(source,function(element,title) { | ||||||
|  | 				checkTiddler(title); | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return results; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										43
									
								
								core/modules/filters/is/system.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								core/modules/filters/is/system.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/is/system.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: isfilteroperator | ||||||
|  |  | ||||||
|  | Filter function for [is[system]] | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.system = function(source,prefix,options) { | ||||||
|  | 	var results = []; | ||||||
|  | 	// Function to check a tiddler | ||||||
|  | 	function checkTiddler(title) { | ||||||
|  | 		var match = options.wiki.isSystemTiddler(title); | ||||||
|  | 		if(prefix === "!") { | ||||||
|  | 			match = !match; | ||||||
|  | 		} | ||||||
|  | 		if(match) { | ||||||
|  | 			results.push(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; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										38
									
								
								core/modules/filters/limit.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								core/modules/filters/limit.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/limit.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator for chopping the results to a specified maximum number of entries | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.limit = function(source,operator,options) { | ||||||
|  | 	var results = []; | ||||||
|  | 	// Convert to an array if necessary | ||||||
|  | 	if(!$tw.utils.isArray(source)) { | ||||||
|  | 		var copy = []; | ||||||
|  | 		$tw.utils.each(source,function(element,title) { | ||||||
|  | 			copy.push(title); | ||||||
|  | 		}); | ||||||
|  | 		source = copy; | ||||||
|  | 	} | ||||||
|  | 	// Slice the array if necessary | ||||||
|  | 	var limit = Math.min(source.length,parseInt(operator.operand,10)); | ||||||
|  | 	if(operator.prefix === "!") { | ||||||
|  | 		results = source.slice(source.length - limit,limit); | ||||||
|  | 	} else { | ||||||
|  | 		results = source.slice(0,limit); | ||||||
|  | 	} | ||||||
|  | 	return results; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										37
									
								
								core/modules/filters/links.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								core/modules/filters/links.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/links.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator for returning all the links from a tiddler | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.links = function(source,operator,options) { | ||||||
|  | 	var results = []; | ||||||
|  | 	// Function to check an individual title | ||||||
|  | 	function checkTiddler(title) { | ||||||
|  | 		$tw.utils.pushTop(results,options.wiki.getTiddlerLinks(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; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										47
									
								
								core/modules/filters/list.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								core/modules/filters/list.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/list.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator returning the tiddlers whose title is listed in the operand tiddler | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.list = function(source,operator,options) { | ||||||
|  | 	var results = [], | ||||||
|  | 		list = options.wiki.getTiddlerList(operator.operand); | ||||||
|  | 	function checkTiddler(title) { | ||||||
|  | 		var match = list.indexOf(title) !== -1; | ||||||
|  | 		if(operator.prefix === "!") { | ||||||
|  | 			match = !match; | ||||||
|  | 		} | ||||||
|  | 		if(match) { | ||||||
|  | 			results.push(title); | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  | 	// Iterate through the source tiddlers | ||||||
|  | 	if($tw.utils.isArray(source)) { | ||||||
|  | 		$tw.utils.each(source,function(title) { | ||||||
|  | 			checkTiddler(title); | ||||||
|  | 		}); | ||||||
|  | 	} else { | ||||||
|  | 		if(operator.prefix !== "!") { | ||||||
|  | 			results = list; | ||||||
|  | 		} else { | ||||||
|  | 			$tw.utils.each(source,function(element,title) { | ||||||
|  | 				checkTiddler(title); | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return results; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										46
									
								
								core/modules/filters/prefix.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								core/modules/filters/prefix.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/prefix.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator for checking if a title starts with a prefix | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.prefix = function(source,operator,options) { | ||||||
|  | 	var results = []; | ||||||
|  | 	// Function to check an individual title | ||||||
|  | 	function checkTiddler(title) { | ||||||
|  | 		var tiddler = options.wiki.getTiddler(title); | ||||||
|  | 		if(tiddler) { | ||||||
|  | 			var match = tiddler.fields.title.substr(0,operator.operand.length) === operator.operand; | ||||||
|  | 			if(operator.prefix === "!") { | ||||||
|  | 				match = !match; | ||||||
|  | 			} | ||||||
|  | 			if(match) { | ||||||
|  | 				results.push(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; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										28
									
								
								core/modules/filters/searchVia.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								core/modules/filters/searchVia.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/searchVia.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator for searching for the text in the operand tiddler | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.searchVia = function(source,operator,options) { | ||||||
|  | 	var term = options.wiki.getTiddlerText(operator.operand,""), | ||||||
|  | 		invert = operator.prefix === "!"; | ||||||
|  | 	return options.wiki.search(term,{ | ||||||
|  | 		titles: source, | ||||||
|  | 		invert: invert, | ||||||
|  | 		exclude: [operator.operand] | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										32
									
								
								core/modules/filters/sort.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								core/modules/filters/sort.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/sort.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator for sorting | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.sort = function(source,operator,options) { | ||||||
|  | 	var results; | ||||||
|  | 	if($tw.utils.isArray(source)) { | ||||||
|  | 		results = source; | ||||||
|  | 	} else { | ||||||
|  | 		results = []; | ||||||
|  | 		$tw.utils.each(source,function(element,title) { | ||||||
|  | 			results.push(title); | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | 	options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!"); | ||||||
|  | 	return results; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										32
									
								
								core/modules/filters/sortcs.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								core/modules/filters/sortcs.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/sortcs.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator for case-sensitive sorting | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.sortcs = function(source,operator,options) { | ||||||
|  | 	var results; | ||||||
|  | 	if($tw.utils.isArray(source)) { | ||||||
|  | 		results = source; | ||||||
|  | 	} else { | ||||||
|  | 		results = []; | ||||||
|  | 		$tw.utils.each(source,function(element,title) { | ||||||
|  | 			results.push(title); | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | 	options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!",true); | ||||||
|  | 	return results; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										46
									
								
								core/modules/filters/tag.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								core/modules/filters/tag.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/tag.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator for checking for the presence of a tag | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.tag = function(source,operator,options) { | ||||||
|  | 	var results = []; | ||||||
|  | 	// Function to check an individual title | ||||||
|  | 	function checkTiddler(title) { | ||||||
|  | 		var tiddler = options.wiki.getTiddler(title); | ||||||
|  | 		if(tiddler) { | ||||||
|  | 			var match = tiddler.hasTag(operator.operand); | ||||||
|  | 			if(operator.prefix === "!") { | ||||||
|  | 				match = !match; | ||||||
|  | 			} | ||||||
|  | 			if(match) { | ||||||
|  | 				results.push(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; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										37
									
								
								core/modules/filters/tagging.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								core/modules/filters/tagging.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/tagging.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator returning all tiddlers that are tagged with the selected tiddlers | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.tagging = function(source,operator,options) { | ||||||
|  | 	var results = []; | ||||||
|  | 	// Function to check an individual title | ||||||
|  | 	function checkTiddler(title) { | ||||||
|  | 		$tw.utils.pushTop(results,options.wiki.getTiddlersWithTag(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; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										40
									
								
								core/modules/filters/tags.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								core/modules/filters/tags.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/tags.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator returning all tiddlers tagging the selected tiddlers | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.tags = function(source,operator,options) { | ||||||
|  | 	var results = []; | ||||||
|  | 	// Function to check an individual title | ||||||
|  | 	function checkTiddler(title) { | ||||||
|  | 		var tiddler = options.wiki.getTiddler(title); | ||||||
|  | 		if(tiddler && tiddler.fields.tags) { | ||||||
|  | 			$tw.utils.pushTop(results,tiddler.fields.tags); | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  | 	// 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; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										53
									
								
								core/modules/filters/title.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								core/modules/filters/title.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | /*\ | ||||||
|  | title: $:/core/modules/filters/title.js | ||||||
|  | type: application/javascript | ||||||
|  | module-type: filteroperator | ||||||
|  |  | ||||||
|  | Filter operator for comparing title fields for equality | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | Export our filter function | ||||||
|  | */ | ||||||
|  | exports.title = function(source,operator,options) { | ||||||
|  | 	var results = []; | ||||||
|  | 	// Function to check an individual title | ||||||
|  | 	function checkTiddler(title) { | ||||||
|  | 		var tiddler = options.wiki.getTiddler(title); | ||||||
|  | 		if(tiddler) { | ||||||
|  | 			var match = tiddler.fields[operator.operator] === operator.operand; | ||||||
|  | 			if(operator.prefix === "!") { | ||||||
|  | 				match = !match; | ||||||
|  | 			} | ||||||
|  | 			if(match) { | ||||||
|  | 				results.push(title); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  | 	// Iterate through the source tiddlers | ||||||
|  | 	if($tw.utils.isArray(source)) { | ||||||
|  | 		$tw.utils.each(source,function(title) { | ||||||
|  | 			checkTiddler(title); | ||||||
|  | 		}); | ||||||
|  | 	} else { | ||||||
|  | 		// If we're filtering a hashmap we change the behaviour to pass through missing tiddlers | ||||||
|  | 		if(operator.prefix !== "!") { | ||||||
|  | 			results.push(operator.operand); | ||||||
|  | 		} else { | ||||||
|  | 			$tw.utils.each(source,function(element,title) { | ||||||
|  | 				if(title !== operator.operand) { | ||||||
|  | 					checkTiddler(title); | ||||||
|  | 				} | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return results; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | })(); | ||||||
							
								
								
									
										181
									
								
								editions/test/tiddlers/tests/test-filters.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								editions/test/tiddlers/tests/test-filters.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,181 @@ | |||||||
|  | /*\ | ||||||
|  | title: test-filters.js | ||||||
|  | type: application/javascript | ||||||
|  | tags: [[$:/tags/test-spec]] | ||||||
|  |  | ||||||
|  | Tests the filtering mechanism. | ||||||
|  |  | ||||||
|  | \*/ | ||||||
|  | (function(){ | ||||||
|  |  | ||||||
|  | /*jslint node: true, browser: true */ | ||||||
|  | /*global $tw: false */ | ||||||
|  | "use strict"; | ||||||
|  |  | ||||||
|  | describe("Filter tests", function() { | ||||||
|  |  | ||||||
|  | 	// Create a wiki | ||||||
|  | 	var wiki = new $tw.Wiki(); | ||||||
|  |  | ||||||
|  | 	// Some helpers | ||||||
|  | 	var addShadowTiddler = function(fields) { | ||||||
|  | 		var tiddler = new $tw.Tiddler(fields); | ||||||
|  | 		wiki.shadowTiddlers[tiddler.fields.title] = {tiddler: tiddler}; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	// Add a few  tiddlers | ||||||
|  | 	wiki.addTiddler({ | ||||||
|  | 		title: "TiddlerOne", | ||||||
|  | 		text: "The quick brown fox in $:/TiddlerTwo", | ||||||
|  | 		tags: ["one"], | ||||||
|  | 		modifier: "JoeBloggs"}); | ||||||
|  | 	wiki.addTiddler({ | ||||||
|  | 		title: "$:/TiddlerTwo", | ||||||
|  | 		text: "The rain in Spain\nfalls mainly on the plain and [[a fourth tiddler]]", | ||||||
|  | 		tags: ["two"]}); | ||||||
|  | 	wiki.addTiddler({ | ||||||
|  | 		title: "Tiddler Three", | ||||||
|  | 		text: "The speed of sound in light\n\nThere is no TiddlerZero but TiddlerSix", | ||||||
|  | 		tags: ["one","two"]}); | ||||||
|  | 	wiki.addTiddler({ | ||||||
|  | 		title: "a fourth tiddler", | ||||||
|  | 		text: "The quality of mercy is not drained by [[Tiddler Three]]", | ||||||
|  | 		tags: []}); | ||||||
|  | 	// And some shadows | ||||||
|  | 	addShadowTiddler({ | ||||||
|  | 		title: "$:/TiddlerFive", | ||||||
|  | 		text: "Everything in federation", | ||||||
|  | 		tags: ["two"]}); | ||||||
|  | 	addShadowTiddler({ | ||||||
|  | 		title: "TiddlerSix", | ||||||
|  | 		text: "Missing inaction from TiddlerOne", | ||||||
|  | 		tags: []}); | ||||||
|  | 	addShadowTiddler({ | ||||||
|  | 		title: "TiddlerSeventh", | ||||||
|  | 		text: "TiddlerOne\nTiddler Three\na fourth tiddler\nMissingTiddler", | ||||||
|  | 		tags: []}); | ||||||
|  | 	addShadowTiddler({ | ||||||
|  | 		title: "Tiddler8", | ||||||
|  | 		text: "Tidd", | ||||||
|  | 		tags: []}); | ||||||
|  |  | ||||||
|  | 	// Our tests | ||||||
|  |  | ||||||
|  | 	it("should handle the title operator", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("TiddlerOne [title[$:/TiddlerTwo]] [[Tiddler Three]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three"); | ||||||
|  | 		expect(wiki.filterTiddlers("[!title[Tiddler Three]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,a fourth tiddler"); | ||||||
|  | 		expect(wiki.filterTiddlers("TiddlerOne [title[$:/TiddlerTwo]] [[Tiddler Three]] [[A Missing Tiddler]]").join(",")).toBe("TiddlerOne,$:/TiddlerTwo,Tiddler Three,A Missing Tiddler"); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it("should handle the field operator", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("[modifier[JoeBloggs]]").join(",")).toBe("TiddlerOne"); | ||||||
|  | 		expect(wiki.filterTiddlers("[!modifier[JoeBloggs]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,a fourth tiddler"); | ||||||
|  | 		expect(wiki.filterTiddlers("[!is[system]!modifier[JoeBloggs]]").join(",")).toBe("Tiddler Three,a fourth tiddler"); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it("should handle the prefix operator", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("[prefix[Tiddler]]").join(",")).toBe("TiddlerOne,Tiddler Three"); | ||||||
|  | 		expect(wiki.filterTiddlers("[prefix[nothing]]").join(",")).toBe(""); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it("should handle the sort and sortcs operators", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("[sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne"); | ||||||
|  | 		expect(wiki.filterTiddlers("[!sort[title]]").join(",")).toBe("TiddlerOne,Tiddler Three,a fourth tiddler,$:/TiddlerTwo"); | ||||||
|  | 		expect(wiki.filterTiddlers("[sortcs[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three,TiddlerOne,a fourth tiddler"); | ||||||
|  | 		expect(wiki.filterTiddlers("[!sortcs[title]]").join(",")).toBe("a fourth tiddler,TiddlerOne,Tiddler Three,$:/TiddlerTwo"); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it("should handle the tag operator", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("[tag[one]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne"); | ||||||
|  | 		expect(wiki.filterTiddlers("[!tag[one]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler"); | ||||||
|  | 		expect(wiki.filterTiddlers("[prefix[Tidd]tag[one]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne"); | ||||||
|  | 		expect(wiki.filterTiddlers("[!is[shadow]tag[two]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three"); | ||||||
|  | 		expect(wiki.filterTiddlers("[is[shadow]tag[two]sort[title]]").join(",")).toBe("$:/TiddlerFive"); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it("should handle the tags operator", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("[tags[]sort[title]]").join(",")).toBe("one,two"); | ||||||
|  | 		expect(wiki.filterTiddlers("[[TiddlerOne]tags[]sort[title]]").join(",")).toBe("one"); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it("should handle the tagging operator", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("[[one]tagging[]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne"); | ||||||
|  | 		expect(wiki.filterTiddlers("[[two]tagging[]sort[title]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three"); | ||||||
|  | 		expect(wiki.filterTiddlers("[is[current]tagging[]sort[title]]","one").join(",")).toBe("Tiddler Three,TiddlerOne"); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it("should handle the links operator", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("[!is[shadow]links[]sort[title]]").join(",")).toBe("a fourth tiddler,Tiddler Three,TiddlerSix,TiddlerTwo,TiddlerZero"); | ||||||
|  | 		expect(wiki.filterTiddlers("[is[shadow]links[]sort[title]]").join(",")).toBe("MissingTiddler,TiddlerOne"); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it("should handle the backlinks operator", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("[!is[shadow]backlinks[]sort[title]]").join(",")).toBe("a fourth tiddler"); | ||||||
|  | 		expect(wiki.filterTiddlers("[is[shadow]backlinks[]sort[title]]").join(",")).toBe("Tiddler Three"); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it("should handle the has operator", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("[has[modifier]sort[title]]").join(",")).toBe("TiddlerOne"); | ||||||
|  | 		expect(wiki.filterTiddlers("[!has[modifier]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three"); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it("should handle the limit operator", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("[!is[system]sort[title]limit[2]]").join(",")).toBe("a fourth tiddler,Tiddler Three"); | ||||||
|  | 		expect(wiki.filterTiddlers("[prefix[Tid]sort[title]limit[1]]").join(",")).toBe("Tiddler Three"); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it("should handle the list operator", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("[list[TiddlerSeventh]sort[title]]").join(",")).toBe("a fourth tiddler,MissingTiddler,Tiddler Three,TiddlerOne"); | ||||||
|  | 		expect(wiki.filterTiddlers("[tag[one]list[TiddlerSeventh]sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne"); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it("should handle the searchVia operator", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("[searchVia[Tiddler8]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne"); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	describe("testing the is operator",function() { | ||||||
|  |  | ||||||
|  | 		it("should handle the '[is[current]]' operator", function() { | ||||||
|  | 			expect(wiki.filterTiddlers("[is[current]]","Tiddler Three").join(",")).toBe("Tiddler Three"); | ||||||
|  | 			expect(wiki.filterTiddlers("[[Tiddler Three]is[current]]","Tiddler Three").join(",")).toBe("Tiddler Three"); | ||||||
|  | 			expect(wiki.filterTiddlers("[[$:/TiddlerTwo]is[current]]","Tiddler Three").join(",")).toBe(""); | ||||||
|  | 			expect(wiki.filterTiddlers("[!is[current]sort[title]]","Tiddler Three").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,TiddlerOne"); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		it("should handle the '[is[system]]' operator", function() { | ||||||
|  | 			expect(wiki.filterTiddlers("[is[system]]").join(",")).toBe("$:/TiddlerTwo"); | ||||||
|  | 			expect(wiki.filterTiddlers("[!is[system]sort[title]]").join(",")).toBe("a fourth tiddler,Tiddler Three,TiddlerOne"); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		it("should handle the '[is[shadow]]' operator", function() { | ||||||
|  | 			expect(wiki.filterTiddlers("[is[shadow]sort[title]]").join(",")).toBe("$:/TiddlerFive,Tiddler8,TiddlerSeventh,TiddlerSix"); | ||||||
|  | 			expect(wiki.filterTiddlers("[!is[shadow]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne"); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		it("should handle the '[is[missing]]' operator", function() { | ||||||
|  | 			expect(wiki.filterTiddlers("[is[missing]]").join(",")).toBe("TiddlerZero,TiddlerSix,TiddlerTwo"); | ||||||
|  | 			expect(wiki.filterTiddlers("[!is[missing]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,Tiddler Three,TiddlerOne"); | ||||||
|  | 			expect(wiki.filterTiddlers("[[TiddlerOne]is[missing]]").join(",")).toBe(""); | ||||||
|  | 			expect(wiki.filterTiddlers("[[TiddlerZero]is[missing]]").join(",")).toBe("TiddlerZero"); | ||||||
|  | 			expect(wiki.filterTiddlers("[!title[Tiddler Three]is[missing]]").join(",")).toBe(""); | ||||||
|  | 			expect(wiki.filterTiddlers("[!title[Tiddler Three]!is[missing]sort[title]]").join(",")).toBe("$:/TiddlerTwo,a fourth tiddler,TiddlerOne"); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 		it("should handle the '[is[orphan]]' operator", function() { | ||||||
|  | 			expect(wiki.filterTiddlers("[is[orphan]sort[title]]").join(",")).toBe("a fourth tiddler,TiddlerOne"); | ||||||
|  | 			expect(wiki.filterTiddlers("[!is[orphan]]").join(",")).toBe("$:/TiddlerTwo,Tiddler Three"); | ||||||
|  | 			expect(wiki.filterTiddlers("[[TiddlerOne]is[orphan]]").join(",")).toBe("TiddlerOne"); | ||||||
|  | 			expect(wiki.filterTiddlers("[[TiddlerOne]!is[orphan]]").join(",")).toBe(""); | ||||||
|  | 			expect(wiki.filterTiddlers("[!title[Tiddler Three]is[orphan]sort[title]]").join(",")).toBe("a fourth tiddler,TiddlerOne"); | ||||||
|  | 			expect(wiki.filterTiddlers("[!title[Tiddler Three]!is[orphan]]").join(",")).toBe("$:/TiddlerTwo"); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it("should handle the operand prefixes", function() { | ||||||
|  | 		expect(wiki.filterTiddlers("[prefix[Tiddler]] +[sort[title]]").join(",")).toBe("Tiddler Three,TiddlerOne"); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | })(); | ||||||
| @@ -46,11 +46,11 @@ Welcome to TiddlyWiki created by Jeremy Ruston; Copyright © 2004-2007 Jerem | |||||||
| <div id="contentWrapper"></div> | <div id="contentWrapper"></div> | ||||||
| <div id="contentStash"></div> | <div id="contentStash"></div> | ||||||
| <div id="shadowArea"> | <div id="shadowArea"> | ||||||
| {{{ [prefix[{shadow}]] +[sort-case-sensitive[title]] ||$:/core/templates/html-div-tiddler-remove-prefix}}} | {{{ [prefix[{shadow}]] +[sortcs[title]] ||$:/core/templates/html-div-tiddler-remove-prefix}}} | ||||||
| </div> | </div> | ||||||
| <!--POST-SHADOWAREA--> | <!--POST-SHADOWAREA--> | ||||||
| <div id="storeArea"> | <div id="storeArea"> | ||||||
| {{{ [prefix[{tiddler}]] +[sort-case-sensitive[title]] ||$:/core/templates/html-div-tiddler-remove-prefix}}} | {{{ [prefix[{tiddler}]] +[sortcs[title]] ||$:/core/templates/html-div-tiddler-remove-prefix}}} | ||||||
| {{{ [prefix[{plugin}]] ||$:/core/templates/plain-text-tiddler}}} | {{{ [prefix[{plugin}]] ||$:/core/templates/plain-text-tiddler}}} | ||||||
| {{{ [prefix[{posttiddlers}]] ||$:/core/templates/plain-text-tiddler}}} | {{{ [prefix[{posttiddlers}]] ||$:/core/templates/plain-text-tiddler}}} | ||||||
| </div> | </div> | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ A filter string consists of one or more runs of filter operators that each look | |||||||
| * ''is'': tests whether a tiddler is a member of the system defined set named in the operand (see below) | * ''is'': tests whether a tiddler is a member of the system defined set named in the operand (see below) | ||||||
| * ''has'': tests whether a tiddler has the field specified in the operand | * ''has'': tests whether a tiddler has the field specified in the operand | ||||||
| * ''sort'': sorts the tiddlers by the field specified in the operand | * ''sort'': sorts the tiddlers by the field specified in the operand | ||||||
| * ''sort-case-sensitive'': a case sensitive sort of the current tiddlers by the field specified in the operand | * ''sortcs'': a case sensitive sort of the current tiddlers by the field specified in the operand | ||||||
| * ''prefix'': tests whether a tiddlers title starts with the prefix specified in the operand | * ''prefix'': tests whether a tiddlers title starts with the prefix specified in the operand | ||||||
| * ''limit'': limits the number of subresults to the integer specified in the operand | * ''limit'': limits the number of subresults to the integer specified in the operand | ||||||
| * ''tag'': tests whether a given tag is (`[tag[mytag]]`) or is not (`[!tag[mytag]]`) present on the tiddler | * ''tag'': tests whether a given tag is (`[tag[mytag]]`) or is not (`[!tag[mytag]]`) present on the tiddler | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jeremy Ruston
					Jeremy Ruston