A whole slew of IE fixes and safety guards.

This commit is contained in:
Jeremy Ashkenas
2010-02-24 15:01:51 -05:00
parent 8d632ada0b
commit 71b6e4f555

View File

@@ -65,7 +65,7 @@
var each = _.forEach = function(obj, iterator, context) {
var index = 0;
try {
if (obj.forEach === nativeForEach) {
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);
@@ -83,7 +83,7 @@
// Return the results of applying the iterator to each element.
// Delegates to JavaScript 1.6's native map if available.
_.map = function(obj, iterator, context) {
if (obj.map === nativeMap) return obj.map(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));
@@ -94,7 +94,7 @@
// 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, memo, iterator, context) {
if (obj.reduce === nativeReduce) return obj.reduce(_.bind(iterator, context), memo);
if (nativeReduce && obj.reduce === nativeReduce) return obj.reduce(_.bind(iterator, context), memo);
each(obj, function(value, index, list) {
memo = iterator.call(context, memo, value, index, list);
});
@@ -104,9 +104,9 @@
// The right-associative version of reduce, also known as foldr. Uses
// Delegates to JavaScript 1.8's native reduceRight if available.
_.reduceRight = function(obj, memo, iterator, context) {
if (obj.reduceRight === nativeReduceRight) return obj.reduceRight(_.bind(iterator, context), memo);
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) return obj.reduceRight(_.bind(iterator, context), memo);
var reversed = _.clone(_.toArray(obj)).reverse();
return reduce(reversed, memo, iterator, context);
return _.reduce(reversed, memo, iterator, context);
};
// Return the first value which passes a truth test.
@@ -124,7 +124,7 @@
// Return all the elements that pass a truth test.
// Delegates to JavaScript 1.6's native filter if available.
_.filter = function(obj, iterator, context) {
if (obj.filter === nativeFilter) return obj.filter(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);
@@ -145,7 +145,7 @@
// Delegates to JavaScript 1.6's native every if available.
_.every = function(obj, iterator, context) {
iterator = iterator || _.identity;
if (obj.every === nativeEvery) return obj.every(iterator, context);
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();
@@ -157,7 +157,7 @@
// Delegates to JavaScript 1.6's native some if available.
_.some = function(obj, iterator, context) {
iterator = iterator || _.identity;
if (obj.some === nativeSome) return obj.some(iterator, context);
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();
@@ -167,10 +167,12 @@
// Determine if a given value is included in the array or object using '==='.
_.include = function(obj, target) {
if (obj && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
return !! _.detect(obj, function(value) {
return value === target;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
var found = false;
each(obj, function(value) {
if (found = value === target) _.breakLoop();
});
return found;
};
// Invoke a method with arguments on every item in a collection.
@@ -271,7 +273,7 @@
// Trim out all falsy values from an array.
_.compact = function(array) {
return _.select(array, function(value){ return !!value; });
return _.filter(array, function(value){ return !!value; });
};
// Return a completely flattened version of an array.
@@ -286,7 +288,7 @@
// Return a version of the array that does not contain the specified value(s).
_.without = function(array) {
var values = _.rest(arguments);
return _.select(array, function(value){ return !_.include(values, value); });
return _.filter(array, function(value){ return !_.include(values, value); });
};
// Produce a duplicate-free version of the array. If the array has already
@@ -302,8 +304,8 @@
// passed-in arrays.
_.intersect = function(array) {
var rest = _.rest(arguments);
return _.select(_.uniq(array), function(item) {
return _.all(rest, function(other) {
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
return _.indexOf(other, item) >= 0;
});
});
@@ -324,7 +326,7 @@
// 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.
_.indexOf = function(array, item) {
if (array.indexOf === nativeIndexOf) return array.indexOf(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;
return -1;
};
@@ -332,7 +334,7 @@
// Delegates to JavaScript 1.6's native lastIndexOf if available.
_.lastIndexOf = function(array, item) {
if (array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
var i = array.length;
while (i--) if (array[i] === item) return i;
return -1;
@@ -428,7 +430,7 @@
// Return a sorted list of the function names available on the object.
_.functions = function(obj) {
return _.select(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort();
return _.filter(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort();
};
// Extend a given object with all of the properties in a source object.
@@ -577,7 +579,7 @@
// Add your own custom functions to the Underscore object, ensuring that
// they're correctly added to the OOP wrapper as well.
_.mixin = function(obj) {
_.each(_.functions(obj), function(name){
each(_.functions(obj), function(name){
addToWrapper(name, _[name] = obj[name]);
});
};
@@ -601,13 +603,15 @@
// 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.
_.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\t\n]/g, " ")
.replace(new RegExp("'(?=[^"+c.end[0]+"]*"+escapeRegExp(c.end)+")","g"),"\t")
.replace(endMatch,"\t")
.split("'").join("\\'")
.split("\t").join("'")
.replace(c.interpolate, "',$1,'")