diff options
| author | Xavier Morel <xmo@openerp.com> | 2011-07-14 13:57:45 +0200 |
|---|---|---|
| committer | Xavier Morel <xmo@openerp.com> | 2011-07-14 13:57:45 +0200 |
| commit | e35bb246d352965474076c23efb0dc5460b9e474 (patch) | |
| tree | 8bcc65d87c53918d0c616924a57d63024ac58493 /addons/base/static/lib/underscore/underscore.js | |
| parent | 68ab4a39e33d2003a858040edb3f8ad516593f85 (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.js | 90 |
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')); |
