underscore-source 1.2.1 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
|
|
1
|
-
// Underscore.js 1.2.
|
1
|
+
// Underscore.js 1.2.2
|
2
2
|
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
|
3
3
|
// Underscore is freely distributable under the MIT license.
|
4
4
|
// Portions of Underscore are inspired or borrowed from Prototype,
|
@@ -67,7 +67,7 @@
|
|
67
67
|
}
|
68
68
|
|
69
69
|
// Current version.
|
70
|
-
_.VERSION = '1.2.
|
70
|
+
_.VERSION = '1.2.2';
|
71
71
|
|
72
72
|
// Collection Functions
|
73
73
|
// --------------------
|
@@ -194,7 +194,7 @@
|
|
194
194
|
if (obj == null) return result;
|
195
195
|
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
|
196
196
|
each(obj, function(value, index, list) {
|
197
|
-
if (result
|
197
|
+
if (result || (result = iterator.call(context, value, index, list))) return breaker;
|
198
198
|
});
|
199
199
|
return !!result;
|
200
200
|
};
|
@@ -206,7 +206,7 @@
|
|
206
206
|
if (obj == null) return found;
|
207
207
|
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
|
208
208
|
found = any(obj, function(value) {
|
209
|
-
|
209
|
+
return value === target;
|
210
210
|
});
|
211
211
|
return found;
|
212
212
|
};
|
@@ -335,7 +335,11 @@
|
|
335
335
|
// Get the last element of an array. Passing **n** will return the last N
|
336
336
|
// values in the array. The **guard** check allows it to work with `_.map`.
|
337
337
|
_.last = function(array, n, guard) {
|
338
|
-
|
338
|
+
if ((n != null) && !guard) {
|
339
|
+
return slice.call(array, Math.max(array.length - n, 0));
|
340
|
+
} else {
|
341
|
+
return array[array.length - 1];
|
342
|
+
}
|
339
343
|
};
|
340
344
|
|
341
345
|
// Returns everything but the first entry of the array. Aliased as `tail`.
|
@@ -523,18 +527,22 @@
|
|
523
527
|
// Returns a function, that, when invoked, will only be triggered at most once
|
524
528
|
// during a given window of time.
|
525
529
|
_.throttle = function(func, wait) {
|
526
|
-
var
|
527
|
-
|
530
|
+
var context, args, timeout, throttling, more;
|
531
|
+
var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
|
528
532
|
return function() {
|
529
533
|
context = this; args = arguments;
|
530
|
-
var
|
534
|
+
var later = function() {
|
531
535
|
timeout = null;
|
532
|
-
func.apply(context, args);
|
533
|
-
|
536
|
+
if (more) func.apply(context, args);
|
537
|
+
whenDone();
|
534
538
|
};
|
535
|
-
if (!timeout) timeout = setTimeout(
|
536
|
-
if (
|
537
|
-
|
539
|
+
if (!timeout) timeout = setTimeout(later, wait);
|
540
|
+
if (throttling) {
|
541
|
+
more = true;
|
542
|
+
} else {
|
543
|
+
func.apply(context, args);
|
544
|
+
}
|
545
|
+
whenDone();
|
538
546
|
throttling = true;
|
539
547
|
};
|
540
548
|
};
|
@@ -546,12 +554,12 @@
|
|
546
554
|
var timeout;
|
547
555
|
return function() {
|
548
556
|
var context = this, args = arguments;
|
549
|
-
var
|
557
|
+
var later = function() {
|
550
558
|
timeout = null;
|
551
559
|
func.apply(context, args);
|
552
560
|
};
|
553
561
|
clearTimeout(timeout);
|
554
|
-
timeout = setTimeout(
|
562
|
+
timeout = setTimeout(later, wait);
|
555
563
|
};
|
556
564
|
};
|
557
565
|
|
@@ -591,6 +599,7 @@
|
|
591
599
|
|
592
600
|
// Returns a function that will only be executed after being called N times.
|
593
601
|
_.after = function(times, func) {
|
602
|
+
if (times <= 0) return func();
|
594
603
|
return function() {
|
595
604
|
if (--times < 1) { return func.apply(this, arguments); }
|
596
605
|
};
|
@@ -663,48 +672,42 @@
|
|
663
672
|
// See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
|
664
673
|
if (a === b) return a !== 0 || 1 / a == 1 / b;
|
665
674
|
// A strict comparison is necessary because `null == undefined`.
|
666
|
-
if (
|
675
|
+
if (a == null || b == null) return a === b;
|
667
676
|
// Unwrap any wrapped objects.
|
668
677
|
if (a._chain) a = a._wrapped;
|
669
678
|
if (b._chain) b = b._wrapped;
|
670
679
|
// Invoke a custom `isEqual` method if one is provided.
|
671
680
|
if (_.isFunction(a.isEqual)) return a.isEqual(b);
|
672
681
|
if (_.isFunction(b.isEqual)) return b.isEqual(a);
|
673
|
-
// Compare
|
674
|
-
var
|
675
|
-
if (
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
a.ignoreCase == b.ignoreCase;
|
682
|
+
// Compare `[[Class]]` names.
|
683
|
+
var className = toString.call(a);
|
684
|
+
if (className != toString.call(b)) return false;
|
685
|
+
switch (className) {
|
686
|
+
// Strings, numbers, dates, and booleans are compared by value.
|
687
|
+
case '[object String]':
|
688
|
+
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
|
689
|
+
// equivalent to `new String("5")`.
|
690
|
+
return String(a) == String(b);
|
691
|
+
case '[object Number]':
|
692
|
+
a = +a;
|
693
|
+
b = +b;
|
694
|
+
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
|
695
|
+
// other numeric values.
|
696
|
+
return a != a ? b != b : (a == 0 ? 1 / a == 1 / b : a == b);
|
697
|
+
case '[object Date]':
|
698
|
+
case '[object Boolean]':
|
699
|
+
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
|
700
|
+
// millisecond representations. Note that invalid dates with millisecond representations
|
701
|
+
// of `NaN` are not equivalent.
|
702
|
+
return +a == +b;
|
703
|
+
// RegExps are compared by their source patterns and flags.
|
704
|
+
case '[object RegExp]':
|
705
|
+
return a.source == b.source &&
|
706
|
+
a.global == b.global &&
|
707
|
+
a.multiline == b.multiline &&
|
708
|
+
a.ignoreCase == b.ignoreCase;
|
701
709
|
}
|
702
|
-
|
703
|
-
if (typeA != 'object') return false;
|
704
|
-
// Arrays or Arraylikes with different lengths are not equal.
|
705
|
-
if (a.length !== b.length) return false;
|
706
|
-
// Objects with different constructors are not equal.
|
707
|
-
if (a.constructor !== b.constructor) return false;
|
710
|
+
if (typeof a != 'object' || typeof b != 'object') return false;
|
708
711
|
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
709
712
|
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
710
713
|
var length = stack.length;
|
@@ -716,21 +719,37 @@
|
|
716
719
|
// Add the first object to the stack of traversed objects.
|
717
720
|
stack.push(a);
|
718
721
|
var size = 0, result = true;
|
719
|
-
//
|
720
|
-
|
721
|
-
if
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
722
|
+
// Recursively compare objects and arrays.
|
723
|
+
if (className == '[object Array]') {
|
724
|
+
// Compare array lengths to determine if a deep comparison is necessary.
|
725
|
+
size = a.length;
|
726
|
+
result = size == b.length;
|
727
|
+
if (result) {
|
728
|
+
// Deep compare the contents, ignoring non-numeric properties.
|
729
|
+
while (size--) {
|
730
|
+
// Ensure commutative equality for sparse arrays.
|
731
|
+
if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
|
732
|
+
}
|
726
733
|
}
|
727
|
-
}
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
734
|
+
} else {
|
735
|
+
// Objects with different constructors are not equivalent.
|
736
|
+
if ("constructor" in a != "constructor" in b || a.constructor != b.constructor) return false;
|
737
|
+
// Deep compare objects.
|
738
|
+
for (var key in a) {
|
739
|
+
if (hasOwnProperty.call(a, key)) {
|
740
|
+
// Count the expected number of properties.
|
741
|
+
size++;
|
742
|
+
// Deep compare each member.
|
743
|
+
if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
|
744
|
+
}
|
745
|
+
}
|
746
|
+
// Ensure that both objects contain the same number of properties.
|
747
|
+
if (result) {
|
748
|
+
for (key in b) {
|
749
|
+
if (hasOwnProperty.call(b, key) && !(size--)) break;
|
750
|
+
}
|
751
|
+
result = !size;
|
732
752
|
}
|
733
|
-
result = !size;
|
734
753
|
}
|
735
754
|
// Remove the first object from the stack of traversed objects.
|
736
755
|
stack.pop();
|
@@ -845,7 +864,7 @@
|
|
845
864
|
|
846
865
|
// Escape a string for HTML interpolation.
|
847
866
|
_.escape = function(string) {
|
848
|
-
return (''+string).replace(
|
867
|
+
return (''+string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/');
|
849
868
|
};
|
850
869
|
|
851
870
|
// Add your own custom functions to the Underscore object, ensuring that
|
@@ -889,14 +908,14 @@
|
|
889
908
|
})
|
890
909
|
.replace(c.evaluate || null, function(match, code) {
|
891
910
|
return "');" + code.replace(/\\'/g, "'")
|
892
|
-
.replace(/[\r\n\t]/g, ' ') + "__p.push('";
|
911
|
+
.replace(/[\r\n\t]/g, ' ') + ";__p.push('";
|
893
912
|
})
|
894
913
|
.replace(/\r/g, '\\r')
|
895
914
|
.replace(/\n/g, '\\n')
|
896
915
|
.replace(/\t/g, '\\t')
|
897
916
|
+ "');}return __p.join('');";
|
898
|
-
var func = new Function('obj', tmpl);
|
899
|
-
return data ? func(data) : func;
|
917
|
+
var func = new Function('obj', '_', tmpl);
|
918
|
+
return data ? func(data, _) : function(data) { return func(data, _) };
|
900
919
|
};
|
901
920
|
|
902
921
|
// The OOP Wrapper
|
@@ -955,4 +974,4 @@
|
|
955
974
|
return this._wrapped;
|
956
975
|
};
|
957
976
|
|
958
|
-
})();
|
977
|
+
}).call(this);
|