Skip to content
Browse files

Merge pull request #50 from manzhikov/master

Updated underscore.js to v.1.5.1
  • Loading branch information...
2 parents bcea43c + 3d70148 commit e0ac0cadf972d5acd08e7e836decea014fa68365 @meleyal committed
Showing with 134 additions and 103 deletions.
  1. +1 −1 lib/backbone-on-rails/version.rb
  2. +1 −1 test/backbone-on-rails_test.rb
  3. +132 −101 vendor/assets/javascripts/underscore.js
View
2 lib/backbone-on-rails/version.rb
@@ -1,3 +1,3 @@
module BackboneOnRails
- VERSION = "1.0.0.0"
+ VERSION = "1.0.0.1"
end
View
2 test/backbone-on-rails_test.rb
@@ -10,7 +10,7 @@ def setup
test "underscore.js is found as an asset" do
assert_not_nil @app.assets["underscore"]
- assert_file "#{BackboneOnRails::Engine.root}/vendor/assets/javascripts/underscore.js", /1.4.4/
+ assert_file "#{BackboneOnRails::Engine.root}/vendor/assets/javascripts/underscore.js", /1.5.1/
end
test "backbone.js is found as an asset" do
View
233 vendor/assets/javascripts/underscore.js
@@ -1,15 +1,14 @@
-// Underscore.js 1.4.4
-// ===================
+// Underscore.js 1.5.1
+// http://underscorejs.org
+// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// Underscore may be freely distributed under the MIT license.
-// > http://underscorejs.org
-// > (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
-// > Underscore may be freely distributed under the MIT license.
-
-// Baseline setup
-// --------------
(function() {
- // Establish the root object, `window` in the browser, or `global` on the server.
+ // Baseline setup
+ // --------------
+
+ // Establish the root object, `window` in the browser, or `exports` on the server.
var root = this;
// Save the previous value of the `_` variable.
@@ -22,11 +21,12 @@
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
// Create quick reference variables for speed access to core prototypes.
- var push = ArrayProto.push,
- slice = ArrayProto.slice,
- concat = ArrayProto.concat,
- toString = ObjProto.toString,
- hasOwnProperty = ObjProto.hasOwnProperty;
+ var
+ push = ArrayProto.push,
+ slice = ArrayProto.slice,
+ concat = ArrayProto.concat,
+ toString = ObjProto.toString,
+ hasOwnProperty = ObjProto.hasOwnProperty;
// All **ECMAScript 5** native function implementations that we hope to use
// are declared here.
@@ -65,7 +65,7 @@
}
// Current version.
- _.VERSION = '1.4.4';
+ _.VERSION = '1.5.1';
// Collection Functions
// --------------------
@@ -78,14 +78,13 @@
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
- for (var i = 0, l = obj.length; i < l; i++) {
+ for (var i = 0, length = obj.length; i < length; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
- for (var key in obj) {
- if (_.has(obj, key)) {
- if (iterator.call(context, obj[key], key, obj) === breaker) return;
- }
+ var keys = _.keys(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
}
}
};
@@ -97,7 +96,7 @@
if (obj == null) return results;
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
each(obj, function(value, index, list) {
- results[results.length] = iterator.call(context, value, index, list);
+ results.push(iterator.call(context, value, index, list));
});
return results;
};
@@ -172,7 +171,7 @@
if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
each(obj, function(value, index, list) {
- if (iterator.call(context, value, index, list)) results[results.length] = value;
+ if (iterator.call(context, value, index, list)) results.push(value);
});
return results;
};
@@ -239,7 +238,7 @@
// Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs.
_.where = function(obj, attrs, first) {
- if (_.isEmpty(attrs)) return first ? null : [];
+ if (_.isEmpty(attrs)) return first ? void 0 : [];
return _[first ? 'find' : 'filter'](obj, function(value) {
for (var key in attrs) {
if (attrs[key] !== value[key]) return false;
@@ -256,7 +255,7 @@
// Return the maximum element or (element-based computation).
// Can't optimize arrays of integers longer than 65,535 elements.
- // See: https://bugs.webkit.org/show_bug.cgi?id=80797
+ // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.max.apply(Math, obj);
@@ -265,7 +264,7 @@
var result = {computed : -Infinity, value: -Infinity};
each(obj, function(value, index, list) {
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});
});
return result.value;
};
@@ -307,9 +306,9 @@
var iterator = lookupIterator(value);
return _.pluck(_.map(obj, function(value, index, list) {
return {
- value : value,
- index : index,
- criteria : iterator.call(context, value, index, list)
+ value: value,
+ index: index,
+ criteria: iterator.call(context, value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria;
@@ -318,38 +317,41 @@
if (a > b || a === void 0) return 1;
if (a < b || b === void 0) return -1;
}
- return left.index < right.index ? -1 : 1;
+ return left.index - right.index;
}), 'value');
};
// An internal function used for aggregate "group by" operations.
- var group = function(obj, value, context, behavior) {
- var result = {};
- var iterator = lookupIterator(value || _.identity);
- each(obj, function(value, index) {
- var key = iterator.call(context, value, index, obj);
- behavior(result, key, value);
- });
- return result;
+ var group = function(behavior) {
+ return function(obj, value, context) {
+ var result = {};
+ var iterator = value == null ? _.identity : lookupIterator(value);
+ each(obj, function(value, index) {
+ var key = iterator.call(context, value, index, obj);
+ behavior(result, key, value);
+ });
+ return result;
+ };
};
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
- _.groupBy = function(obj, value, context) {
- return group(obj, value, context, function(result, key, value) {
- (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
- });
- };
+ _.groupBy = group(function(result, key, value) {
+ (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
+ });
+
+ // Indexes the object's values by a criterion, similar to `groupBy`, but for
+ // when you know that your index values will be unique.
+ _.indexBy = group(function(result, key, value) {
+ result[key] = value;
+ });
// Counts instances of an object that group by a certain criterion. Pass
// either a string attribute to count by, or a function that returns the
// criterion.
- _.countBy = function(obj, value, context) {
- return group(obj, value, context, function(result, key) {
- if (!_.has(result, key)) result[key] = 0;
- result[key]++;
- });
- };
+ _.countBy = group(function(result, key, value) {
+ _.has(result, key) ? result[key]++ : result[key] = 1;
+ });
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
@@ -364,7 +366,7 @@
return low;
};
- // Safely convert anything iterable into a real, live array.
+ // Safely create a real, live array from anything iterable.
_.toArray = function(obj) {
if (!obj) return [];
if (_.isArray(obj)) return slice.call(obj);
@@ -386,7 +388,7 @@
// allows it to work with `_.map`.
_.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 ? array[0] : slice.call(array, 0, n);
};
// Returns everything but the last entry of the array. Especially useful on
@@ -401,10 +403,10 @@
// values in the array. The **guard** check allows it to work with `_.map`.
_.last = function(array, n, guard) {
if (array == null) return void 0;
- if ((n != null) && !guard) {
- return slice.call(array, Math.max(array.length - n, 0));
- } else {
+ if ((n == null) || guard) {
return array[array.length - 1];
+ } else {
+ return slice.call(array, Math.max(array.length - n, 0));
}
};
@@ -423,8 +425,11 @@
// Internal implementation of a recursive `flatten` function.
var flatten = function(input, shallow, output) {
+ if (shallow && _.every(input, _.isArray)) {
+ return concat.apply(output, input);
+ }
each(input, function(value) {
- if (_.isArray(value)) {
+ if (_.isArray(value) || _.isArguments(value)) {
shallow ? push.apply(output, value) : flatten(value, shallow, output);
} else {
output.push(value);
@@ -433,7 +438,7 @@
return output;
};
- // Return a completely flattened version of an array.
+ // Flatten out an array, either recursively (by default), or just one level.
_.flatten = function(array, shallow) {
return flatten(array, shallow, []);
};
@@ -467,7 +472,7 @@
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
- return _.uniq(concat.apply(ArrayProto, arguments));
+ return _.uniq(_.flatten(arguments, true));
};
// Produce an array that contains every item shared between all the
@@ -491,11 +496,10 @@
// 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'));
+ var length = _.max(_.pluck(arguments, "length").concat(0));
var results = new Array(length);
for (var i = 0; i < length; i++) {
- results[i] = _.pluck(args, "" + i);
+ results[i] = _.pluck(arguments, '' + i);
}
return results;
};
@@ -506,7 +510,7 @@
_.object = function(list, values) {
if (list == null) return {};
var result = {};
- for (var i = 0, l = list.length; i < l; i++) {
+ for (var i = 0, length = list.length; i < length; i++) {
if (values) {
result[list[i]] = values[i];
} else {
@@ -524,17 +528,17 @@
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
- var i = 0, l = array.length;
+ var i = 0, length = array.length;
if (isSorted) {
if (typeof isSorted == 'number') {
- i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
+ i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
} else {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
- for (; i < l; i++) if (array[i] === item) return i;
+ for (; i < length; i++) if (array[i] === item) return i;
return -1;
};
@@ -560,11 +564,11 @@
}
step = arguments[2] || 1;
- var len = Math.max(Math.ceil((stop - start) / step), 0);
+ var length = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
- var range = new Array(len);
+ var range = new Array(length);
- while(idx < len) {
+ while(idx < length) {
range[idx++] = start;
start += step;
}
@@ -575,14 +579,25 @@
// Function (ahem) Functions
// ------------------
+ // Reusable constructor function for prototype setting.
+ var ctor = function(){};
+
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
// available.
_.bind = function(func, context) {
- if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
- var args = slice.call(arguments, 2);
- return function() {
- return func.apply(context, args.concat(slice.call(arguments)));
+ var args, bound;
+ if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
+ if (!_.isFunction(func)) throw new TypeError;
+ args = slice.call(arguments, 2);
+ return bound = function() {
+ if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
+ ctor.prototype = func.prototype;
+ var self = new ctor;
+ ctor.prototype = null;
+ var result = func.apply(self, args.concat(slice.call(arguments)));
+ if (Object(result) === result) return result;
+ return self;
};
};
@@ -599,7 +614,7 @@
// all callbacks defined on an object belong to it.
_.bindAll = function(obj) {
var funcs = slice.call(arguments, 1);
- if (funcs.length === 0) funcs = _.functions(obj);
+ if (funcs.length === 0) throw new Error("bindAll must be passed function names");
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
return obj;
};
@@ -628,17 +643,23 @@
};
// Returns a function, that, when invoked, will only be triggered at most once
- // during a given window of time.
- _.throttle = function(func, wait) {
- var context, args, timeout, result;
+ // during a given window of time. Normally, the throttled function will run
+ // as much as it can, without ever going more than once per `wait` duration;
+ // but if you'd like to disable the execution on the leading edge, pass
+ // `{leading: false}`. To disable execution on the trailing edge, ditto.
+ _.throttle = function(func, wait, options) {
+ var context, args, result;
+ var timeout = null;
var previous = 0;
+ options || (options = {});
var later = function() {
- previous = new Date;
+ previous = options.leading === false ? 0 : new Date;
timeout = null;
result = func.apply(context, args);
};
return function() {
var now = new Date;
+ if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
@@ -647,7 +668,7 @@
timeout = null;
previous = now;
result = func.apply(context, args);
- } else if (!timeout) {
+ } else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
@@ -659,7 +680,8 @@
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
- var timeout, result;
+ var result;
+ var timeout = null;
return function() {
var context = this, args = arguments;
var later = function() {
@@ -713,7 +735,6 @@
// Returns a function that will only be executed after being called N times.
_.after = function(times, func) {
- if (times <= 0) return func();
return function() {
if (--times < 1) {
return func.apply(this, arguments);
@@ -729,28 +750,39 @@
_.keys = nativeKeys || function(obj) {
if (obj !== Object(obj)) throw new TypeError('Invalid object');
var keys = [];
- for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
+ for (var key in obj) if (_.has(obj, key)) keys.push(key);
return keys;
};
// Retrieve the values of an object's properties.
_.values = function(obj) {
- var values = [];
- for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var values = new Array(length);
+ for (var i = 0; i < length; i++) {
+ values[i] = obj[keys[i]];
+ }
return values;
};
// Convert an object into a list of `[key, value]` pairs.
_.pairs = function(obj) {
- var pairs = [];
- for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var pairs = new Array(length);
+ for (var i = 0; i < length; i++) {
+ pairs[i] = [keys[i], obj[keys[i]]];
+ }
return pairs;
};
// Invert the keys and values of an object. The values must be serializable.
_.invert = function(obj) {
var result = {};
- for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
+ var keys = _.keys(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ result[obj[keys[i]]] = keys[i];
+ }
return result;
};
@@ -801,7 +833,7 @@
each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) {
- if (obj[prop] == null) obj[prop] = source[prop];
+ if (obj[prop] === void 0) obj[prop] = source[prop];
}
}
});
@@ -825,7 +857,7 @@
// Internal recursive comparison function for `isEqual`.
var eq = function(a, b, aStack, bStack) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
- // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
+ // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
if (a === b) return a !== 0 || 1 / a == 1 / b;
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
@@ -867,6 +899,13 @@
// unique nested structures.
if (aStack[length] == a) return bStack[length] == b;
}
+ // Objects with different constructors are not equivalent, but `Object`s
+ // from different frames are.
+ var aCtor = a.constructor, bCtor = b.constructor;
+ if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
+ _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
+ return false;
+ }
// Add the first object to the stack of traversed objects.
aStack.push(a);
bStack.push(b);
@@ -883,13 +922,6 @@
}
}
} else {
- // Objects with different constructors are not equivalent, but `Object`s
- // from different frames are.
- var aCtor = a.constructor, bCtor = b.constructor;
- if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
- _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
- return false;
- }
// Deep compare objects.
for (var key in a) {
if (_.has(a, key)) {
@@ -1013,7 +1045,7 @@
// Run a function **n** times.
_.times = function(n, iterator, context) {
- var accum = Array(n);
+ var accum = Array(Math.max(0, n));
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
return accum;
};
@@ -1034,8 +1066,7 @@
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
- "'": '&#x27;',
- '/': '&#x2F;'
+ "'": '&#x27;'
}
};
entityMap.unescape = _.invert(entityMap.escape);
@@ -1056,17 +1087,17 @@
};
});
- // If the value of the named property is a function then invoke it;
- // otherwise, return it.
+ // If the value of the named `property` is a function then invoke it with the
+ // `object` as context; otherwise, return it.
_.result = function(object, property) {
- if (object == null) return null;
+ if (object == null) return void 0;
var value = object[property];
return _.isFunction(value) ? value.call(object) : value;
};
// Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
- each(_.functions(obj), function(name){
+ each(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
@@ -1224,4 +1255,4 @@
});
-}).call(this);
+}).call(this);

0 comments on commit e0ac0ca

Please sign in to comment.
Something went wrong with that request. Please try again.