underscore-source 0.1.1 → 0.2.0

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 = "0.1.1"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -5,17 +5,22 @@
5
5
  // Oliver Steele's Functional, And John Resig's Micro-Templating.
6
6
  // For all details and documentation:
7
7
  // http://documentcloud.github.com/underscore/
8
- window.Underscore = {
8
+
9
+ (function() {
10
+
11
+ var root = (typeof window != 'undefined') ? window : exports;
9
12
 
10
- VERSION : '0.1.1',
13
+ var previousUnderscore = root._;
11
14
 
12
- PREVIOUS_UNDERSCORE : window._,
15
+ var _ = root._ = {};
13
16
 
17
+ _.VERSION = '0.2.0';
18
+
14
19
  /*------------------------ Collection Functions: ---------------------------*/
15
20
 
16
21
  // The cornerstone, an each implementation.
17
22
  // Handles objects implementing forEach, each, arrays, and raw objects.
18
- each : function(obj, iterator, context) {
23
+ _.each = function(obj, iterator, context) {
19
24
  var index = 0;
20
25
  try {
21
26
  if (obj.forEach) {
@@ -37,30 +42,30 @@ window.Underscore = {
37
42
  if (e != '__break__') throw e;
38
43
  }
39
44
  return obj;
40
- },
45
+ };
41
46
 
42
47
  // Return the results of applying the iterator to each element. Use Javascript
43
48
  // 1.6's version of map, if possible.
44
- map : function(obj, iterator, context) {
49
+ _.map = function(obj, iterator, context) {
45
50
  if (obj && obj.map) return obj.map(iterator, context);
46
51
  var results = [];
47
52
  _.each(obj, function(value, index) {
48
53
  results.push(iterator.call(context, value, index));
49
54
  });
50
55
  return results;
51
- },
56
+ };
52
57
 
53
- // Inject builds up a single result from a list of values. Also known as
54
- // reduce, or foldl.
55
- inject : function(obj, memo, iterator, context) {
58
+ // Reduce builds up a single result from a list of values. Also known as
59
+ // inject, or foldl.
60
+ _.reduce = function(obj, memo, iterator, context) {
56
61
  _.each(obj, function(value, index) {
57
62
  memo = iterator.call(context, memo, value, index);
58
63
  });
59
64
  return memo;
60
- },
65
+ };
61
66
 
62
67
  // Return the first value which passes a truth test.
63
- detect : function(obj, iterator, context) {
68
+ _.detect = function(obj, iterator, context) {
64
69
  var result;
65
70
  _.each(obj, function(value, index) {
66
71
  if (iterator.call(context, value, index)) {
@@ -69,31 +74,31 @@ window.Underscore = {
69
74
  }
70
75
  });
71
76
  return result;
72
- },
77
+ };
73
78
 
74
79
  // Return all the elements that pass a truth test. Use Javascript 1.6's
75
80
  // filter(), if it exists.
76
- select : function(obj, iterator, context) {
81
+ _.select = function(obj, iterator, context) {
77
82
  if (obj.filter) return obj.filter(iterator, context);
78
83
  var results = [];
79
84
  _.each(obj, function(value, index) {
80
85
  if (iterator.call(context, value, index)) results.push(value);
81
86
  });
82
87
  return results;
83
- },
88
+ };
84
89
 
85
90
  // Return all the elements for which a truth test fails.
86
- reject : function(obj, iterator, context) {
91
+ _.reject = function(obj, iterator, context) {
87
92
  var results = [];
88
93
  _.each(obj, function(value, index) {
89
94
  if (!iterator.call(context, value, index)) results.push(value);
90
95
  });
91
96
  return results;
92
- },
97
+ };
93
98
 
94
99
  // Determine whether all of the elements match a truth test. Delegate to
95
100
  // Javascript 1.6's every(), if it is present.
96
- all : function(obj, iterator, context) {
101
+ _.all = function(obj, iterator, context) {
97
102
  iterator = iterator || function(v){ return v; };
98
103
  if (obj.every) return obj.every(iterator, context);
99
104
  var result = true;
@@ -102,11 +107,11 @@ window.Underscore = {
102
107
  if (!result) throw '__break__';
103
108
  });
104
109
  return result;
105
- },
110
+ };
106
111
 
107
112
  // Determine if at least one element in the object matches a truth test. Use
108
113
  // Javascript 1.6's some(), if it exists.
109
- any : function(obj, iterator, context) {
114
+ _.any = function(obj, iterator, context) {
110
115
  iterator = iterator || function(v) { return v; };
111
116
  if (obj.some) return obj.some(iterator, context);
112
117
  var result = false;
@@ -114,11 +119,11 @@ window.Underscore = {
114
119
  if (result = !!iterator.call(context, value, index)) throw '__break__';
115
120
  });
116
121
  return result;
117
- },
122
+ };
118
123
 
119
124
  // Determine if a given value is included in the array or object,
120
125
  // based on '==='.
121
- include : function(obj, target) {
126
+ _.include = function(obj, target) {
122
127
  if (_.isArray(obj)) return _.indexOf(obj, target) != -1;
123
128
  var found = false;
124
129
  _.each(obj, function(pair) {
@@ -128,25 +133,25 @@ window.Underscore = {
128
133
  }
129
134
  });
130
135
  return found;
131
- },
136
+ };
132
137
 
133
138
  // Invoke a method with arguments on every item in a collection.
134
- invoke : function(obj, method) {
139
+ _.invoke = function(obj, method) {
135
140
  var args = _.toArray(arguments).slice(2);
136
141
  return _.map(obj, function(value) {
137
142
  return (method ? value[method] : value).apply(value, args);
138
143
  });
139
- },
144
+ };
140
145
 
141
146
  // Optimized version of a common use case of map: fetching a property.
142
- pluck : function(obj, key) {
147
+ _.pluck = function(obj, key) {
143
148
  var results = [];
144
149
  _.each(obj, function(value){ results.push(value[key]); });
145
150
  return results;
146
- },
151
+ };
147
152
 
148
153
  // Return the maximum item or (item-based computation).
149
- max : function(obj, iterator, context) {
154
+ _.max = function(obj, iterator, context) {
150
155
  if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
151
156
  var result;
152
157
  _.each(obj, function(value, index) {
@@ -154,10 +159,10 @@ window.Underscore = {
154
159
  if (result == null || computed >= result.computed) result = {value : value, computed : computed};
155
160
  });
156
161
  return result.value;
157
- },
162
+ };
158
163
 
159
164
  // Return the minimum element (or element-based computation).
160
- min : function(obj, iterator, context) {
165
+ _.min = function(obj, iterator, context) {
161
166
  if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
162
167
  var result;
163
168
  _.each(obj, function(value, index) {
@@ -165,10 +170,10 @@ window.Underscore = {
165
170
  if (result == null || computed < result.computed) result = {value : value, computed : computed};
166
171
  });
167
172
  return result.value;
168
- },
173
+ };
169
174
 
170
175
  // Sort the object's values by a criteria produced by an iterator.
171
- sortBy : function(obj, iterator, context) {
176
+ _.sortBy = function(obj, iterator, context) {
172
177
  return _.pluck(_.map(obj, function(value, index) {
173
178
  return {
174
179
  value : value,
@@ -178,11 +183,11 @@ window.Underscore = {
178
183
  var a = left.criteria, b = right.criteria;
179
184
  return a < b ? -1 : a > b ? 1 : 0;
180
185
  }), 'value');
181
- },
186
+ };
182
187
 
183
188
  // Use a comparator function to figure out at what index an object should
184
189
  // be inserted so as to maintain order. Uses binary search.
185
- sortedIndex : function(array, obj, iterator) {
190
+ _.sortedIndex = function(array, obj, iterator) {
186
191
  iterator = iterator || function(val) { return val; };
187
192
  var low = 0, high = array.length;
188
193
  while (low < high) {
@@ -190,163 +195,182 @@ window.Underscore = {
190
195
  iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
191
196
  }
192
197
  return low;
193
- },
198
+ };
194
199
 
195
200
  // Convert anything iterable into a real, live array.
196
- toArray : function(iterable) {
201
+ _.toArray = function(iterable) {
197
202
  if (!iterable) return [];
198
203
  if (_.isArray(iterable)) return iterable;
199
204
  return _.map(iterable, function(val){ return val; });
200
- },
205
+ };
201
206
 
202
207
  // Return the number of elements in an object.
203
- size : function(obj) {
208
+ _.size = function(obj) {
204
209
  return _.toArray(obj).length;
205
- },
210
+ };
206
211
 
207
212
  /*-------------------------- Array Functions: ------------------------------*/
208
213
 
209
214
  // Get the first element of an array.
210
- first : function(array) {
215
+ _.first = function(array) {
211
216
  return array[0];
212
- },
217
+ };
213
218
 
214
219
  // Get the last element of an array.
215
- last : function(array) {
220
+ _.last = function(array) {
216
221
  return array[array.length - 1];
217
- },
222
+ };
218
223
 
219
224
  // Trim out all falsy values from an array.
220
- compact : function(array) {
225
+ _.compact = function(array) {
221
226
  return _.select(array, function(value){ return !!value; });
222
- },
227
+ };
223
228
 
224
229
  // Return a completely flattened version of an array.
225
- flatten : function(array) {
226
- return _.inject(array, [], function(memo, value) {
230
+ _.flatten = function(array) {
231
+ return _.reduce(array, [], function(memo, value) {
227
232
  if (_.isArray(value)) return memo.concat(_.flatten(value));
228
233
  memo.push(value);
229
234
  return memo;
230
235
  });
231
- },
236
+ };
232
237
 
233
238
  // Return a version of the array that does not contain the specified value(s).
234
- without : function(array) {
239
+ _.without = function(array) {
235
240
  var values = array.slice.call(arguments, 0);
236
241
  return _.select(array, function(value){ return !_.include(values, value); });
237
- },
242
+ };
238
243
 
239
244
  // Produce a duplicate-free version of the array. If the array has already
240
245
  // been sorted, you have the option of using a faster algorithm.
241
- uniq : function(array, isSorted) {
242
- return _.inject(array, [], function(memo, el, i) {
246
+ _.uniq = function(array, isSorted) {
247
+ return _.reduce(array, [], function(memo, el, i) {
243
248
  if (0 == i || (isSorted ? _.last(memo) != el : !_.include(memo, el))) memo.push(el);
244
249
  return memo;
245
250
  });
246
- },
251
+ };
247
252
 
248
253
  // Produce an array that contains every item shared between all the
249
254
  // passed-in arrays.
250
- intersect : function(array) {
255
+ _.intersect = function(array) {
251
256
  var rest = _.toArray(arguments).slice(1);
252
257
  return _.select(_.uniq(array), function(item) {
253
258
  return _.all(rest, function(other) {
254
259
  return _.indexOf(other, item) >= 0;
255
260
  });
256
261
  });
257
- },
262
+ };
258
263
 
259
264
  // Zip together multiple lists into a single array -- elements that share
260
265
  // an index go together.
261
- zip : function() {
266
+ _.zip = function() {
262
267
  var args = _.toArray(arguments);
263
268
  var length = _.max(_.pluck(args, 'length'));
264
269
  var results = new Array(length);
265
270
  for (var i=0; i<length; i++) results[i] = _.pluck(args, String(i));
266
271
  return results;
267
- },
272
+ };
268
273
 
269
274
  // If the browser doesn't supply us with indexOf (I'm looking at you, MSIE),
270
275
  // we need this function. Return the position of the first occurence of an
271
276
  // item in an array, or -1 if the item is not included in the array.
272
- indexOf : function(array, item) {
277
+ _.indexOf = function(array, item) {
273
278
  if (array.indexOf) return array.indexOf(item);
274
- var length = array.length;
275
- for (i=0; i<length; i++) if (array[i] === item) return i;
279
+ for (i=0; i<array.length; i++) if (array[i] === item) return i;
280
+ return -1;
281
+ };
282
+
283
+ // Provide Javascript 1.6's lastIndexOf, delegating to the native function,
284
+ // if possible.
285
+ _.lastIndexOf = function(array, item) {
286
+ if (array.lastIndexOf) return array.lastIndexOf(item);
287
+ for (i=array.length - 1; i>=0; i--) if (array[i] === item) return i;
276
288
  return -1;
277
- },
289
+ };
278
290
 
279
291
  /* ----------------------- Function Functions: -----------------------------*/
280
292
 
281
293
  // Create a function bound to a given object (assigning 'this', and arguments,
282
294
  // optionally). Binding with arguments is also known as 'curry'.
283
- bind : function(func, context) {
295
+ _.bind = function(func, context) {
284
296
  if (!context) return func;
285
297
  var args = _.toArray(arguments).slice(2);
286
298
  return function() {
287
299
  var a = args.concat(_.toArray(arguments));
288
300
  return func.apply(context, a);
289
301
  };
290
- },
302
+ };
291
303
 
292
304
  // Bind all of an object's methods to that object. Useful for ensuring that
293
305
  // all callbacks defined on an object belong to it.
294
- bindAll : function() {
306
+ _.bindAll = function() {
295
307
  var args = _.toArray(arguments);
296
308
  var context = args.pop();
297
309
  _.each(args, function(methodName) {
298
310
  context[methodName] = _.bind(context[methodName], context);
299
311
  });
300
- },
312
+ };
301
313
 
302
314
  // Delays a function for the given number of milliseconds, and then calls
303
315
  // it with the arguments supplied.
304
- delay : function(func, wait) {
316
+ _.delay = function(func, wait) {
305
317
  var args = _.toArray(arguments).slice(2);
306
- return window.setTimeout(function(){ return func.apply(func, args); }, wait);
307
- },
318
+ return setTimeout(function(){ return func.apply(func, args); }, wait);
319
+ };
308
320
 
309
321
  // Defers a function, scheduling it to run after the current call stack has
310
322
  // cleared.
311
- defer : function(func) {
323
+ _.defer = function(func) {
312
324
  return _.delay.apply(_, [func, 1].concat(_.toArray(arguments).slice(1)));
313
- },
325
+ };
314
326
 
315
327
  // Returns the first function passed as an argument to the second,
316
328
  // allowing you to adjust arguments, run code before and after, and
317
329
  // conditionally execute the original function.
318
- wrap : function(func, wrapper) {
330
+ _.wrap = function(func, wrapper) {
319
331
  return function() {
320
332
  var args = [func].concat(_.toArray(arguments));
321
333
  return wrapper.apply(wrapper, args);
322
334
  };
323
- },
335
+ };
336
+
337
+ // Returns a function that is the composition of a list of functions, each
338
+ // consuming the return value of the function that follows.
339
+ _.compose = function() {
340
+ var funcs = _.toArray(arguments);
341
+ return function() {
342
+ for (var i=funcs.length-1; i >= 0; i--) {
343
+ arguments = [funcs[i].apply(this, arguments)];
344
+ }
345
+ return arguments[0];
346
+ };
347
+ };
324
348
 
325
349
  /* ------------------------- Object Functions: ---------------------------- */
326
350
 
327
351
  // Retrieve the names of an object's properties.
328
- keys : function(obj) {
352
+ _.keys = function(obj) {
329
353
  return _.pluck(obj, 'key');
330
- },
354
+ };
331
355
 
332
356
  // Retrieve the values of an object's properties.
333
- values : function(obj) {
357
+ _.values = function(obj) {
334
358
  return _.pluck(obj, 'value');
335
- },
359
+ };
336
360
 
337
361
  // Extend a given object with all of the properties in a source object.
338
- extend : function(destination, source) {
362
+ _.extend = function(destination, source) {
339
363
  for (var property in source) destination[property] = source[property];
340
364
  return destination;
341
- },
365
+ };
342
366
 
343
367
  // Create a (shallow-cloned) duplicate of an object.
344
- clone : function(obj) {
368
+ _.clone = function(obj) {
345
369
  return _.extend({}, obj);
346
- },
370
+ };
347
371
 
348
372
  // Perform a deep comparison to check if two objects are equal.
349
- isEqual : function(a, b) {
373
+ _.isEqual = function(a, b) {
350
374
  // Check object identity.
351
375
  if (a === b) return true;
352
376
  // Different types?
@@ -365,47 +389,47 @@ window.Underscore = {
365
389
  // Recursive comparison of contents.
366
390
  for (var key in a) if (!_.isEqual(a[key], b[key])) return false;
367
391
  return true;
368
- },
392
+ };
369
393
 
370
394
  // Is a given value a DOM element?
371
- isElement : function(obj) {
395
+ _.isElement = function(obj) {
372
396
  return !!(obj && obj.nodeType == 1);
373
- },
397
+ };
374
398
 
375
399
  // Is a given value a real Array?
376
- isArray : function(obj) {
400
+ _.isArray = function(obj) {
377
401
  return Object.prototype.toString.call(obj) == '[object Array]';
378
- },
402
+ };
379
403
 
380
404
  // Is a given value a Function?
381
- isFunction : function(obj) {
405
+ _.isFunction = function(obj) {
382
406
  return typeof obj == 'function';
383
- },
407
+ };
384
408
 
385
409
  // Is a given variable undefined?
386
- isUndefined : function(obj) {
410
+ _.isUndefined = function(obj) {
387
411
  return typeof obj == 'undefined';
388
- },
412
+ };
389
413
 
390
414
  /* -------------------------- Utility Functions: -------------------------- */
391
415
 
392
416
  // Run Underscore.js in noConflict mode, returning the '_' variable to its
393
417
  // previous owner. Returns a reference to the Underscore object.
394
- noConflict : function() {
395
- window._ = Underscore.PREVIOUS_UNDERSCORE;
418
+ _.noConflict = function() {
419
+ root._ = previousUnderscore;
396
420
  return this;
397
- },
421
+ };
398
422
 
399
423
  // Generate a unique integer id (unique within the entire client session).
400
424
  // Useful for temporary DOM ids.
401
- uniqueId : function(prefix) {
425
+ _.uniqueId = function(prefix) {
402
426
  var id = this._idCounter = (this._idCounter || 0) + 1;
403
427
  return prefix ? prefix + id : id;
404
- },
428
+ };
405
429
 
406
430
  // Javascript templating a-la ERB, pilfered from John Resig's
407
431
  // "Secrets of the Javascript Ninja", page 83.
408
- template : function(str, data) {
432
+ _.template = function(str, data) {
409
433
  var fn = new Function('obj',
410
434
  'var p=[],print=function(){p.push.apply(p,arguments);};' +
411
435
  'with(obj){p.push(\'' +
@@ -419,8 +443,18 @@ window.Underscore = {
419
443
  .split("\r").join("\\'")
420
444
  + "');}return p.join('');");
421
445
  return data ? fn(data) : fn;
422
- }
446
+ };
447
+
448
+ /*------------------------------- Aliases ----------------------------------*/
449
+
450
+ _.forEach = _.each;
451
+ _.inject = _.reduce;
452
+ _.filter = _.select;
453
+ _.every = _.all;
454
+ _.some = _.any;
455
+
456
+ /*------------------------- Export for ServerJS ----------------------------*/
423
457
 
424
- };
458
+ if (!_.isUndefined(exports)) exports = _;
425
459
 
426
- window._ = Underscore;
460
+ })();
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: underscore-source
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.1
5
+ version: 0.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Daniel X. Moore