underscore-source 1.1.0 → 1.1.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.
@@ -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