vendor/assets/javascripts/underscore.js in backbone-rails-0.5.0 vs vendor/assets/javascripts/underscore.js in backbone-rails-0.5.2

- old
+ new

@@ -1,6 +1,6 @@ -// Underscore.js 1.1.6 +// Underscore.js 1.1.7 // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc. // Underscore is freely distributable under the MIT license. // Portions of Underscore are inspired or borrowed from Prototype, // Oliver Steele's Functional, and John Resig's Micro-Templating. // For all details and documentation: @@ -53,29 +53,30 @@ // global object. if (typeof module !== 'undefined' && module.exports) { module.exports = _; _._ = _; } else { - root._ = _; + // Exported as a string, for Closure Compiler "advanced" mode. + root['_'] = _; } // Current version. - _.VERSION = '1.1.6'; + _.VERSION = '1.1.7'; // Collection Functions // -------------------- // The cornerstone, an `each` implementation, aka `forEach`. - // Handles objects implementing `forEach`, arrays, and raw objects. + // Handles objects with the built-in `forEach`, arrays, and raw objects. // Delegates to **ECMAScript 5**'s native `forEach` if available. var each = _.each = _.forEach = function(obj, iterator, context) { if (obj == null) return; if (nativeForEach && obj.forEach === nativeForEach) { obj.forEach(iterator, context); - } else if (_.isNumber(obj.length)) { + } else if (obj.length === +obj.length) { for (var i = 0, l = obj.length; i < l; i++) { - if (iterator.call(context, obj[i], i, obj) === breaker) return; + if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return; } } else { for (var key in obj) { if (hasOwnProperty.call(obj, key)) { if (iterator.call(context, obj[key], key, obj) === breaker) return; @@ -104,11 +105,11 @@ if (nativeReduce && obj.reduce === nativeReduce) { if (context) iterator = _.bind(iterator, context); return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); } each(obj, function(value, index, list) { - if (!initial && index === 0) { + if (!initial) { memo = value; initial = true; } else { memo = iterator.call(context, memo, value, index, list); } @@ -179,18 +180,18 @@ // Determine if at least one element in the object matches a truth test. // Delegates to **ECMAScript 5**'s native `some` if available. // Aliased as `any`. var any = _.some = _.any = function(obj, iterator, context) { - iterator || (iterator = _.identity); + iterator = iterator || _.identity; var result = false; if (obj == null) return result; if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); each(obj, function(value, index, list) { - if (result = iterator.call(context, value, index, list)) return breaker; + if (result |= iterator.call(context, value, index, list)) return breaker; }); - return result; + return !!result; }; // Determine if a given value is included in the array or object using `===`. // Aliased as `contains`. _.include = _.contains = function(obj, target) { @@ -249,10 +250,20 @@ var a = left.criteria, b = right.criteria; return a < b ? -1 : a > b ? 1 : 0; }), 'value'); }; + // Groups the object's values by a criterion produced by an iterator + _.groupBy = function(obj, iterator) { + var result = {}; + each(obj, function(value, index) { + var key = iterator(value, index); + (result[key] || (result[key] = [])).push(value); + }); + return result; + }; + // Use a comparator function to figure out at what index an object should // be inserted so as to maintain order. Uses binary search. _.sortedIndex = function(array, obj, iterator) { iterator || (iterator = _.identity); var low = 0, high = array.length; @@ -265,11 +276,11 @@ // Safely convert anything iterable into a real, live array. _.toArray = function(iterable) { if (!iterable) return []; if (iterable.toArray) return iterable.toArray(); - if (_.isArray(iterable)) return iterable; + if (_.isArray(iterable)) return slice.call(iterable); if (_.isArguments(iterable)) return slice.call(iterable); return _.values(iterable); }; // Return the number of elements in an object. @@ -314,12 +325,11 @@ }, []); }; // Return a version of the array that does not contain the specified value(s). _.without = function(array) { - var values = slice.call(arguments, 1); - return _.filter(array, function(value){ return !_.include(values, value); }); + return _.difference(array, slice.call(arguments, 1)); }; // Produce a duplicate-free version of the array. If the array has already // been sorted, you have the option of using a faster algorithm. // Aliased as `unique`. @@ -328,21 +338,33 @@ if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el; return memo; }, []); }; + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(_.flatten(arguments)); + }; + // Produce an array that contains every item shared between all the - // passed-in arrays. - _.intersect = function(array) { + // passed-in arrays. (Aliased as "intersect" for back-compat.) + _.intersection = _.intersect = function(array) { var rest = slice.call(arguments, 1); return _.filter(_.uniq(array), function(item) { return _.every(rest, function(other) { return _.indexOf(other, item) >= 0; }); }); }; + // Take the difference between one array and another. + // Only the elements present in just the first array will remain. + _.difference = function(array, other) { + return _.filter(array, function(value){ return !_.include(other, value); }); + }; + // Zip together multiple lists into a single array -- elements that share // an index go together. _.zip = function() { var args = slice.call(arguments); var length = _.max(_.pluck(args, 'length')); @@ -500,11 +522,11 @@ // consuming the return value of the function that follows. _.compose = function() { var funcs = slice.call(arguments); return function() { var args = slice.call(arguments); - for (var i=funcs.length-1; i >= 0; i--) { + for (var i = funcs.length - 1; i >= 0; i--) { args = [funcs[i].apply(this, args)]; } return args[0]; }; }; @@ -535,11 +557,15 @@ }; // Return a sorted list of the function names available on the object. // Aliased as `methods` _.functions = _.methods = function(obj) { - return _.filter(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort(); + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); }; // Extend a given object with all the properties in passed-in object(s). _.extend = function(obj) { each(slice.call(arguments, 1), function(source) { @@ -587,10 +613,11 @@ // Unwrap any wrapped objects. if (a._chain) a = a._wrapped; if (b._chain) b = b._wrapped; // One of them implements an isEqual()? if (a.isEqual) return a.isEqual(b); + if (b.isEqual) return b.isEqual(a); // Check dates' integer values. if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime(); // Both are NaN? if (_.isNaN(a) && _.isNaN(b)) return false; // Compare regular expressions. @@ -626,9 +653,14 @@ // Is a given value an array? // Delegates to ECMA5's native Array.isArray _.isArray = nativeIsArray || function(obj) { return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + return obj === Object(obj); }; // Is a given variable an arguments object? _.isArguments = function(obj) { return !!(obj && hasOwnProperty.call(obj, 'callee'));