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'));