[Pkg-javascript-commits] [backbone] 09/12: Upgrading test suite to latest Underscore.
Jonas Smedegaard
js at moszumanska.debian.org
Sat May 3 16:59:40 UTC 2014
This is an automated email from the git hooks/post-receive script.
js pushed a commit to tag 0.3.3
in repository backbone.
commit 418b77ffffe9366a053d3ed73d8d7f6a204e188e
Author: Jeremy Ashkenas <jashkenas at gmail.com>
Date: Wed Dec 1 12:55:05 2010 -0500
Upgrading test suite to latest Underscore.
---
test/test.html | 2 +-
.../{underscore-1.1.0.js => underscore-1.1.3.js} | 405 +++++++++++----------
2 files changed, 221 insertions(+), 186 deletions(-)
diff --git a/test/test.html b/test/test.html
index cd43ee2..b8adb6c 100644
--- a/test/test.html
+++ b/test/test.html
@@ -7,7 +7,7 @@
<script type="text/javascript" src="vendor/jquery-1.4.2.js"></script>
<script type="text/javascript" src="vendor/qunit.js"></script>
<script type="text/javascript" src="vendor/jslitmus.js"></script>
- <script type="text/javascript" src="vendor/underscore-1.1.0.js"></script>
+ <script type="text/javascript" src="vendor/underscore-1.1.3.js"></script>
<script type="text/javascript" src="../backbone.js"></script>
<script type="text/javascript" src="events.js"></script>
diff --git a/test/vendor/underscore-1.1.0.js b/test/vendor/underscore-1.1.3.js
similarity index 64%
rename from test/vendor/underscore-1.1.0.js
rename to test/vendor/underscore-1.1.3.js
index 60bf47c..887d039 100644
--- a/test/vendor/underscore-1.1.0.js
+++ b/test/vendor/underscore-1.1.3.js
@@ -1,37 +1,36 @@
-// Underscore.js
-// (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
-// Underscore is freely distributable under the terms of the MIT license.
-// Portions of Underscore are inspired by or borrowed from Prototype.js,
-// Oliver Steele's Functional, and John Resig's Micro-Templating.
-// For all details and documentation:
-// http://documentcloud.github.com/underscore
+// Underscore.js 1.1.3
+// (c) 2010 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:
+// http://documentcloud.github.com/underscore
(function() {
- // ------------------------- Baseline setup ---------------------------------
- // Establish the root object, "window" in the browser, or "global" on the server.
+ // Baseline setup
+ // --------------
+
+ // Establish the root object, `window` in the browser, or `global` on the server.
var root = this;
- // Save the previous value of the "_" variable.
+ // Save the previous value of the `_` variable.
var previousUnderscore = root._;
- // Establish the object that gets thrown to break out of a loop iteration.
- var breaker = typeof StopIteration !== 'undefined' ? StopIteration : '__break__';
-
- // Quick regexp-escaping function, because JS doesn't have RegExp.escape().
- var escapeRegExp = function(s) { return s.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1'); };
+ // Establish the object that gets returned to break out of a loop iteration.
+ var breaker = {};
// Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array.prototype, ObjProto = Object.prototype;
// Create quick reference variables for speed access to core prototypes.
- var slice = ArrayProto.slice,
- unshift = ArrayProto.unshift,
- toString = ObjProto.toString,
- hasOwnProperty = ObjProto.hasOwnProperty,
- propertyIsEnumerable = ObjProto.propertyIsEnumerable;
+ var slice = ArrayProto.slice,
+ unshift = ArrayProto.unshift,
+ toString = ObjProto.toString,
+ hasOwnProperty = ObjProto.hasOwnProperty;
- // All ECMA5 native implementations we hope to use are declared here.
+ // All **ECMAScript 5** native function implementations that we hope to use
+ // are declared here.
var
nativeForEach = ArrayProto.forEach,
nativeMap = ArrayProto.map,
@@ -48,91 +47,102 @@
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) { return new wrapper(obj); };
- // Export the Underscore object for CommonJS.
- if (typeof exports !== 'undefined') exports._ = _;
-
- // Export underscore to global scope.
- root._ = _;
+ // Export the Underscore object for **CommonJS**, with backwards-compatibility
+ // for the old `require()` API. If we're not in CommonJS, add `_` to the
+ // global object.
+ if (typeof module !== 'undefined' && module.exports) {
+ module.exports = _;
+ _._ = _;
+ } else {
+ root._ = _;
+ }
// Current version.
- _.VERSION = '1.1.0';
-
- // ------------------------ Collection Functions: ---------------------------
-
- // The cornerstone, an each implementation.
- // Handles objects implementing forEach, arrays, and raw objects.
- // Delegates to JavaScript 1.6's native forEach if available.
- var each = _.forEach = function(obj, iterator, context) {
- try {
- if (nativeForEach && obj.forEach === nativeForEach) {
- obj.forEach(iterator, context);
- } else if (_.isNumber(obj.length)) {
- for (var i = 0, l = obj.length; i < l; i++) iterator.call(context, obj[i], i, obj);
- } else {
- for (var key in obj) {
- if (hasOwnProperty.call(obj, key)) iterator.call(context, obj[key], key, obj);
+ _.VERSION = '1.1.3';
+
+ // Collection Functions
+ // --------------------
+
+ // The cornerstone, an `each` implementation, aka `forEach`.
+ // Handles objects implementing `forEach`, arrays, and raw objects.
+ // Delegates to **ECMAScript 5**'s native `forEach` if available.
+ var each = _.each = _.forEach = function(obj, iterator, context) {
+ var value;
+ if (nativeForEach && obj.forEach === nativeForEach) {
+ obj.forEach(iterator, context);
+ } else if (_.isNumber(obj.length)) {
+ for (var i = 0, l = obj.length; i < l; i++) {
+ if (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;
}
}
- } catch(e) {
- if (e != breaker) throw e;
}
- return obj;
};
// Return the results of applying the iterator to each element.
- // Delegates to JavaScript 1.6's native map if available.
+ // Delegates to **ECMAScript 5**'s native `map` if available.
_.map = function(obj, iterator, context) {
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
var results = [];
each(obj, function(value, index, list) {
- results.push(iterator.call(context, value, index, list));
+ results[results.length] = iterator.call(context, value, index, list);
});
return results;
};
- // Reduce builds up a single result from a list of values, aka inject, or foldl.
- // Delegates to JavaScript 1.8's native reduce if available.
- _.reduce = function(obj, iterator, memo, context) {
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
+ // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
+ _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
+ var initial = memo !== void 0;
if (nativeReduce && obj.reduce === nativeReduce) {
if (context) iterator = _.bind(iterator, context);
- return obj.reduce(iterator, memo);
+ return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
}
each(obj, function(value, index, list) {
- memo = iterator.call(context, memo, value, index, list);
+ if (!initial && index === 0) {
+ memo = value;
+ } else {
+ memo = iterator.call(context, memo, value, index, list);
+ }
});
return memo;
};
- // The right-associative version of reduce, also known as foldr. Uses
- // Delegates to JavaScript 1.8's native reduceRight if available.
- _.reduceRight = function(obj, iterator, memo, context) {
+ // The right-associative version of reduce, also known as `foldr`.
+ // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
+ _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
if (context) iterator = _.bind(iterator, context);
- return obj.reduceRight(iterator, memo);
+ return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
}
- var reversed = _.clone(_.toArray(obj)).reverse();
+ var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
return _.reduce(reversed, iterator, memo, context);
};
- // Return the first value which passes a truth test.
- _.detect = function(obj, iterator, context) {
+ // Return the first value which passes a truth test. Aliased as `detect`.
+ _.find = _.detect = function(obj, iterator, context) {
var result;
- each(obj, function(value, index, list) {
+ any(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) {
result = value;
- _.breakLoop();
+ return true;
}
});
return result;
};
// Return all the elements that pass a truth test.
- // Delegates to JavaScript 1.6's native filter if available.
- _.filter = function(obj, iterator, context) {
+ // Delegates to **ECMAScript 5**'s native `filter` if available.
+ // Aliased as `select`.
+ _.filter = _.select = function(obj, iterator, context) {
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
var results = [];
each(obj, function(value, index, list) {
- iterator.call(context, value, index, list) && results.push(value);
+ if (iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
};
@@ -141,59 +151,62 @@
_.reject = function(obj, iterator, context) {
var results = [];
each(obj, function(value, index, list) {
- !iterator.call(context, value, index, list) && results.push(value);
+ if (!iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
};
// Determine whether all of the elements match a truth test.
- // Delegates to JavaScript 1.6's native every if available.
- _.every = function(obj, iterator, context) {
+ // Delegates to **ECMAScript 5**'s native `every` if available.
+ // Aliased as `all`.
+ _.every = _.all = function(obj, iterator, context) {
iterator = iterator || _.identity;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
var result = true;
each(obj, function(value, index, list) {
- if (!(result = result && iterator.call(context, value, index, list))) _.breakLoop();
+ if (!(result = result && iterator.call(context, value, index, list))) return breaker;
});
return result;
};
// Determine if at least one element in the object matches a truth test.
- // Delegates to JavaScript 1.6's native some if available.
- _.some = function(obj, iterator, context) {
+ // Delegates to **ECMAScript 5**'s native `some` if available.
+ // Aliased as `any`.
+ var any = _.some = _.any = function(obj, iterator, context) {
iterator = iterator || _.identity;
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
var result = false;
each(obj, function(value, index, list) {
- if (result = iterator.call(context, value, index, list)) _.breakLoop();
+ if (result = iterator.call(context, value, index, list)) return breaker;
});
return result;
};
- // Determine if a given value is included in the array or object using '==='.
- _.include = function(obj, target) {
+ // Determine if a given value is included in the array or object using `===`.
+ // Aliased as `contains`.
+ _.include = _.contains = function(obj, target) {
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
var found = false;
- each(obj, function(value) {
- if (found = value === target) _.breakLoop();
+ any(obj, function(value) {
+ if (found = value === target) return true;
});
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) {
- var args = _.rest(arguments, 2);
+ var args = slice.call(arguments, 2);
return _.map(obj, function(value) {
return (method ? value[method] : value).apply(value, args);
});
};
- // Convenience version of a common use case of map: fetching a property.
+ // Convenience version of a common use case of `map`: fetching a property.
_.pluck = function(obj, key) {
return _.map(obj, function(value){ return value[key]; });
};
- // Return the maximum item or (item-based computation).
+ // Return the maximum element or (element-based computation).
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
var result = {computed : -Infinity};
@@ -240,7 +253,7 @@
return low;
};
- // Convert anything iterable into a real, live array.
+ // Safely convert anything iterable into a real, live array.
_.toArray = function(iterable) {
if (!iterable) return [];
if (iterable.toArray) return iterable.toArray();
@@ -254,20 +267,21 @@
return _.toArray(obj).length;
};
- // -------------------------- Array Functions: ------------------------------
+ // Array Functions
+ // ---------------
- // Get the first element of an array. Passing "n" will return the first N
- // values in the array. Aliased as "head". The "guard" check allows it to work
- // with _.map.
- _.first = function(array, n, guard) {
+ // Get the first element of an array. Passing **n** will return the first N
+ // values in the array. Aliased as `head`. The **guard** check allows it to work
+ // with `_.map`.
+ _.first = _.head = function(array, n, guard) {
return n && !guard ? slice.call(array, 0, n) : array[0];
};
- // Returns everything but the first entry of the array. Aliased as "tail".
- // Especially useful on the arguments object. Passing an "index" will return
- // the rest of the values in the array from that index onward. The "guard"
- //check allows it to work with _.map.
- _.rest = function(array, index, guard) {
+ // Returns everything but the first entry of the array. Aliased as `tail`.
+ // Especially useful on the arguments object. Passing an **index** will return
+ // the rest of the values in the array from that index onward. The **guard**
+ // check allows it to work with `_.map`.
+ _.rest = _.tail = function(array, index, guard) {
return slice.call(array, _.isUndefined(index) || guard ? 1 : index);
};
@@ -285,22 +299,23 @@
_.flatten = function(array) {
return _.reduce(array, function(memo, value) {
if (_.isArray(value)) return memo.concat(_.flatten(value));
- memo.push(value);
+ memo[memo.length] = value;
return memo;
}, []);
};
// Return a version of the array that does not contain the specified value(s).
_.without = function(array) {
- var values = _.rest(arguments);
+ var values = slice.call(arguments, 1);
return _.filter(array, function(value){ return !_.include(values, value); });
};
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
- _.uniq = function(array, isSorted) {
+ // Aliased as `unique`.
+ _.uniq = _.unique = function(array, isSorted) {
return _.reduce(array, function(memo, el, i) {
- if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo.push(el);
+ if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el;
return memo;
}, []);
};
@@ -308,7 +323,7 @@
// Produce an array that contains every item shared between all the
// passed-in arrays.
_.intersect = function(array) {
- var rest = _.rest(arguments);
+ var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
return _.indexOf(other, item) >= 0;
@@ -319,17 +334,17 @@
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
- var args = _.toArray(arguments);
+ var args = slice.call(arguments);
var length = _.max(_.pluck(args, 'length'));
var results = new Array(length);
- for (var i = 0; i < length; i++) results[i] = _.pluck(args, String(i));
+ for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
return results;
};
- // If the browser doesn't supply us with indexOf (I'm looking at you, MSIE),
- // we need this function. Return the position of the first occurence of an
+ // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
+ // we need this function. Return the position of the first occurrence of an
// item in an array, or -1 if the item is not included in the array.
- // Delegates to JavaScript 1.8's native indexOf if available.
+ // Delegates to **ECMAScript 5**'s native `indexOf` if available.
_.indexOf = function(array, item) {
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
for (var i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
@@ -337,7 +352,7 @@
};
- // Delegates to JavaScript 1.6's native lastIndexOf if available.
+ // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
_.lastIndexOf = function(array, item) {
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
var i = array.length;
@@ -346,36 +361,40 @@
};
// Generate an integer Array containing an arithmetic progression. A port of
- // the native Python range() function. See:
- // http://docs.python.org/library/functions.html#range
+ // the native Python `range()` function. See
+ // [the Python documentation](http://docs.python.org/library/functions.html#range).
_.range = function(start, stop, step) {
- var a = _.toArray(arguments);
- var solo = a.length <= 1;
- var start = solo ? 0 : a[0], stop = solo ? a[0] : a[1], step = a[2] || 1;
- var len = Math.ceil((stop - start) / step);
- if (len <= 0) return [];
- var range = new Array(len);
- for (var i = start, idx = 0; true; i += step) {
- if ((step > 0 ? i - stop : stop - i) >= 0) return range;
- range[idx++] = i;
+ var args = slice.call(arguments),
+ solo = args.length <= 1,
+ start = solo ? 0 : args[0],
+ stop = solo ? args[0] : args[1],
+ step = args[2] || 1,
+ len = Math.max(Math.ceil((stop - start) / step), 0),
+ idx = 0,
+ range = new Array(len);
+ while (idx < len) {
+ range[idx++] = start;
+ start += step;
}
+ return range;
};
- // ----------------------- Function Functions: ------------------------------
+ // Function (ahem) Functions
+ // ------------------
- // Create a function bound to a given object (assigning 'this', and arguments,
- // optionally). Binding with arguments is also known as 'curry'.
+ // Create a function bound to a given object (assigning `this`, and arguments,
+ // optionally). Binding with arguments is also known as `curry`.
_.bind = function(func, obj) {
- var args = _.rest(arguments, 2);
+ var args = slice.call(arguments, 2);
return function() {
- return func.apply(obj || {}, args.concat(_.toArray(arguments)));
+ return func.apply(obj || {}, args.concat(slice.call(arguments)));
};
};
// Bind all of an object's methods to that object. Useful for ensuring that
// all callbacks defined on an object belong to it.
_.bindAll = function(obj) {
- var funcs = _.rest(arguments);
+ var funcs = slice.call(arguments, 1);
if (funcs.length == 0) funcs = _.functions(obj);
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
return obj;
@@ -394,14 +413,41 @@
// Delays a function for the given number of milliseconds, and then calls
// it with the arguments supplied.
_.delay = function(func, wait) {
- var args = _.rest(arguments, 2);
+ var args = slice.call(arguments, 2);
return setTimeout(function(){ return func.apply(func, args); }, wait);
};
// Defers a function, scheduling it to run after the current call stack has
// cleared.
_.defer = function(func) {
- return _.delay.apply(_, [func, 1].concat(_.rest(arguments)));
+ return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
+ };
+
+ // Internal function used to implement `_.throttle` and `_.debounce`.
+ var limit = function(func, wait, debounce) {
+ var timeout;
+ return function() {
+ var context = this, args = arguments;
+ var throttler = function() {
+ timeout = null;
+ func.apply(context, args);
+ };
+ if (debounce) clearTimeout(timeout);
+ if (debounce || !timeout) timeout = setTimeout(throttler, wait);
+ };
+ };
+
+ // Returns a function, that, when invoked, will only be triggered at most once
+ // during a given window of time.
+ _.throttle = function(func, wait) {
+ return limit(func, wait, false);
+ };
+
+ // Returns a function, that, as long as it continues to be invoked, will not
+ // be triggered. The function will be called after it stops being called for
+ // N milliseconds.
+ _.debounce = function(func, wait) {
+ return limit(func, wait, true);
};
// Returns the first function passed as an argument to the second,
@@ -409,7 +455,7 @@
// conditionally execute the original function.
_.wrap = function(func, wrapper) {
return function() {
- var args = [func].concat(_.toArray(arguments));
+ var args = [func].concat(slice.call(arguments));
return wrapper.apply(wrapper, args);
};
};
@@ -417,9 +463,9 @@
// Returns a function that is the composition of a list of functions, each
// consuming the return value of the function that follows.
_.compose = function() {
- var funcs = _.toArray(arguments);
+ var funcs = slice.call(arguments);
return function() {
- var args = _.toArray(arguments);
+ var args = slice.call(arguments);
for (var i=funcs.length-1; i >= 0; i--) {
args = [funcs[i].apply(this, args)];
}
@@ -427,14 +473,15 @@
};
};
- // ------------------------- Object Functions: ------------------------------
+ // Object Functions
+ // ----------------
// Retrieve the names of an object's properties.
- // Delegates to ECMA5's native Object.keys
+ // Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = nativeKeys || function(obj) {
if (_.isArray(obj)) return _.range(0, obj.length);
var keys = [];
- for (var key in obj) if (hasOwnProperty.call(obj, key)) keys.push(key);
+ for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
return keys;
};
@@ -444,13 +491,14 @@
};
// Return a sorted list of the function names available on the object.
- _.functions = function(obj) {
+ // Aliased as `methods`
+ _.functions = _.methods = function(obj) {
return _.filter(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort();
};
// Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) {
- each(_.rest(arguments), function(source) {
+ each(slice.call(arguments, 1), function(source) {
for (var prop in source) obj[prop] = source[prop];
});
return obj;
@@ -458,12 +506,12 @@
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
- if (_.isArray(obj)) return obj.slice(0);
- return _.extend({}, obj);
+ return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
// Invokes interceptor with the obj, and then returns obj.
- // The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain.
+ // The primary purpose of this method is to "tap into" a method chain, in
+ // order to perform operations on intermediate results within the chain.
_.tap = function(obj, interceptor) {
interceptor(obj);
return obj;
@@ -525,7 +573,7 @@
// Is a given variable an arguments object?
_.isArguments = function(obj) {
- return obj && obj.callee;
+ return !!(obj && obj.callee);
};
// Is a given value a function?
@@ -540,7 +588,13 @@
// Is a given value a number?
_.isNumber = function(obj) {
- return (obj === +obj) || (toString.call(obj) === '[object Number]');
+ return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
+ };
+
+ // Is the given value NaN -- this one is interesting. NaN != NaN, and
+ // isNaN(undefined) == true, so we make sure it's a number first.
+ _.isNaN = function(obj) {
+ return toString.call(obj) === '[object Number]' && isNaN(obj);
};
// Is a given value a boolean?
@@ -558,12 +612,6 @@
return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
};
- // Is the given value NaN -- this one is interesting. NaN != NaN, and
- // isNaN(undefined) == true, so we make sure it's a number first.
- _.isNaN = function(obj) {
- return _.isNumber(obj) && isNaN(obj);
- };
-
// Is a given value equal to null?
_.isNull = function(obj) {
return obj === null;
@@ -571,12 +619,13 @@
// Is a given variable undefined?
_.isUndefined = function(obj) {
- return typeof obj == 'undefined';
+ return obj === void 0;
};
- // -------------------------- Utility Functions: ----------------------------
+ // Utility Functions
+ // -----------------
- // Run Underscore.js in noConflict mode, returning the '_' variable to its
+ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
// previous owner. Returns a reference to the Underscore object.
_.noConflict = function() {
root._ = previousUnderscore;
@@ -588,16 +637,11 @@
return value;
};
- // Run a function n times.
+ // Run a function **n** times.
_.times = function (n, iterator, context) {
for (var i = 0; i < n; i++) iterator.call(context, i);
};
- // Break out of the middle of an iteration.
- _.breakLoop = function() {
- throw breaker;
- };
-
// Add your own custom functions to the Underscore object, ensuring that
// they're correctly added to the OOP wrapper as well.
_.mixin = function(obj) {
@@ -617,54 +661,45 @@
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_.templateSettings = {
- start : '<%',
- end : '%>',
- interpolate : /<%=(.+?)%>/g
+ evaluate : /<%([\s\S]+?)%>/g,
+ interpolate : /<%=([\s\S]+?)%>/g
};
- // JavaScript templating a-la ERB, pilfered from John Resig's
- // "Secrets of the JavaScript Ninja", page 83.
- // Single-quote fix from Rick Strahl's version.
- // With alterations for arbitrary delimiters, and to preserve whitespace.
+ // JavaScript micro-templating, similar to John Resig's implementation.
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
+ // and correctly escapes quotes within interpolated code.
_.template = function(str, data) {
var c = _.templateSettings;
- var endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g");
- var fn = new Function('obj',
- 'var p=[],print=function(){p.push.apply(p,arguments);};' +
- 'with(obj||{}){p.push(\'' +
- str.replace(/\r/g, '\\r')
+ var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
+ 'with(obj||{}){__p.push(\'' +
+ str.replace(/\\/g, '\\\\')
+ .replace(/'/g, "\\'")
+ .replace(c.interpolate, function(match, code) {
+ return "'," + code.replace(/\\'/g, "'") + ",'";
+ })
+ .replace(c.evaluate || null, function(match, code) {
+ return "');" + code.replace(/\\'/g, "'")
+ .replace(/[\r\n\t]/g, ' ') + "__p.push('";
+ })
+ .replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
.replace(/\t/g, '\\t')
- .replace(endMatch,"✄")
- .split("'").join("\\'")
- .split("✄").join("'")
- .replace(c.interpolate, "',$1,'")
- .split(c.start).join("');")
- .split(c.end).join("p.push('")
- + "');}return p.join('');");
- return data ? fn(data) : fn;
- };
-
- // ------------------------------- Aliases ----------------------------------
-
- _.each = _.forEach;
- _.foldl = _.inject = _.reduce;
- _.foldr = _.reduceRight;
- _.select = _.filter;
- _.all = _.every;
- _.any = _.some;
- _.contains = _.include;
- _.head = _.first;
- _.tail = _.rest;
- _.methods = _.functions;
-
- // ------------------------ Setup the OOP Wrapper: --------------------------
+ + "');}return __p.join('');";
+ var func = new Function('obj', tmpl);
+ return data ? func(data) : func;
+ };
+
+ // The OOP Wrapper
+ // ---------------
// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions. Wrapped objects may be chained.
var wrapper = function(obj) { this._wrapped = obj; };
+ // Expose `wrapper.prototype` as `_.prototype`
+ _.prototype = wrapper.prototype;
+
// Helper function to continue chaining intermediate results.
var result = function(obj, chain) {
return chain ? _(obj).chain() : obj;
@@ -673,7 +708,7 @@
// A method to easily add functions to the OOP wrapper.
var addToWrapper = function(name, func) {
wrapper.prototype[name] = function() {
- var args = _.toArray(arguments);
+ var args = slice.call(arguments);
unshift.call(args, this._wrapped);
return result(func.apply(_, args), this._chain);
};
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/backbone.git
More information about the Pkg-javascript-commits
mailing list