summaryrefslogtreecommitdiff
path: root/addons/base/static/lib/underscore/underscore.js
diff options
context:
space:
mode:
authorXavier Morel <xmo@openerp.com>2011-07-14 13:57:45 +0200
committerXavier Morel <xmo@openerp.com>2011-07-14 13:57:45 +0200
commite35bb246d352965474076c23efb0dc5460b9e474 (patch)
tree8bcc65d87c53918d0c616924a57d63024ac58493 /addons/base/static/lib/underscore/underscore.js
parent68ab4a39e33d2003a858040edb3f8ad516593f85 (diff)
[IMP] update underscore to 1.1.7 for _.groupBy
bzr revid: xmo@openerp.com-20110714115745-r5rd69skkk8917ek
Diffstat (limited to 'addons/base/static/lib/underscore/underscore.js')
-rw-r--r--addons/base/static/lib/underscore/underscore.js90
1 files changed, 67 insertions, 23 deletions
diff --git a/addons/base/static/lib/underscore/underscore.js b/addons/base/static/lib/underscore/underscore.js
index c627740a02d..4f56013259b 100644
--- a/addons/base/static/lib/underscore/underscore.js
+++ b/addons/base/static/lib/underscore/underscore.js
@@ -1,4 +1,4 @@
-// Underscore.js 1.1.5
+// 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,
@@ -55,25 +55,26 @@
module.exports = _;
_._ = _;
} else {
- root._ = _;
+ // Exported as a string, for Closure Compiler "advanced" mode.
+ root['_'] = _;
}
// Current version.
- _.VERSION = '1.1.5';
+ _.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) {
@@ -106,7 +107,7 @@
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 {
@@ -168,7 +169,6 @@
// Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`.
_.every = _.all = function(obj, iterator, context) {
- iterator = iterator || _.identity;
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
@@ -187,9 +187,9 @@
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 `===`.
@@ -208,7 +208,7 @@
_.invoke = function(obj, method) {
var args = slice.call(arguments, 2);
return _.map(obj, function(value) {
- return (method ? value[method] : value).apply(value, args);
+ return (method.call ? method || value : value[method]).apply(value, args);
});
};
@@ -252,10 +252,20 @@
}), '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;
+ iterator || (iterator = _.identity);
var low = 0, high = array.length;
while (low < high) {
var mid = (low + high) >> 1;
@@ -268,7 +278,7 @@
_.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);
};
@@ -317,8 +327,7 @@
// 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
@@ -331,9 +340,15 @@
}, []);
};
+ // 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) {
@@ -342,6 +357,12 @@
});
};
+ // 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() {
@@ -408,8 +429,9 @@
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Binding with arguments is also known as `curry`.
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
+ // We check for `func.bind` first, to fail fast when `func` is undefined.
_.bind = function(func, obj) {
- if (nativeBind && func.bind === nativeBind) return func.bind.apply(func, slice.call(arguments, 1));
+ if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
var args = slice.call(arguments, 2);
return function() {
return func.apply(obj, args.concat(slice.call(arguments)));
@@ -428,7 +450,7 @@
// Memoize an expensive function by storing its results.
_.memoize = function(func, hasher) {
var memo = {};
- hasher = hasher || _.identity;
+ hasher || (hasher = _.identity);
return function() {
var key = hasher.apply(this, arguments);
return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
@@ -502,13 +524,21 @@
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];
};
};
+ // Returns a function that will only be executed after being called N times.
+ _.after = function(times, func) {
+ return function() {
+ if (--times < 1) { return func.apply(this, arguments); }
+ };
+ };
+
+
// Object Functions
// ----------------
@@ -529,13 +559,19 @@
// 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) {
- for (var prop in source) obj[prop] = source[prop];
+ for (var prop in source) {
+ if (source[prop] !== void 0) obj[prop] = source[prop];
+ }
});
return obj;
};
@@ -543,7 +579,9 @@
// Fill in a given object with default properties.
_.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) {
- for (var prop in source) if (obj[prop] == null) obj[prop] = source[prop];
+ for (var prop in source) {
+ if (obj[prop] == null) obj[prop] = source[prop];
+ }
});
return obj;
};
@@ -577,6 +615,7 @@
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?
@@ -618,6 +657,11 @@
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'));