underscore-source 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  module Underscore
2
2
  module Source
3
- VERSION = "1.1.0"
3
+ VERSION = "1.1.1"
4
4
  end
5
5
  end
@@ -1,24 +1,25 @@
1
- // Underscore.js
2
- // (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
3
- // Underscore is freely distributable under the terms of the MIT license.
4
- // Portions of Underscore are inspired by or borrowed from Prototype.js,
5
- // Oliver Steele's Functional, and John Resig's Micro-Templating.
6
- // For all details and documentation:
7
- // http://documentcloud.github.com/underscore
1
+ // (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
2
+ // Underscore is freely distributable under the terms of the MIT license.
3
+ // Portions of Underscore are inspired by or borrowed from Prototype.js,
4
+ // Oliver Steele's Functional, and John Resig's Micro-Templating.
5
+ // For all details and documentation:
6
+ // http://documentcloud.github.com/underscore
8
7
 
9
8
  (function() {
10
- // ------------------------- Baseline setup ---------------------------------
11
9
 
12
- // Establish the root object, "window" in the browser, or "global" on the server.
10
+ // Baseline setup
11
+ // --------------
12
+
13
+ // Establish the root object, `window` in the browser, or `global` on the server.
13
14
  var root = this;
14
15
 
15
- // Save the previous value of the "_" variable.
16
+ // Save the previous value of the `_` variable.
16
17
  var previousUnderscore = root._;
17
18
 
18
19
  // Establish the object that gets thrown to break out of a loop iteration.
19
20
  var breaker = typeof StopIteration !== 'undefined' ? StopIteration : '__break__';
20
21
 
21
- // Quick regexp-escaping function, because JS doesn't have RegExp.escape().
22
+ // Quick regexp-escaping function, because JS doesn't have a `RegExp.escape()`.
22
23
  var escapeRegExp = function(s) { return s.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1'); };
23
24
 
24
25
  // Save bytes in the minified (but not gzipped) version:
@@ -31,7 +32,8 @@
31
32
  hasOwnProperty = ObjProto.hasOwnProperty,
32
33
  propertyIsEnumerable = ObjProto.propertyIsEnumerable;
33
34
 
34
- // All ECMA5 native implementations we hope to use are declared here.
35
+ // All **ECMAScript 5** native function implementations that we hope to use
36
+ // are declared here.
35
37
  var
36
38
  nativeForEach = ArrayProto.forEach,
37
39
  nativeMap = ArrayProto.map,
@@ -48,20 +50,21 @@
48
50
  // Create a safe reference to the Underscore object for use below.
49
51
  var _ = function(obj) { return new wrapper(obj); };
50
52
 
51
- // Export the Underscore object for CommonJS.
53
+ // Export the Underscore object for **CommonJS**.
52
54
  if (typeof exports !== 'undefined') exports._ = _;
53
55
 
54
- // Export underscore to global scope.
56
+ // Export Underscore to the global scope.
55
57
  root._ = _;
56
58
 
57
59
  // Current version.
58
- _.VERSION = '1.1.0';
60
+ _.VERSION = '1.1.1';
59
61
 
60
- // ------------------------ Collection Functions: ---------------------------
62
+ // Collection Functions
63
+ // --------------------
61
64
 
62
- // The cornerstone, an each implementation.
63
- // Handles objects implementing forEach, arrays, and raw objects.
64
- // Delegates to JavaScript 1.6's native forEach if available.
65
+ // The cornerstone, an `each` implementation.
66
+ // Handles objects implementing `forEach`, arrays, and raw objects.
67
+ // Delegates to **ECMAScript 5**'s native `forEach` if available.
65
68
  var each = _.forEach = function(obj, iterator, context) {
66
69
  try {
67
70
  if (nativeForEach && obj.forEach === nativeForEach) {
@@ -80,18 +83,18 @@
80
83
  };
81
84
 
82
85
  // Return the results of applying the iterator to each element.
83
- // Delegates to JavaScript 1.6's native map if available.
86
+ // Delegates to **ECMAScript 5**'s native `map` if available.
84
87
  _.map = function(obj, iterator, context) {
85
88
  if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
86
89
  var results = [];
87
90
  each(obj, function(value, index, list) {
88
- results.push(iterator.call(context, value, index, list));
91
+ results[results.length] = iterator.call(context, value, index, list);
89
92
  });
90
93
  return results;
91
94
  };
92
95
 
93
- // Reduce builds up a single result from a list of values, aka inject, or foldl.
94
- // Delegates to JavaScript 1.8's native reduce if available.
96
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
97
+ // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
95
98
  _.reduce = function(obj, iterator, memo, context) {
96
99
  if (nativeReduce && obj.reduce === nativeReduce) {
97
100
  if (context) iterator = _.bind(iterator, context);
@@ -103,8 +106,8 @@
103
106
  return memo;
104
107
  };
105
108
 
106
- // The right-associative version of reduce, also known as foldr. Uses
107
- // Delegates to JavaScript 1.8's native reduceRight if available.
109
+ // The right-associative version of reduce, also known as `foldr`. Uses
110
+ // Delegates to **ECMAScript 5**'s native reduceRight if available.
108
111
  _.reduceRight = function(obj, iterator, memo, context) {
109
112
  if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
110
113
  if (context) iterator = _.bind(iterator, context);
@@ -127,12 +130,12 @@
127
130
  };
128
131
 
129
132
  // Return all the elements that pass a truth test.
130
- // Delegates to JavaScript 1.6's native filter if available.
133
+ // Delegates to **ECMAScript 5**'s native `filter` if available.
131
134
  _.filter = function(obj, iterator, context) {
132
135
  if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
133
136
  var results = [];
134
137
  each(obj, function(value, index, list) {
135
- iterator.call(context, value, index, list) && results.push(value);
138
+ if (iterator.call(context, value, index, list)) results[results.length] = value;
136
139
  });
137
140
  return results;
138
141
  };
@@ -141,13 +144,13 @@
141
144
  _.reject = function(obj, iterator, context) {
142
145
  var results = [];
143
146
  each(obj, function(value, index, list) {
144
- !iterator.call(context, value, index, list) && results.push(value);
147
+ if (!iterator.call(context, value, index, list)) results[results.length] = value;
145
148
  });
146
149
  return results;
147
150
  };
148
151
 
149
152
  // Determine whether all of the elements match a truth test.
150
- // Delegates to JavaScript 1.6's native every if available.
153
+ // Delegates to **ECMAScript 5**'s native `every` if available.
151
154
  _.every = function(obj, iterator, context) {
152
155
  iterator = iterator || _.identity;
153
156
  if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
@@ -159,7 +162,7 @@
159
162
  };
160
163
 
161
164
  // Determine if at least one element in the object matches a truth test.
162
- // Delegates to JavaScript 1.6's native some if available.
165
+ // Delegates to **ECMAScript 5**'s native `some` if available.
163
166
  _.some = function(obj, iterator, context) {
164
167
  iterator = iterator || _.identity;
165
168
  if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
@@ -170,7 +173,7 @@
170
173
  return result;
171
174
  };
172
175
 
173
- // Determine if a given value is included in the array or object using '==='.
176
+ // Determine if a given value is included in the array or object using `===`.
174
177
  _.include = function(obj, target) {
175
178
  if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
176
179
  var found = false;
@@ -180,20 +183,20 @@
180
183
  return found;
181
184
  };
182
185
 
183
- // Invoke a method with arguments on every item in a collection.
186
+ // Invoke a method (with arguments) on every item in a collection.
184
187
  _.invoke = function(obj, method) {
185
- var args = _.rest(arguments, 2);
188
+ var args = slice.call(arguments, 2);
186
189
  return _.map(obj, function(value) {
187
190
  return (method ? value[method] : value).apply(value, args);
188
191
  });
189
192
  };
190
193
 
191
- // Convenience version of a common use case of map: fetching a property.
194
+ // Convenience version of a common use case of `map`: fetching a property.
192
195
  _.pluck = function(obj, key) {
193
196
  return _.map(obj, function(value){ return value[key]; });
194
197
  };
195
198
 
196
- // Return the maximum item or (item-based computation).
199
+ // Return the maximum element or (element-based computation).
197
200
  _.max = function(obj, iterator, context) {
198
201
  if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
199
202
  var result = {computed : -Infinity};
@@ -240,7 +243,7 @@
240
243
  return low;
241
244
  };
242
245
 
243
- // Convert anything iterable into a real, live array.
246
+ // Safely convert anything iterable into a real, live array.
244
247
  _.toArray = function(iterable) {
245
248
  if (!iterable) return [];
246
249
  if (iterable.toArray) return iterable.toArray();
@@ -254,19 +257,20 @@
254
257
  return _.toArray(obj).length;
255
258
  };
256
259
 
257
- // -------------------------- Array Functions: ------------------------------
260
+ // Array Functions
261
+ // ---------------
258
262
 
259
- // Get the first element of an array. Passing "n" will return the first N
260
- // values in the array. Aliased as "head". The "guard" check allows it to work
261
- // with _.map.
263
+ // Get the first element of an array. Passing **n** will return the first N
264
+ // values in the array. Aliased as `head`. The **guard** check allows it to work
265
+ // with `_.map`.
262
266
  _.first = function(array, n, guard) {
263
267
  return n && !guard ? slice.call(array, 0, n) : array[0];
264
268
  };
265
269
 
266
- // Returns everything but the first entry of the array. Aliased as "tail".
267
- // Especially useful on the arguments object. Passing an "index" will return
268
- // the rest of the values in the array from that index onward. The "guard"
269
- //check allows it to work with _.map.
270
+ // Returns everything but the first entry of the array. Aliased as `tail`.
271
+ // Especially useful on the arguments object. Passing an **index** will return
272
+ // the rest of the values in the array from that index onward. The **guard**
273
+ // check allows it to work with `_.map`.
270
274
  _.rest = function(array, index, guard) {
271
275
  return slice.call(array, _.isUndefined(index) || guard ? 1 : index);
272
276
  };
@@ -285,14 +289,14 @@
285
289
  _.flatten = function(array) {
286
290
  return _.reduce(array, function(memo, value) {
287
291
  if (_.isArray(value)) return memo.concat(_.flatten(value));
288
- memo.push(value);
292
+ memo[memo.length] = value;
289
293
  return memo;
290
294
  }, []);
291
295
  };
292
296
 
293
297
  // Return a version of the array that does not contain the specified value(s).
294
298
  _.without = function(array) {
295
- var values = _.rest(arguments);
299
+ var values = slice.call(arguments, 1);
296
300
  return _.filter(array, function(value){ return !_.include(values, value); });
297
301
  };
298
302
 
@@ -300,7 +304,7 @@
300
304
  // been sorted, you have the option of using a faster algorithm.
301
305
  _.uniq = function(array, isSorted) {
302
306
  return _.reduce(array, function(memo, el, i) {
303
- if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo.push(el);
307
+ if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el;
304
308
  return memo;
305
309
  }, []);
306
310
  };
@@ -308,7 +312,7 @@
308
312
  // Produce an array that contains every item shared between all the
309
313
  // passed-in arrays.
310
314
  _.intersect = function(array) {
311
- var rest = _.rest(arguments);
315
+ var rest = slice.call(arguments, 1);
312
316
  return _.filter(_.uniq(array), function(item) {
313
317
  return _.every(rest, function(other) {
314
318
  return _.indexOf(other, item) >= 0;
@@ -319,17 +323,17 @@
319
323
  // Zip together multiple lists into a single array -- elements that share
320
324
  // an index go together.
321
325
  _.zip = function() {
322
- var args = _.toArray(arguments);
326
+ var args = slice.call(arguments);
323
327
  var length = _.max(_.pluck(args, 'length'));
324
328
  var results = new Array(length);
325
- for (var i = 0; i < length; i++) results[i] = _.pluck(args, String(i));
329
+ for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
326
330
  return results;
327
331
  };
328
332
 
329
333
  // If the browser doesn't supply us with indexOf (I'm looking at you, MSIE),
330
334
  // we need this function. Return the position of the first occurence of an
331
335
  // item in an array, or -1 if the item is not included in the array.
332
- // Delegates to JavaScript 1.8's native indexOf if available.
336
+ // Delegates to **ECMAScript 5**'s native `indexOf` if available.
333
337
  _.indexOf = function(array, item) {
334
338
  if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
335
339
  for (var i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
@@ -337,7 +341,7 @@
337
341
  };
338
342
 
339
343
 
340
- // Delegates to JavaScript 1.6's native lastIndexOf if available.
344
+ // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
341
345
  _.lastIndexOf = function(array, item) {
342
346
  if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
343
347
  var i = array.length;
@@ -346,10 +350,10 @@
346
350
  };
347
351
 
348
352
  // Generate an integer Array containing an arithmetic progression. A port of
349
- // the native Python range() function. See:
350
- // http://docs.python.org/library/functions.html#range
353
+ // the native Python `range()` function. See
354
+ // [the Python documentation](http://docs.python.org/library/functions.html#range).
351
355
  _.range = function(start, stop, step) {
352
- var a = _.toArray(arguments);
356
+ var a = slice.call(arguments);
353
357
  var solo = a.length <= 1;
354
358
  var start = solo ? 0 : a[0], stop = solo ? a[0] : a[1], step = a[2] || 1;
355
359
  var len = Math.ceil((stop - start) / step);
@@ -361,21 +365,22 @@
361
365
  }
362
366
  };
363
367
 
364
- // ----------------------- Function Functions: ------------------------------
368
+ // Function Functions
369
+ // ------------------
365
370
 
366
- // Create a function bound to a given object (assigning 'this', and arguments,
367
- // optionally). Binding with arguments is also known as 'curry'.
371
+ // Create a function bound to a given object (assigning `this`, and arguments,
372
+ // optionally). Binding with arguments is also known as `curry`.
368
373
  _.bind = function(func, obj) {
369
- var args = _.rest(arguments, 2);
374
+ var args = slice.call(arguments, 2);
370
375
  return function() {
371
- return func.apply(obj || {}, args.concat(_.toArray(arguments)));
376
+ return func.apply(obj || {}, args.concat(slice.call(arguments)));
372
377
  };
373
378
  };
374
379
 
375
380
  // Bind all of an object's methods to that object. Useful for ensuring that
376
381
  // all callbacks defined on an object belong to it.
377
382
  _.bindAll = function(obj) {
378
- var funcs = _.rest(arguments);
383
+ var funcs = slice.call(arguments, 1);
379
384
  if (funcs.length == 0) funcs = _.functions(obj);
380
385
  each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
381
386
  return obj;
@@ -394,14 +399,14 @@
394
399
  // Delays a function for the given number of milliseconds, and then calls
395
400
  // it with the arguments supplied.
396
401
  _.delay = function(func, wait) {
397
- var args = _.rest(arguments, 2);
402
+ var args = slice.call(arguments, 2);
398
403
  return setTimeout(function(){ return func.apply(func, args); }, wait);
399
404
  };
400
405
 
401
406
  // Defers a function, scheduling it to run after the current call stack has
402
407
  // cleared.
403
408
  _.defer = function(func) {
404
- return _.delay.apply(_, [func, 1].concat(_.rest(arguments)));
409
+ return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
405
410
  };
406
411
 
407
412
  // Returns the first function passed as an argument to the second,
@@ -409,7 +414,7 @@
409
414
  // conditionally execute the original function.
410
415
  _.wrap = function(func, wrapper) {
411
416
  return function() {
412
- var args = [func].concat(_.toArray(arguments));
417
+ var args = [func].concat(slice.call(arguments));
413
418
  return wrapper.apply(wrapper, args);
414
419
  };
415
420
  };
@@ -417,9 +422,9 @@
417
422
  // Returns a function that is the composition of a list of functions, each
418
423
  // consuming the return value of the function that follows.
419
424
  _.compose = function() {
420
- var funcs = _.toArray(arguments);
425
+ var funcs = slice.call(arguments);
421
426
  return function() {
422
- var args = _.toArray(arguments);
427
+ var args = slice.call(arguments);
423
428
  for (var i=funcs.length-1; i >= 0; i--) {
424
429
  args = [funcs[i].apply(this, args)];
425
430
  }
@@ -427,14 +432,15 @@
427
432
  };
428
433
  };
429
434
 
430
- // ------------------------- Object Functions: ------------------------------
435
+ // Object Functions
436
+ // ----------------
431
437
 
432
438
  // Retrieve the names of an object's properties.
433
- // Delegates to ECMA5's native Object.keys
439
+ // Delegates to **ECMAScript 5**'s native `Object.keys`
434
440
  _.keys = nativeKeys || function(obj) {
435
441
  if (_.isArray(obj)) return _.range(0, obj.length);
436
442
  var keys = [];
437
- for (var key in obj) if (hasOwnProperty.call(obj, key)) keys.push(key);
443
+ for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
438
444
  return keys;
439
445
  };
440
446
 
@@ -450,7 +456,7 @@
450
456
 
451
457
  // Extend a given object with all the properties in passed-in object(s).
452
458
  _.extend = function(obj) {
453
- each(_.rest(arguments), function(source) {
459
+ each(slice.call(arguments, 1), function(source) {
454
460
  for (var prop in source) obj[prop] = source[prop];
455
461
  });
456
462
  return obj;
@@ -463,7 +469,8 @@
463
469
  };
464
470
 
465
471
  // Invokes interceptor with the obj, and then returns obj.
466
- // The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain.
472
+ // The primary purpose of this method is to "tap into" a method chain, in
473
+ // order to perform operations on intermediate results within the chain.
467
474
  _.tap = function(obj, interceptor) {
468
475
  interceptor(obj);
469
476
  return obj;
@@ -525,7 +532,7 @@
525
532
 
526
533
  // Is a given variable an arguments object?
527
534
  _.isArguments = function(obj) {
528
- return obj && obj.callee;
535
+ return !!(obj && obj.callee);
529
536
  };
530
537
 
531
538
  // Is a given value a function?
@@ -574,9 +581,10 @@
574
581
  return typeof obj == 'undefined';
575
582
  };
576
583
 
577
- // -------------------------- Utility Functions: ----------------------------
584
+ // Utility Functions
585
+ // -----------------
578
586
 
579
- // Run Underscore.js in noConflict mode, returning the '_' variable to its
587
+ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
580
588
  // previous owner. Returns a reference to the Underscore object.
581
589
  _.noConflict = function() {
582
590
  root._ = previousUnderscore;
@@ -588,7 +596,7 @@
588
596
  return value;
589
597
  };
590
598
 
591
- // Run a function n times.
599
+ // Run a function **n** times.
592
600
  _.times = function (n, iterator, context) {
593
601
  for (var i = 0; i < n; i++) iterator.call(context, i);
594
602
  };
@@ -617,35 +625,35 @@
617
625
  // By default, Underscore uses ERB-style template delimiters, change the
618
626
  // following template settings to use alternative delimiters.
619
627
  _.templateSettings = {
620
- start : '<%',
621
- end : '%>',
622
- interpolate : /<%=(.+?)%>/g
628
+ evaluate : /<%([\s\S]+?)%>/g,
629
+ interpolate : /<%=([\s\S]+?)%>/g
623
630
  };
624
631
 
625
- // JavaScript templating a-la ERB, pilfered from John Resig's
626
- // "Secrets of the JavaScript Ninja", page 83.
627
- // Single-quote fix from Rick Strahl's version.
628
- // With alterations for arbitrary delimiters, and to preserve whitespace.
632
+ // JavaScript micro-templating, similar to John Resig's implementation.
633
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
634
+ // and correctly escapes quotes within interpolated code.
629
635
  _.template = function(str, data) {
630
636
  var c = _.templateSettings;
631
- var endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g");
632
- var fn = new Function('obj',
633
- 'var p=[],print=function(){p.push.apply(p,arguments);};' +
634
- 'with(obj||{}){p.push(\'' +
635
- str.replace(/\r/g, '\\r')
637
+ var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
638
+ 'with(obj||{}){__p.push(\'' +
639
+ str.replace(/'/g, "\\'")
640
+ .replace(c.interpolate, function(match, code) {
641
+ return "'," + code.replace(/\\'/g, "'") + ",'";
642
+ })
643
+ .replace(c.evaluate || null, function(match, code) {
644
+ return "');" + code.replace(/\\'/g, "'")
645
+ .replace(/[\r\n\t]/g, ' ') + "__p.push('";
646
+ })
647
+ .replace(/\r/g, '\\r')
636
648
  .replace(/\n/g, '\\n')
637
649
  .replace(/\t/g, '\\t')
638
- .replace(endMatch,"✄")
639
- .split("'").join("\\'")
640
- .split("✄").join("'")
641
- .replace(c.interpolate, "',$1,'")
642
- .split(c.start).join("');")
643
- .split(c.end).join("p.push('")
644
- + "');}return p.join('');");
645
- return data ? fn(data) : fn;
650
+ + "');}return __p.join('');";
651
+ var func = new Function('obj', tmpl);
652
+ return data ? func(data) : func;
646
653
  };
647
654
 
648
- // ------------------------------- Aliases ----------------------------------
655
+ // Aliases:
656
+ // --------
649
657
 
650
658
  _.each = _.forEach;
651
659
  _.foldl = _.inject = _.reduce;
@@ -658,7 +666,8 @@
658
666
  _.tail = _.rest;
659
667
  _.methods = _.functions;
660
668
 
661
- // ------------------------ Setup the OOP Wrapper: --------------------------
669
+ // The OOP Wrapper
670
+ // ---------------
662
671
 
663
672
  // If Underscore is called as a function, it returns a wrapped object that
664
673
  // can be used OO-style. This wrapper holds altered versions of all the
@@ -673,7 +682,7 @@
673
682
  // A method to easily add functions to the OOP wrapper.
674
683
  var addToWrapper = function(name, func) {
675
684
  wrapper.prototype[name] = function() {
676
- var args = _.toArray(arguments);
685
+ var args = slice.call(arguments);
677
686
  unshift.call(args, this._wrapped);
678
687
  return result(func.apply(_, args), this._chain);
679
688
  };
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: underscore-source
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.1.0
5
+ version: 1.1.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Daniel X. Moore