Bumped underscore to 1.4.4

This commit is contained in:
Dan Wilson
2013-05-13 21:48:22 +01:00
parent 2f099717bf
commit 6c8d9ec50a
4 changed files with 110 additions and 83 deletions

View File

@@ -21,7 +21,7 @@
<!-- 3rd party JS libraries --> <!-- 3rd party JS libraries -->
<script type="text/javascript" src="{{page.root}}vendor/jquery/1.7.1/jquery.js"></script> <script type="text/javascript" src="{{page.root}}vendor/jquery/1.7.1/jquery.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/underscore/1.4.2/underscore.js"></script> <script type="text/javascript" src="{{page.root}}vendor/underscore/1.4.4/underscore.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/backbone/0.9.2/backbone.js"></script> <script type="text/javascript" src="{{page.root}}vendor/backbone/0.9.2/backbone.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/mustache/0.5.0-dev/mustache.js"></script> <script type="text/javascript" src="{{page.root}}vendor/mustache/0.5.0-dev/mustache.js"></script>
<script type="text/javascript" src="{{page.root}}vendor/bootstrap/2.0.2/bootstrap.js"></script> <script type="text/javascript" src="{{page.root}}vendor/bootstrap/2.0.2/bootstrap.js"></script>

View File

@@ -9,7 +9,7 @@
<link rel="stylesheet" href="../css/flot.css" type="text/css" media="screen" /> <link rel="stylesheet" href="../css/flot.css" type="text/css" media="screen" />
<script type="text/javascript" src="../vendor/jquery/1.7.1/jquery.js"></script> <script type="text/javascript" src="../vendor/jquery/1.7.1/jquery.js"></script>
<script type="text/javascript" src="../vendor/underscore/1.4.2/underscore.js"></script> <script type="text/javascript" src="../vendor/underscore/1.4.4/underscore.js"></script>
<script type="text/javascript" src="../vendor/backbone/0.9.2/backbone.js"></script> <script type="text/javascript" src="../vendor/backbone/0.9.2/backbone.js"></script>
<script type="text/javascript" src="../vendor/jquery-ui-1.8.14.custom.min.js"></script> <script type="text/javascript" src="../vendor/jquery-ui-1.8.14.custom.min.js"></script>
<script type="text/javascript" src="../vendor/jquery.flot/0.7/jquery.flot.js"></script> <script type="text/javascript" src="../vendor/jquery.flot/0.7/jquery.flot.js"></script>

View File

@@ -9,7 +9,7 @@
<link rel="stylesheet" href="../css/map.css"> <link rel="stylesheet" href="../css/map.css">
<script type="text/javascript" src="../vendor/jquery/1.7.1/jquery.js"></script> <script type="text/javascript" src="../vendor/jquery/1.7.1/jquery.js"></script>
<script type="text/javascript" src="../vendor/underscore/1.4.2/underscore.js"></script> <script type="text/javascript" src="../vendor/underscore/1.4.4/underscore.js"></script>
<script type="text/javascript" src="../vendor/backbone/0.9.2/backbone.js"></script> <script type="text/javascript" src="../vendor/backbone/0.9.2/backbone.js"></script>
<script type="text/javascript" src="../vendor/moment/1.6.2/moment.js"></script> <script type="text/javascript" src="../vendor/moment/1.6.2/moment.js"></script>
<script type="text/javascript" src="../vendor/mustache/0.5.0-dev/mustache.js"></script> <script type="text/javascript" src="../vendor/mustache/0.5.0-dev/mustache.js"></script>

View File

