underscore-rails 1.2.0 → 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.
- data/lib/underscore-rails/version.rb +1 -1
- data/vendor/assets/javascripts/underscore.js +139 -93
- metadata +3 -2
@@ -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,
|
@@ -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.2';
|
64
71
|
|
65
72
|
// Collection Functions
|
66
73
|
// --------------------
|
@@ -187,7 +194,7 @@
|
|
187
194
|
if (obj == null) return result;
|
188
195
|
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
|
189
196
|
each(obj, function(value, index, list) {
|
190
|
-
if (result
|
197
|
+
if (result || (result = iterator.call(context, value, index, list))) return breaker;
|
191
198
|
});
|
192
199
|
return !!result;
|
193
200
|
};
|
@@ -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
|
-
|
208
|
+
found = any(obj, function(value) {
|
209
|
+
return value === target;
|
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);
|
@@ -326,7 +335,11 @@
|
|
326
335
|
// Get the last element of an array. Passing **n** will return the last N
|
327
336
|
// values in the array. The **guard** check allows it to work with `_.map`.
|
328
337
|
_.last = function(array, n, guard) {
|
329
|
-
|
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
|
+
}
|
330
343
|
};
|
331
344
|
|
332
345
|
// Returns everything but the first entry of the array. Aliased as `tail`.
|
@@ -343,9 +356,9 @@
|
|
343
356
|
};
|
344
357
|
|
345
358
|
// Return a completely flattened version of an array.
|
346
|
-
_.flatten = function(array) {
|
359
|
+
_.flatten = function(array, shallow) {
|
347
360
|
return _.reduce(array, function(memo, value) {
|
348
|
-
if (_.isArray(value)) return memo.concat(_.flatten(value));
|
361
|
+
if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
|
349
362
|
memo[memo.length] = value;
|
350
363
|
return memo;
|
351
364
|
}, []);
|
@@ -375,7 +388,7 @@
|
|
375
388
|
// Produce an array that contains the union: each distinct element from all of
|
376
389
|
// the passed-in arrays.
|
377
390
|
_.union = function() {
|
378
|
-
return _.uniq(_.flatten(arguments));
|
391
|
+
return _.uniq(_.flatten(arguments, true));
|
379
392
|
};
|
380
393
|
|
381
394
|
// Produce an array that contains every item shared between all the
|
@@ -457,15 +470,25 @@
|
|
457
470
|
// Function (ahem) Functions
|
458
471
|
// ------------------
|
459
472
|
|
473
|
+
// Reusable constructor function for prototype setting.
|
474
|
+
var ctor = function(){};
|
475
|
+
|
460
476
|
// Create a function bound to a given object (assigning `this`, and arguments,
|
461
477
|
// optionally). Binding with arguments is also known as `curry`.
|
462
478
|
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
|
463
479
|
// We check for `func.bind` first, to fail fast when `func` is undefined.
|
464
|
-
_.bind = function(func,
|
480
|
+
_.bind = function bind(func, context) {
|
481
|
+
var bound, args;
|
465
482
|
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
466
|
-
|
467
|
-
|
468
|
-
|
483
|
+
if (!_.isFunction(func)) throw new TypeError;
|
484
|
+
args = slice.call(arguments, 2);
|
485
|
+
return bound = function() {
|
486
|
+
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
|
487
|
+
ctor.prototype = func.prototype;
|
488
|
+
var self = new ctor;
|
489
|
+
var result = func.apply(self, args.concat(slice.call(arguments)));
|
490
|
+
if (Object(result) === result) return result;
|
491
|
+
return self;
|
469
492
|
};
|
470
493
|
};
|
471
494
|
|
@@ -501,31 +524,43 @@
|
|
501
524
|
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
|
502
525
|
};
|
503
526
|
|
504
|
-
//
|
505
|
-
|
506
|
-
|
527
|
+
// Returns a function, that, when invoked, will only be triggered at most once
|
528
|
+
// during a given window of time.
|
529
|
+
_.throttle = function(func, wait) {
|
530
|
+
var context, args, timeout, throttling, more;
|
531
|
+
var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
|
507
532
|
return function() {
|
508
|
-
|
509
|
-
var
|
533
|
+
context = this; args = arguments;
|
534
|
+
var later = function() {
|
510
535
|
timeout = null;
|
511
|
-
func.apply(context, args);
|
536
|
+
if (more) func.apply(context, args);
|
537
|
+
whenDone();
|
512
538
|
};
|
513
|
-
if (
|
514
|
-
if (
|
539
|
+
if (!timeout) timeout = setTimeout(later, wait);
|
540
|
+
if (throttling) {
|
541
|
+
more = true;
|
542
|
+
} else {
|
543
|
+
func.apply(context, args);
|
544
|
+
}
|
545
|
+
whenDone();
|
546
|
+
throttling = true;
|
515
547
|
};
|
516
548
|
};
|
517
549
|
|
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
550
|
// Returns a function, that, as long as it continues to be invoked, will not
|
525
551
|
// be triggered. The function will be called after it stops being called for
|
526
552
|
// N milliseconds.
|
527
553
|
_.debounce = function(func, wait) {
|
528
|
-
|
554
|
+
var timeout;
|
555
|
+
return function() {
|
556
|
+
var context = this, args = arguments;
|
557
|
+
var later = function() {
|
558
|
+
timeout = null;
|
559
|
+
func.apply(context, args);
|
560
|
+
};
|
561
|
+
clearTimeout(timeout);
|
562
|
+
timeout = setTimeout(later, wait);
|
563
|
+
};
|
529
564
|
};
|
530
565
|
|
531
566
|
// Returns a function that will be executed at most one time, no matter how
|
@@ -564,6 +599,7 @@
|
|
564
599
|
|
565
600
|
// Returns a function that will only be executed after being called N times.
|
566
601
|
_.after = function(times, func) {
|
602
|
+
if (times <= 0) return func();
|
567
603
|
return function() {
|
568
604
|
if (--times < 1) { return func.apply(this, arguments); }
|
569
605
|
};
|
@@ -618,6 +654,7 @@
|
|
618
654
|
|
619
655
|
// Create a (shallow-cloned) duplicate of an object.
|
620
656
|
_.clone = function(obj) {
|
657
|
+
if (!_.isObject(obj)) return obj;
|
621
658
|
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
|
622
659
|
};
|
623
660
|
|
@@ -635,66 +672,68 @@
|
|
635
672
|
// See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
|
636
673
|
if (a === b) return a !== 0 || 1 / a == 1 / b;
|
637
674
|
// A strict comparison is necessary because `null == undefined`.
|
638
|
-
if (a == null) return a === b;
|
639
|
-
// Compare object types.
|
640
|
-
var typeA = typeof a;
|
641
|
-
if (typeA != typeof b) return false;
|
642
|
-
// Optimization; ensure that both values are truthy or falsy.
|
643
|
-
if (!a != !b) return false;
|
644
|
-
// `NaN` values are equal.
|
645
|
-
if (_.isNaN(a)) return _.isNaN(b);
|
646
|
-
// Compare string objects by value.
|
647
|
-
var isStringA = _.isString(a), isStringB = _.isString(b);
|
648
|
-
if (isStringA || isStringB) return isStringA && isStringB && String(a) == String(b);
|
649
|
-
// Compare number objects by value.
|
650
|
-
var isNumberA = _.isNumber(a), isNumberB = _.isNumber(b);
|
651
|
-
if (isNumberA || isNumberB) return isNumberA && isNumberB && +a == +b;
|
652
|
-
// Compare boolean objects by value. The value of `true` is 1; the value of `false` is 0.
|
653
|
-
var isBooleanA = _.isBoolean(a), isBooleanB = _.isBoolean(b);
|
654
|
-
if (isBooleanA || isBooleanB) return isBooleanA && isBooleanB && +a == +b;
|
655
|
-
// Compare dates by their millisecond values.
|
656
|
-
var isDateA = _.isDate(a), isDateB = _.isDate(b);
|
657
|
-
if (isDateA || isDateB) return isDateA && isDateB && a.getTime() == b.getTime();
|
658
|
-
// Compare RegExps by their source patterns and flags.
|
659
|
-
var isRegExpA = _.isRegExp(a), isRegExpB = _.isRegExp(b);
|
660
|
-
if (isRegExpA || isRegExpB) {
|
661
|
-
// Ensure commutative equality for RegExps.
|
662
|
-
return isRegExpA && isRegExpB &&
|
663
|
-
a.source == b.source &&
|
664
|
-
a.global == b.global &&
|
665
|
-
a.multiline == b.multiline &&
|
666
|
-
a.ignoreCase == b.ignoreCase;
|
667
|
-
}
|
668
|
-
// Ensure that both values are objects.
|
669
|
-
if (typeA != 'object') return false;
|
675
|
+
if (a == null || b == null) return a === b;
|
670
676
|
// Unwrap any wrapped objects.
|
671
677
|
if (a._chain) a = a._wrapped;
|
672
678
|
if (b._chain) b = b._wrapped;
|
673
679
|
// Invoke a custom `isEqual` method if one is provided.
|
674
680
|
if (_.isFunction(a.isEqual)) return a.isEqual(b);
|
675
|
-
|
676
|
-
//
|
681
|
+
if (_.isFunction(b.isEqual)) return b.isEqual(a);
|
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;
|
709
|
+
}
|
710
|
+
if (typeof a != 'object' || typeof b != 'object') return false;
|
711
|
+
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
712
|
+
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
677
713
|
var length = stack.length;
|
678
714
|
while (length--) {
|
679
|
-
// Linear search. Performance is inversely proportional to the number of
|
680
|
-
// structures.
|
715
|
+
// Linear search. Performance is inversely proportional to the number of
|
716
|
+
// unique nested structures.
|
681
717
|
if (stack[length] == a) return true;
|
682
718
|
}
|
683
719
|
// Add the first object to the stack of traversed objects.
|
684
720
|
stack.push(a);
|
685
721
|
var size = 0, result = true;
|
686
|
-
|
687
|
-
|
722
|
+
// Recursively compare objects and arrays.
|
723
|
+
if (className == '[object Array]') {
|
724
|
+
// Compare array lengths to determine if a deep comparison is necessary.
|
688
725
|
size = a.length;
|
689
726
|
result = size == b.length;
|
690
727
|
if (result) {
|
691
|
-
// Deep compare
|
728
|
+
// Deep compare the contents, ignoring non-numeric properties.
|
692
729
|
while (size--) {
|
693
730
|
// Ensure commutative equality for sparse arrays.
|
694
731
|
if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
|
695
732
|
}
|
696
733
|
}
|
697
734
|
} else {
|
735
|
+
// Objects with different constructors are not equivalent.
|
736
|
+
if ("constructor" in a != "constructor" in b || a.constructor != b.constructor) return false;
|
698
737
|
// Deep compare objects.
|
699
738
|
for (var key in a) {
|
700
739
|
if (hasOwnProperty.call(a, key)) {
|
@@ -707,7 +746,7 @@
|
|
707
746
|
// Ensure that both objects contain the same number of properties.
|
708
747
|
if (result) {
|
709
748
|
for (key in b) {
|
710
|
-
if (hasOwnProperty.call(b, key) && !size--) break;
|
749
|
+
if (hasOwnProperty.call(b, key) && !(size--)) break;
|
711
750
|
}
|
712
751
|
result = !size;
|
713
752
|
}
|
@@ -722,7 +761,8 @@
|
|
722
761
|
return eq(a, b, []);
|
723
762
|
};
|
724
763
|
|
725
|
-
// Is a given array or object empty?
|
764
|
+
// Is a given array, string, or object empty?
|
765
|
+
// An "empty" object has no enumerable own-properties.
|
726
766
|
_.isEmpty = function(obj) {
|
727
767
|
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
|
728
768
|
for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
|
@@ -737,7 +777,7 @@
|
|
737
777
|
// Is a given value an array?
|
738
778
|
// Delegates to ECMA5's native Array.isArray
|
739
779
|
_.isArray = nativeIsArray || function(obj) {
|
740
|
-
return toString.call(obj)
|
780
|
+
return toString.call(obj) == '[object Array]';
|
741
781
|
};
|
742
782
|
|
743
783
|
// Is a given variable an object?
|
@@ -746,28 +786,34 @@
|
|
746
786
|
};
|
747
787
|
|
748
788
|
// Is a given variable an arguments object?
|
749
|
-
|
750
|
-
|
751
|
-
|
789
|
+
if (toString.call(arguments) == '[object Arguments]') {
|
790
|
+
_.isArguments = function(obj) {
|
791
|
+
return toString.call(obj) == '[object Arguments]';
|
792
|
+
};
|
793
|
+
} else {
|
794
|
+
_.isArguments = function(obj) {
|
795
|
+
return !!(obj && hasOwnProperty.call(obj, 'callee'));
|
796
|
+
};
|
797
|
+
}
|
752
798
|
|
753
799
|
// Is a given value a function?
|
754
800
|
_.isFunction = function(obj) {
|
755
|
-
return
|
801
|
+
return toString.call(obj) == '[object Function]';
|
756
802
|
};
|
757
803
|
|
758
804
|
// Is a given value a string?
|
759
805
|
_.isString = function(obj) {
|
760
|
-
return
|
806
|
+
return toString.call(obj) == '[object String]';
|
761
807
|
};
|
762
808
|
|
763
809
|
// Is a given value a number?
|
764
810
|
_.isNumber = function(obj) {
|
765
|
-
return
|
811
|
+
return toString.call(obj) == '[object Number]';
|
766
812
|
};
|
767
813
|
|
768
|
-
// Is the given value `NaN`?
|
769
|
-
// that does not equal itself.
|
814
|
+
// Is the given value `NaN`?
|
770
815
|
_.isNaN = function(obj) {
|
816
|
+
// `NaN` is the only value for which `===` is not reflexive.
|
771
817
|
return obj !== obj;
|
772
818
|
};
|
773
819
|
|
@@ -778,12 +824,12 @@
|
|
778
824
|
|
779
825
|
// Is a given value a date?
|
780
826
|
_.isDate = function(obj) {
|
781
|
-
return
|
827
|
+
return toString.call(obj) == '[object Date]';
|
782
828
|
};
|
783
829
|
|
784
830
|
// Is the given value a regular expression?
|
785
831
|
_.isRegExp = function(obj) {
|
786
|
-
return
|
832
|
+
return toString.call(obj) == '[object RegExp]';
|
787
833
|
};
|
788
834
|
|
789
835
|
// Is a given value equal to null?
|
@@ -818,7 +864,7 @@
|
|
818
864
|
|
819
865
|
// Escape a string for HTML interpolation.
|
820
866
|
_.escape = function(string) {
|
821
|
-
return (''+string).replace(
|
867
|
+
return (''+string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/');
|
822
868
|
};
|
823
869
|
|
824
870
|
// Add your own custom functions to the Underscore object, ensuring that
|
@@ -862,14 +908,14 @@
|
|
862
908
|
})
|
863
909
|
.replace(c.evaluate || null, function(match, code) {
|
864
910
|
return "');" + code.replace(/\\'/g, "'")
|
865
|
-
.replace(/[\r\n\t]/g, ' ') + "__p.push('";
|
911
|
+
.replace(/[\r\n\t]/g, ' ') + ";__p.push('";
|
866
912
|
})
|
867
913
|
.replace(/\r/g, '\\r')
|
868
914
|
.replace(/\n/g, '\\n')
|
869
915
|
.replace(/\t/g, '\\t')
|
870
916
|
+ "');}return __p.join('');";
|
871
|
-
var func = new Function('obj', tmpl);
|
872
|
-
return data ? func(data) : func;
|
917
|
+
var func = new Function('obj', '_', tmpl);
|
918
|
+
return data ? func(data, _) : function(data) { return func(data, _) };
|
873
919
|
};
|
874
920
|
|
875
921
|
// The OOP Wrapper
|
@@ -928,4 +974,4 @@
|
|
928
974
|
return this._wrapped;
|
929
975
|
};
|
930
976
|
|
931
|
-
})();
|
977
|
+
}).call(this);
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: underscore-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-11-25 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email:
|
@@ -51,3 +51,4 @@ signing_key:
|
|
51
51
|
specification_version: 3
|
52
52
|
summary: underscore.js asset pipeline provider/wrapper
|
53
53
|
test_files: []
|
54
|
+
has_rdoc:
|