underscore-source 1.2.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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);
|