Browse files

Added not operator and handle arrays as properties in LHS of filterin…

…g operators for nesting
  • Loading branch information...
1 parent 23262be commit 2d4d2d5403e4898f07bd7f4bff416f212728fe27 @kriszyp kriszyp committed Nov 29, 2010
Showing with 33 additions and 22 deletions.
  1. +33 −22 lib/js-array.js
View
55 lib/js-array.js
@@ -8,7 +8,9 @@
define(["exports", "./parser"], function(exports, parser){
var parseQuery = parser.parseQuery;
-
+var stringify = JSON.stringify || function(str){
+ return '"' + str.replace(/"/g, "\\\"") + '"';
+};
exports.jsOperatorMap = {
"eq" : "===",
"ne" : "!==",
@@ -17,6 +19,7 @@ exports.jsOperatorMap = {
"lt" : "<",
"gt" : ">"
};
+var negated = false;
exports.operators = {
sort: function(){
var terms = [];
@@ -45,15 +48,14 @@ exports.operators = {
"in": filter(function(value, values){
return values.indexOf(value) > -1;
}),
- notin: filter(function(value, values){
- return values.indexOf(value) === -1;
- }),
- contains: filter(function(values, value){
- return values.indexOf(value) > -1;
- }),
- notcontains: filter(function(values, value){
- return values.indexOf(value) === -1;
- }),
+ not: function(expression){
+ negated = true;
+ try{
+ return expression.call(this);
+ }finally{
+ negated = false;
+ }
+ },
any: filter(function(array, value){
if(typeof value == "function"){
return array.some(function(i){
@@ -271,13 +273,14 @@ exports.operators = {
}
};
exports.filter = filter;
-function filter(condition){
+function filter(condition, not){
+ // convert to boolean right now
var filter = function(property, second){
var args = arguments;
var filtered = [];
for(var i = 0, length = this.length; i < length; i++){
var item = this[i];
- if(condition(evaluateProperty(item, property), second)){
+ if(!condition(evaluateProperty(item, property), second) == negated){
filtered.push(item);
}
}
@@ -299,15 +302,15 @@ function reducer(func){
}
exports.evaluateProperty = evaluateProperty;
function evaluateProperty(object, property){
- if(property.indexOf(".") === -1){
- return object[decodeURIComponent(property)];
- }
- else{
- property.split(".").forEach(function(part){
+ if(property instanceof Array){
+ property.forEach(function(part){
object = object[decodeURIComponent(part)];
});
return object;
}
+ else{
+ return object[decodeURIComponent(property)];
+ }
};
var conditionEvaluator = exports.conditionEvaluator = function(condition){
var jsOperator = exports.jsOperatorMap[term.name];
@@ -326,7 +329,6 @@ exports.query = query;
exports.missingOperator = function(operator){
throw new Error("Operator " + operator + " is not defined");
}
-function relay(){return this;} // TODO: may be control by options?
function query(query, options, target){
options = options || {};
query = parseQuery(query, options.parameters);
@@ -344,9 +346,18 @@ function query(query, options, target){
var jsOperator = exports.jsOperatorMap[value.name];
if(jsOperator){
// item['foo.bar'] ==> (item && item.foo && item.foo.bar && ...)
- var path = String(value.args[0]);
- var item = path ? path.split('.').map(function(x,i,a){return 'item.'+a.slice(0,i+1).join('.')}).join('&&') : 'item';
- item = '('+item+')';
+ var path = value.args[0];
+ if(path instanceof Array){
+ var item = "(";
+ var escaped = [];
+ for(var i = 0;i < path.length; i++){
+ escaped.push(stringify(path[i]));
+ item += (item.length > 1 ? "&&" : "") + "item[" + escaped.join("][") + ']';
+ }
+ }else{
+ var item = "(item[" + stringify(path) + "]";
+ }
+ item += ')';
if (jsOperator === '===' && value.args[1] instanceof RegExp){
// N.B. matching requires String
item = 'String('+item + '||"")';
@@ -360,7 +371,7 @@ function query(query, options, target){
")})";
}
}else{
- return typeof value === "number" ? value : JSON.stringify(value);
+ return typeof value === "number" ? value : stringify(value);
}
}
var evaluator = eval("(function(target){return " + queryToJS(query) + ".call(target);})");

0 comments on commit 2d4d2d5

Please sign in to comment.