underscore-source 1.2.0 → 1.2.1
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.
- data/lib/underscore-source/version.rb +1 -1
- data/vendor/assets/javascripts/underscore.js +107 -80
- metadata +1 -1
@@ -1,4 +1,4 @@
|
|
1
|
-
// Underscore.js 1.2.
|
1
|
+
// Underscore.js 1.2.1
|
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,
|
@@ -48,19 +48,26 @@
|
|
48
48
|
// Create a safe reference to the Underscore object for use below.
|
49
49
|
var _ = function(obj) { return new wrapper(obj); };
|
50
50
|
|
51
|
-
// Export the Underscore object for **CommonJS**, with
|
52
|
-
// for the old `require()` API. If we're not in
|
53
|
-
// global object.
|
54
|
-
if (typeof
|
55
|
-
module.exports
|
56
|
-
|
51
|
+
// Export the Underscore object for **Node.js** and **"CommonJS"**, with
|
52
|
+
// backwards-compatibility for the old `require()` API. If we're not in
|
53
|
+
// CommonJS, add `_` to the global object.
|
54
|
+
if (typeof exports !== 'undefined') {
|
55
|
+
if (typeof module !== 'undefined' && module.exports) {
|
56
|
+
exports = module.exports = _;
|
57
|
+
}
|
58
|
+
exports._ = _;
|
59
|
+
} else if (typeof define === 'function' && define.amd) {
|
60
|
+
// Register as a named module with AMD.
|
61
|
+
define('underscore', function() {
|
62
|
+
return _;
|
63
|
+
});
|
57
64
|
} else {
|
58
65
|
// Exported as a string, for Closure Compiler "advanced" mode.
|
59
66
|
root['_'] = _;
|
60
67
|
}
|
61
68
|
|
62
69
|
// Current version.
|
63
|
-
_.VERSION = '1.2.
|
70
|
+
_.VERSION = '1.2.1';
|
64
71
|
|
65
72
|
// Collection Functions
|
66
73
|
// --------------------
|
@@ -198,8 +205,8 @@
|
|
198
205
|
var found = false;
|
199
206
|
if (obj == null) return found;
|
200
207
|
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
|
201
|
-
any(obj, function(value) {
|
202
|
-
if (
|
208
|
+
found = any(obj, function(value) {
|
209
|
+
if (value === target) return true;
|
203
210
|
});
|
204
211
|
return found;
|
205
212
|
};
|
@@ -269,9 +276,11 @@
|
|
269
276
|
}), 'value');
|
270
277
|
};
|
271
278
|
|
272
|
-
// Groups the object's values by a criterion
|
273
|
-
|
279
|
+
// Groups the object's values by a criterion. Pass either a string attribute
|
280
|
+
// to group by, or a function that returns the criterion.
|
281
|
+
_.groupBy = function(obj, val) {
|
274
282
|
var result = {};
|
283
|
+
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
|
275
284
|
each(obj, function(value, index) {
|
276
285
|
var key = iterator(value, index);
|
277
286
|
(result[key] || (result[key] = [])).push(value);
|
@@ -343,9 +352,9 @@
|
|
343
352
|
};
|
344
353
|
|
345
354
|
// Return a completely flattened version of an array.
|
346
|
-
_.flatten = function(array) {
|
355
|
+
_.flatten = function(array, shallow) {
|
347
356
|
return _.reduce(array, function(memo, value) {
|
348
|
-
if (_.isArray(value)) return memo.concat(_.flatten(value));
|
357
|
+
if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
|
349
358
|
memo[memo.length] = value;
|
350
359
|
return memo;
|
351
360
|
}, []);
|
@@ -375,7 +384,7 @@
|
|
375
384
|
// Produce an array that contains the union: each distinct element from all of
|
376
385
|
// the passed-in arrays.
|
377
386
|
_.union = function() {
|
378
|
-
return _.uniq(_.flatten(arguments));
|
387
|
+
return _.uniq(_.flatten(arguments, true));
|
379
388
|
};
|
380
389
|
|
381
390
|
// Produce an array that contains every item shared between all the
|
@@ -457,15 +466,25 @@
|
|
457
466
|
// Function (ahem) Functions
|
458
467
|
// ------------------
|
459
468
|
|
469
|
+
// Reusable constructor function for prototype setting.
|
470
|
+
var ctor = function(){};
|
471
|
+
|
460
472
|
// Create a function bound to a given object (assigning `this`, and arguments,
|
461
473
|
// optionally). Binding with arguments is also known as `curry`.
|
462
474
|
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
|
463
475
|
// We check for `func.bind` first, to fail fast when `func` is undefined.
|
464
|
-
_.bind = function(func,
|
476
|
+
_.bind = function bind(func, context) {
|
477
|
+
var bound, args;
|
465
478
|
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
466
|
-
|
467
|
-
|
468
|
-
|
479
|
+
if (!_.isFunction(func)) throw new TypeError;
|
480
|
+
args = slice.call(arguments, 2);
|
481
|
+
return bound = function() {
|
482
|
+
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
|
483
|
+
ctor.prototype = func.prototype;
|
484
|
+
var self = new ctor;
|
485
|
+
var result = func.apply(self, args.concat(slice.call(arguments)));
|
486
|
+
if (Object(result) === result) return result;
|
487
|
+
return self;
|
469
488
|
};
|
470
489
|
};
|
471
490
|
|
@@ -501,31 +520,39 @@
|
|
501
520
|
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
|
502
521
|
};
|
503
522
|
|
504
|
-
//
|
505
|
-
|
506
|
-
|
523
|
+
// Returns a function, that, when invoked, will only be triggered at most once
|
524
|
+
// during a given window of time.
|
525
|
+
_.throttle = function(func, wait) {
|
526
|
+
var timeout, context, args, throttling, finishThrottle;
|
527
|
+
finishThrottle = _.debounce(function(){ throttling = false; }, wait);
|
507
528
|
return function() {
|
508
|
-
|
529
|
+
context = this; args = arguments;
|
509
530
|
var throttler = function() {
|
510
531
|
timeout = null;
|
511
532
|
func.apply(context, args);
|
533
|
+
finishThrottle();
|
512
534
|
};
|
513
|
-
if (
|
514
|
-
if (
|
535
|
+
if (!timeout) timeout = setTimeout(throttler, wait);
|
536
|
+
if (!throttling) func.apply(context, args);
|
537
|
+
if (finishThrottle) finishThrottle();
|
538
|
+
throttling = true;
|
515
539
|
};
|
516
540
|
};
|
517
541
|
|
518
|
-
// Returns a function, that, when invoked, will only be triggered at most once
|
519
|
-
// during a given window of time.
|
520
|
-
_.throttle = function(func, wait) {
|
521
|
-
return limit(func, wait, false);
|
522
|
-
};
|
523
|
-
|
524
542
|
// Returns a function, that, as long as it continues to be invoked, will not
|
525
543
|
// be triggered. The function will be called after it stops being called for
|
526
544
|
// N milliseconds.
|
527
545
|
_.debounce = function(func, wait) {
|
528
|
-
|
546
|
+
var timeout;
|
547
|
+
return function() {
|
548
|
+
var context = this, args = arguments;
|
549
|
+
var throttler = function() {
|
550
|
+
timeout = null;
|
551
|
+
func.apply(context, args);
|
552
|
+
};
|
553
|
+
clearTimeout(timeout);
|
554
|
+
timeout = setTimeout(throttler, wait);
|
555
|
+
};
|
529
556
|
};
|
530
557
|
|
531
558
|
// Returns a function that will be executed at most one time, no matter how
|
@@ -618,6 +645,7 @@
|
|
618
645
|
|
619
646
|
// Create a (shallow-cloned) duplicate of an object.
|
620
647
|
_.clone = function(obj) {
|
648
|
+
if (!_.isObject(obj)) return obj;
|
621
649
|
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
|
622
650
|
};
|
623
651
|
|
@@ -635,7 +663,13 @@
|
|
635
663
|
// See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
|
636
664
|
if (a === b) return a !== 0 || 1 / a == 1 / b;
|
637
665
|
// A strict comparison is necessary because `null == undefined`.
|
638
|
-
if (a == null) return a === b;
|
666
|
+
if ((a == null) || (b == null)) return a === b;
|
667
|
+
// Unwrap any wrapped objects.
|
668
|
+
if (a._chain) a = a._wrapped;
|
669
|
+
if (b._chain) b = b._wrapped;
|
670
|
+
// Invoke a custom `isEqual` method if one is provided.
|
671
|
+
if (_.isFunction(a.isEqual)) return a.isEqual(b);
|
672
|
+
if (_.isFunction(b.isEqual)) return b.isEqual(a);
|
639
673
|
// Compare object types.
|
640
674
|
var typeA = typeof a;
|
641
675
|
if (typeA != typeof b) return false;
|
@@ -667,50 +701,36 @@
|
|
667
701
|
}
|
668
702
|
// Ensure that both values are objects.
|
669
703
|
if (typeA != 'object') return false;
|
670
|
-
//
|
671
|
-
if (a.
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
//
|
676
|
-
// adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
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;
|
708
|
+
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
709
|
+
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
677
710
|
var length = stack.length;
|
678
711
|
while (length--) {
|
679
|
-
// Linear search. Performance is inversely proportional to the number of
|
680
|
-
// structures.
|
712
|
+
// Linear search. Performance is inversely proportional to the number of
|
713
|
+
// unique nested structures.
|
681
714
|
if (stack[length] == a) return true;
|
682
715
|
}
|
683
716
|
// Add the first object to the stack of traversed objects.
|
684
717
|
stack.push(a);
|
685
718
|
var size = 0, result = true;
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
// Deep compare
|
692
|
-
|
693
|
-
// Ensure commutative equality for sparse arrays.
|
694
|
-
if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
|
695
|
-
}
|
696
|
-
}
|
697
|
-
} else {
|
698
|
-
// Deep compare objects.
|
699
|
-
for (var key in a) {
|
700
|
-
if (hasOwnProperty.call(a, key)) {
|
701
|
-
// Count the expected number of properties.
|
702
|
-
size++;
|
703
|
-
// Deep compare each member.
|
704
|
-
if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
|
705
|
-
}
|
719
|
+
// Deep compare objects.
|
720
|
+
for (var key in a) {
|
721
|
+
if (hasOwnProperty.call(a, key)) {
|
722
|
+
// Count the expected number of properties.
|
723
|
+
size++;
|
724
|
+
// Deep compare each member.
|
725
|
+
if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
|
706
726
|
}
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
result = !size;
|
727
|
+
}
|
728
|
+
// Ensure that both objects contain the same number of properties.
|
729
|
+
if (result) {
|
730
|
+
for (key in b) {
|
731
|
+
if (hasOwnProperty.call(b, key) && !size--) break;
|
713
732
|
}
|
733
|
+
result = !size;
|
714
734
|
}
|
715
735
|
// Remove the first object from the stack of traversed objects.
|
716
736
|
stack.pop();
|
@@ -722,7 +742,8 @@
|
|
722
742
|
return eq(a, b, []);
|
723
743
|
};
|
724
744
|
|
725
|
-
// Is a given array or object empty?
|
745
|
+
// Is a given array, string, or object empty?
|
746
|
+
// An "empty" object has no enumerable own-properties.
|
726
747
|
_.isEmpty = function(obj) {
|
727
748
|
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
|
728
749
|
for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
|
@@ -737,7 +758,7 @@
|
|
737
758
|
// Is a given value an array?
|
738
759
|
// Delegates to ECMA5's native Array.isArray
|
739
760
|
_.isArray = nativeIsArray || function(obj) {
|
740
|
-
return toString.call(obj)
|
761
|
+
return toString.call(obj) == '[object Array]';
|
741
762
|
};
|
742
763
|
|
743
764
|
// Is a given variable an object?
|
@@ -746,28 +767,34 @@
|
|
746
767
|
};
|
747
768
|
|
748
769
|
// Is a given variable an arguments object?
|
749
|
-
|
750
|
-
|
751
|
-
|
770
|
+
if (toString.call(arguments) == '[object Arguments]') {
|
771
|
+
_.isArguments = function(obj) {
|
772
|
+
return toString.call(obj) == '[object Arguments]';
|
773
|
+
};
|
774
|
+
} else {
|
775
|
+
_.isArguments = function(obj) {
|
776
|
+
return !!(obj && hasOwnProperty.call(obj, 'callee'));
|
777
|
+
};
|
778
|
+
}
|
752
779
|
|
753
780
|
// Is a given value a function?
|
754
781
|
_.isFunction = function(obj) {
|
755
|
-
return
|
782
|
+
return toString.call(obj) == '[object Function]';
|
756
783
|
};
|
757
784
|
|
758
785
|
// Is a given value a string?
|
759
786
|
_.isString = function(obj) {
|
760
|
-
return
|
787
|
+
return toString.call(obj) == '[object String]';
|
761
788
|
};
|
762
789
|
|
763
790
|
// Is a given value a number?
|
764
791
|
_.isNumber = function(obj) {
|
765
|
-
return
|
792
|
+
return toString.call(obj) == '[object Number]';
|
766
793
|
};
|
767
794
|
|
768
|
-
// Is the given value `NaN`?
|
769
|
-
// that does not equal itself.
|
795
|
+
// Is the given value `NaN`?
|
770
796
|
_.isNaN = function(obj) {
|
797
|
+
// `NaN` is the only value for which `===` is not reflexive.
|
771
798
|
return obj !== obj;
|
772
799
|
};
|
773
800
|
|
@@ -778,12 +805,12 @@
|
|
778
805
|
|
779
806
|
// Is a given value a date?
|
780
807
|
_.isDate = function(obj) {
|
781
|
-
return
|
808
|
+
return toString.call(obj) == '[object Date]';
|
782
809
|
};
|
783
810
|
|
784
811
|
// Is the given value a regular expression?
|
785
812
|
_.isRegExp = function(obj) {
|
786
|
-
return
|
813
|
+
return toString.call(obj) == '[object RegExp]';
|
787
814
|
};
|
788
815
|
|
789
816
|
// Is a given value equal to null?
|