Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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

…g operators for nesting
  • Loading branch information...
commit 2d4d2d5403e4898f07bd7f4bff416f212728fe27 1 parent 23262be
@kriszyp kriszyp authored
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);})");
Please sign in to comment.
Something went wrong with that request. Please try again.