@@ -1,12 +1,13 @@
// Underscore.js 1.4.2 // Underscore.js 1.4.4
// http://underscorejs.org // ===================
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore may be freely distributed under the MIT license.
(function() { // > http://underscorejs.org
// > (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
// > Underscore may be freely distributed under the MIT license.
// Baseline setup // Baseline setup
// -------------- // --------------
(function() {
// Establish the root object, `window` in the browser, or `global` on the server. // Establish the root object, `window` in the browser, or `global` on the server.
var root = this; var root = this;
@@ -24,7 +25,6 @@
var push = ArrayProto.push, var push = ArrayProto.push,
slice = ArrayProto.slice, slice = ArrayProto.slice,
concat = ArrayProto.concat, concat = ArrayProto.concat,
unshift = ArrayProto.unshift,
toString = ObjProto.toString, toString = ObjProto.toString,
hasOwnProperty = ObjProto.hasOwnProperty; hasOwnProperty = ObjProto.hasOwnProperty;
@@ -61,11 +61,11 @@
} }
exports._ = _; exports._ = _;
} else { } else {
root['_'] = _; root._ = _;
} }
// Current version. // Current version.
_.VERSION = '1.4.2'; _.VERSION = '1.4.4';
// Collection Functions // Collection Functions
// -------------------- // --------------------
@@ -102,6 +102,8 @@
return results; return results;
}; };
var reduceError = 'Reduce of empty array with no initial value';
// **Reduce** builds up a single result from a list of values, aka `inject`, // **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
@@ -119,7 +121,7 @@
memo = iterator.call(context, memo, value, index, list); memo = iterator.call(context, memo, value, index, list);
} }
}); });
if (!initial) throw new TypeError('Reduce of empty array with no initial value'); if (!initial) throw new TypeError(reduceError);
return memo; return memo;
}; };
@@ -130,7 +132,7 @@
if (obj == null) obj = []; if (obj == null) obj = [];
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
if (context) iterator = _.bind(iterator, context); if (context) iterator = _.bind(iterator, context);
return arguments.length > 2 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
} }
var length = obj.length; var length = obj.length;
if (length !== +length) { if (length !== +length) {
@@ -146,7 +148,7 @@
memo = iterator.call(context, memo, obj[index], index, list); memo = iterator.call(context, memo, obj[index], index, list);
} }
}); });
if (!initial) throw new TypeError('Reduce of empty array with no initial value'); if (!initial) throw new TypeError(reduceError);
return memo; return memo;
}; };
@@ -177,12 +179,9 @@
// Return all the elements for which a truth test fails. // Return all the elements for which a truth test fails.
_.reject = function(obj, iterator, context) { _.reject = function(obj, iterator, context) {
var results = []; return _.filter(obj, function(value, index, list) {
if (obj == null) return results; return !iterator.call(context, value, index, list);
each(obj, function(value, index, list) { }, context);
if (!iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
}; };
// Determine whether all of the elements match a truth test. // Determine whether all of the elements match a truth test.
@@ -216,20 +215,19 @@
// Determine if the array or object contains a given value (using `===`). // Determine if the array or object contains a given value (using `===`).
// Aliased as `include`. // Aliased as `include`.
_.contains = _.include = function(obj, target) { _.contains = _.include = function(obj, target) {
var found = false; if (obj == null) return false;
if (obj == null) return found;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
found = any(obj, function(value) { return any(obj, function(value) {
return value === target; return value === target;
}); });
return found;
}; };
// Invoke a method (with arguments) on every item in a collection. // Invoke a method (with arguments) on every item in a collection.
_.invoke = function(obj, method) { _.invoke = function(obj, method) {
var args = slice.call(arguments, 2); var args = slice.call(arguments, 2);
var isFunc = _.isFunction(method);
return _.map(obj, function(value) { return _.map(obj, function(value) {
return (_.isFunction(method) ? method : value[method]).apply(value, args); return (isFunc ? method : value[method]).apply(value, args);
}); });
}; };
@@ -239,10 +237,10 @@
}; };
// Convenience version of a common use case of `filter`: selecting only objects // Convenience version of a common use case of `filter`: selecting only objects
// with specific `key:value` pairs. // containing specific `key:value` pairs.
_.where = function(obj, attrs) { _.where = function(obj, attrs, first) {
if (_.isEmpty(attrs)) return []; if (_.isEmpty(attrs)) return first ? null : [];
return _.filter(obj, function(value) { return _[first ? 'find' : 'filter'](obj, function(value) {
for (var key in attrs) { for (var key in attrs) {
if (attrs[key] !== value[key]) return false; if (attrs[key] !== value[key]) return false;
} }
@@ -250,6 +248,12 @@
}); });
}; };
// Convenience version of a common use case of `find`: getting the first object
// containing specific `key:value` pairs.
_.findWhere = function(obj, attrs) {
return _.where(obj, attrs, true);
};
// Return the maximum element or (element-based computation). // Return the maximum element or (element-based computation).
// Can't optimize arrays of integers longer than 65,535 elements. // Can't optimize arrays of integers longer than 65,535 elements.
// See: https://bugs.webkit.org/show_bug.cgi?id=80797 // See: https://bugs.webkit.org/show_bug.cgi?id=80797
@@ -258,7 +262,7 @@
return Math.max.apply(Math, obj); return Math.max.apply(Math, obj);
} }
if (!iterator && _.isEmpty(obj)) return -Infinity; if (!iterator && _.isEmpty(obj)) return -Infinity;
var result = {computed : -Infinity}; var result = {computed : -Infinity, value: -Infinity};
each(obj, function(value, index, list) { each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value; var computed = iterator ? iterator.call(context, value, index, list) : value;
computed >= result.computed && (result = {value : value, computed : computed}); computed >= result.computed && (result = {value : value, computed : computed});
@@ -272,7 +276,7 @@
return Math.min.apply(Math, obj); return Math.min.apply(Math, obj);
} }
if (!iterator && _.isEmpty(obj)) return Infinity; if (!iterator && _.isEmpty(obj)) return Infinity;
var result = {computed : Infinity}; var result = {computed : Infinity, value: Infinity};
each(obj, function(value, index, list) { each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value; var computed = iterator ? iterator.call(context, value, index, list) : value;
computed < result.computed && (result = {value : value, computed : computed}); computed < result.computed && (result = {value : value, computed : computed});
@@ -321,7 +325,7 @@
// An internal function used for aggregate "group by" operations. // An internal function used for aggregate "group by" operations.
var group = function(obj, value, context, behavior) { var group = function(obj, value, context, behavior) {
var result = {}; var result = {};
var iterator = lookupIterator(value); var iterator = lookupIterator(value || _.identity);
each(obj, function(value, index) { each(obj, function(value, index) {
var key = iterator.call(context, value, index, obj); var key = iterator.call(context, value, index, obj);
behavior(result, key, value); behavior(result, key, value);
@@ -341,7 +345,7 @@
// either a string attribute to count by, or a function that returns the // either a string attribute to count by, or a function that returns the
// criterion. // criterion.
_.countBy = function(obj, value, context) { _.countBy = function(obj, value, context) {
return group(obj, value, context, function(result, key, value) { return group(obj, value, context, function(result, key) {
if (!_.has(result, key)) result[key] = 0; if (!_.has(result, key)) result[key] = 0;
result[key]++; result[key]++;
}); });
@@ -363,12 +367,14 @@
// Safely convert anything iterable into a real, live array. // Safely convert anything iterable into a real, live array.
_.toArray = function(obj) { _.toArray = function(obj) {
if (!obj) return []; if (!obj) return [];
if (obj.length === +obj.length) return slice.call(obj); if (_.isArray(obj)) return slice.call(obj);
if (obj.length === +obj.length) return _.map(obj, _.identity);
return _.values(obj); return _.values(obj);
}; };
// Return the number of elements in an object. // Return the number of elements in an object.
_.size = function(obj) { _.size = function(obj) {
if (obj == null) return 0;
return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
}; };
@@ -379,6 +385,7 @@
// values in the array. Aliased as `head` and `take`. The **guard** check // values in the array. Aliased as `head` and `take`. The **guard** check
// allows it to work with `_.map`. // allows it to work with `_.map`.
_.first = _.head = _.take = function(array, n, guard) { _.first = _.head = _.take = function(array, n, guard) {
if (array == null) return void 0;
return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
}; };
@@ -393,6 +400,7 @@
// Get the last element of an array. Passing **n** will return the last N // Get the last element of an array. Passing **n** will return the last N
// values in the array. The **guard** check allows it to work with `_.map`. // values in the array. The **guard** check allows it to work with `_.map`.
_.last = function(array, n, guard) { _.last = function(array, n, guard) {
if (array == null) return void 0;
if ((n != null) && !guard) { if ((n != null) && !guard) {
return slice.call(array, Math.max(array.length - n, 0)); return slice.call(array, Math.max(array.length - n, 0));
} else { } else {
@@ -410,7 +418,7 @@
// Trim out all falsy values from an array. // Trim out all falsy values from an array.
_.compact = function(array) { _.compact = function(array) {
return _.filter(array, function(value){ return !!value; }); return _.filter(array, _.identity);
}; };
// Internal implementation of a recursive `flatten` function. // Internal implementation of a recursive `flatten` function.
@@ -439,6 +447,11 @@
// been sorted, you have the option of using a faster algorithm. // been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`. // Aliased as `unique`.
_.uniq = _.unique = function(array, isSorted, iterator, context) { _.uniq = _.unique = function(array, isSorted, iterator, context) {
if (_.isFunction(isSorted)) {
context = iterator;
iterator = isSorted;
isSorted = false;
}
var initial = iterator ? _.map(array, iterator, context) : array; var initial = iterator ? _.map(array, iterator, context) : array;
var results = []; var results = [];
var seen = []; var seen = [];
@@ -491,6 +504,7 @@
// pairs, or two parallel arrays of the same length -- one of keys, and one of // pairs, or two parallel arrays of the same length -- one of keys, and one of
// the corresponding values. // the corresponding values.
_.object = function(list, values) { _.object = function(list, values) {
if (list == null) return {};
var result = {}; var result = {};
for (var i = 0, l = list.length; i < l; i++) { for (var i = 0, l = list.length; i < l; i++) {
if (values) { if (values) {
@@ -561,25 +575,23 @@
// Function (ahem) Functions // Function (ahem) Functions
// ------------------ // ------------------
// Reusable constructor function for prototype setting.
var ctor = function(){};
// Create a function bound to a given object (assigning `this`, and arguments, // Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Binding with arguments is also known as `curry`. // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
// Delegates to **ECMAScript 5**'s native `Function.bind` if available. // available.
// We check for `func.bind` first, to fail fast when `func` is undefined. _.bind = function(func, context) {
_.bind = function bind(func, context) {
var bound, args;
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
if (!_.isFunction(func)) throw new TypeError; var args = slice.call(arguments, 2);
args = slice.call(arguments, 2); return function() {
return bound = function() { return func.apply(context, args.concat(slice.call(arguments)));
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); };
ctor.prototype = func.prototype; };
var self = new ctor;
var result = func.apply(self, args.concat(slice.call(arguments))); // Partially apply a function by creating a version that has had some of its
if (Object(result) === result) return result; // arguments pre-filled, without changing its dynamic `this` context.
return self; _.partial = function(func) {
var args = slice.call(arguments, 1);
return function() {
return func.apply(this, args.concat(slice.call(arguments)));
}; };
}; };
@@ -587,7 +599,7 @@
// all callbacks defined on an object belong to it. // all callbacks defined on an object belong to it.
_.bindAll = function(obj) { _.bindAll = function(obj) {
var funcs = slice.call(arguments, 1); var funcs = slice.call(arguments, 1);
if (funcs.length == 0) funcs = _.functions(obj); if (funcs.length === 0) funcs = _.functions(obj);
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
return obj; return obj;
}; };
@@ -618,25 +630,26 @@
// Returns a function, that, when invoked, will only be triggered at most once // Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time. // during a given window of time.
_.throttle = function(func, wait) { _.throttle = function(func, wait) {
var context, args, timeout, throttling, more, result; var context, args, timeout, result;
var whenDone = _.debounce(function(){ more = throttling = false; }, wait); var previous = 0;
return function() {
context = this; args = arguments;
var later = function() { var later = function() {
previous = new Date;
timeout = null; timeout = null;
if (more) {
result = func.apply(context, args); result = func.apply(context, args);
}
whenDone();
}; };
if (!timeout) timeout = setTimeout(later, wait); return function() {
if (throttling) { var now = new Date;
more = true; var remaining = wait - (now - previous);
} else { context = this;
throttling = true; args = arguments;
if (remaining <= 0) {
clearTimeout(timeout);
timeout = null;
previous = now;
result = func.apply(context, args); result = func.apply(context, args);
} else if (!timeout) {
timeout = setTimeout(later, remaining);
} }
whenDone();
return result; return result;
}; };
}; };
@@ -754,9 +767,11 @@
// Extend a given object with all the properties in passed-in object(s). // Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) { _.extend = function(obj) {
each(slice.call(arguments, 1), function(source) { each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) { for (var prop in source) {
obj[prop] = source[prop]; obj[prop] = source[prop];
} }
}
}); });
return obj; return obj;
}; };
@@ -784,9 +799,11 @@
// Fill in a given object with default properties. // Fill in a given object with default properties.
_.defaults = function(obj) { _.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) { each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) { for (var prop in source) {
if (obj[prop] == null) obj[prop] = source[prop]; if (obj[prop] == null) obj[prop] = source[prop];
} }
}
}); });
return obj; return obj;
}; };
@@ -950,7 +967,7 @@
// Is a given object a finite number? // Is a given object a finite number?
_.isFinite = function(obj) { _.isFinite = function(obj) {
return _.isNumber(obj) && isFinite(obj); return isFinite(obj) && !isNaN(parseFloat(obj));
}; };
// Is the given value `NaN`? (NaN is the only number which does not equal itself). // Is the given value `NaN`? (NaN is the only number which does not equal itself).
@@ -996,7 +1013,9 @@
// Run a function **n** times. // Run a function **n** times.
_.times = function(n, iterator, context) { _.times = function(n, iterator, context) {
for (var i = 0; i < n; i++) iterator.call(context, i); var accum = Array(n);
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
return accum;
}; };
// Return a random integer between min and max (inclusive). // Return a random integer between min and max (inclusive).
@@ -1005,7 +1024,7 @@
max = min; max = min;
min = 0; min = 0;
} }
return min + (0 | Math.random() * (max - min + 1)); return min + Math.floor(Math.random() * (max - min + 1));
}; };
// List of HTML entities for escaping. // List of HTML entities for escaping.
@@ -1061,7 +1080,7 @@
// Useful for temporary DOM ids. // Useful for temporary DOM ids.
var idCounter = 0; var idCounter = 0;
_.uniqueId = function(prefix) { _.uniqueId = function(prefix) {
var id = idCounter++; var id = ++idCounter + '';
return prefix ? prefix + id : id; return prefix ? prefix + id : id;
}; };
@@ -1096,6 +1115,7 @@
// Underscore templating handles arbitrary delimiters, preserves whitespace, // Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code. // and correctly escapes quotes within interpolated code.
_.template = function(text, data, settings) { _.template = function(text, data, settings) {
var render;
settings = _.defaults({}, settings, _.templateSettings); settings = _.defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation. // Combine delimiters into one regular expression via alternation.
@@ -1111,11 +1131,18 @@
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset) source += text.slice(index, offset)
.replace(escaper, function(match) { return '\\' + escapes[match]; }); .replace(escaper, function(match) { return '\\' + escapes[match]; });
source +=
escape ? "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'" : if (escape) {
interpolate ? "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'" : source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
evaluate ? "';\n" + evaluate + "\n__p+='" : ''; }
if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length; index = offset + match.length;
return match;
}); });
source += "';\n"; source += "';\n";
@@ -1127,7 +1154,7 @@
source + "return __p;\n"; source + "return __p;\n";
try { try {
var render = new Function(settings.variable || 'obj', '_', source); render = new Function(settings.variable || 'obj', '_', source);
} catch (e) { } catch (e) {
e.source = source; e.source = source;
throw e; throw e;