vendor/assets/javascripts/precompiled/development/object.js in sugar-rails-1.3.6 vs vendor/assets/javascripts/precompiled/development/object.js in sugar-rails-1.3.7

- old
+ new

@@ -7,21 +7,21 @@ * http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ * ***/ var ObjectTypeMethods = 'isObject,isNaN'.split(','); - var ObjectHashMethods = 'keys,values,each,merge,clone,equal,watch,tap,has'.split(','); + var ObjectHashMethods = 'keys,values,select,reject,each,merge,clone,equal,watch,tap,has'.split(','); function setParamsObject(obj, param, value, deep) { var reg = /^(.+?)(\[.*\])$/, paramIsArray, match, allKeys, key; if(deep !== false && (match = param.match(reg))) { key = match[1]; allKeys = match[2].replace(/^\[|\]$/g, '').split(']['); allKeys.forEach(function(k) { paramIsArray = !k || k.match(/^\d+$/); if(!key && isArray(obj)) key = obj.length; - if(!obj[key]) { + if(!hasOwnProperty(obj, key)) { obj[key] = paramIsArray ? [] : {}; } obj = obj[key]; key = k; }); @@ -36,11 +36,37 @@ } else { obj[param] = value; } } + function matchKey(key, match) { + if(isRegExp(match)) { + return match.test(key); + } else if(isObjectPrimitive(match)) { + return hasOwnProperty(match, key); + } else { + return key === string(match); + } + } + function selectFromObject(obj, args, select) { + var result = {}, match; + iterateOverObject(obj, function(key, value) { + match = false; + flattenedArgs(args, function(arg) { + if(matchKey(key, arg)) { + match = true; + } + }, 1); + if(match === select) { + result[key] = value; + } + }); + return result; + } + + /*** * @method Object.is[Type](<obj>) * @returns Boolean * @short Returns true if <obj> is an object of that type. * @extra %isObject% will return false on anything that is not an object literal, including instances of inherited classes. Note also that %isNaN% will ONLY return true if the object IS %NaN%. It does not mean the same as browser native %isNaN%, which returns true for anything that is "not a number". @@ -75,11 +101,15 @@ } function buildObjectExtend() { extend(object, false, function(){ return arguments.length === 0; }, { 'extend': function() { - buildObjectInstanceMethods(ObjectTypeMethods.concat(ObjectHashMethods), object); + var methods = ObjectTypeMethods.concat(ObjectHashMethods) + if(typeof EnumerableMethods !== 'undefined') { + methods = methods.concat(EnumerableMethods); + } + buildObjectInstanceMethods(methods, object); } }); } extend(object, false, true, { @@ -269,13 +299,17 @@ * Object.clone() -> {} * Object.extended({foo:'bar'}).clone() -> { foo: 'bar' } * ***/ 'clone': function(obj, deep) { + var target; if(!isObjectPrimitive(obj)) return obj; - if(array.isArray(obj)) return obj.concat(); - var target = obj instanceof Hash ? new Hash() : {}; + if (obj instanceof Hash) { + target = new Hash; + } else { + target = new obj.constructor; + } return object.merge(target, obj, deep); }, /*** * @method Object.fromQueryString(<str>, [deep] = true) @@ -336,9 +370,45 @@ * Object.has({ hasOwnProperty: true }, 'foo') -> false * ***/ 'has': function (obj, key) { return hasOwnProperty(obj, key); + }, + + /*** + * @method select(<obj>, <find>, ...) + * @returns Object + * @short Builds a new object containing the values specified in <find>. + * @extra When <find> is a string, that single key will be selected. It can also be a regex, selecting any key that matches, or an object which will match if the key also exists in that object, effectively doing an "intersect" operation on that object. Multiple selections may also be passed as an array or directly as enumerated arguments. %select% is available as an instance method on extended objects. + * @example + * + * Object.select({a:1,b:2}, 'a') -> {a:1} + * Object.select({a:1,b:2}, /[a-z]/) -> {a:1,ba:2} + * Object.select({a:1,b:2}, {a:1}) -> {a:1} + * Object.select({a:1,b:2}, 'a', 'b') -> {a:1,b:2} + * Object.select({a:1,b:2}, ['a', 'b']) -> {a:1,b:2} + * + ***/ + 'select': function (obj) { + return selectFromObject(obj, arguments, true); + }, + + /*** + * @method reject(<obj>, <find>, ...) + * @returns Object + * @short Builds a new object containing all values except those specified in <find>. + * @extra When <find> is a string, that single key will be rejected. It can also be a regex, rejecting any key that matches, or an object which will match if the key also exists in that object, effectively "subtracting" that object. Multiple selections may also be passed as an array or directly as enumerated arguments. %reject% is available as an instance method on extended objects. + * @example + * + * Object.reject({a:1,b:2}, 'a') -> {b:2} + * Object.reject({a:1,b:2}, /[a-z]/) -> {} + * Object.reject({a:1,b:2}, {a:1}) -> {b:2} + * Object.reject({a:1,b:2}, 'a', 'b') -> {} + * Object.reject({a:1,b:2}, ['a', 'b']) -> {} + * + ***/ + 'reject': function (obj) { + return selectFromObject(obj, arguments, false); } });