appetizer-ui 0.0.0 → 0.1.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.
@@ -10,7 +10,7 @@ Gem::Specification.new do |gem|
10
10
  gem.test_files = `git ls-files -- test/*`.split("\n")
11
11
  gem.name = "appetizer-ui"
12
12
  gem.require_paths = ["lib"]
13
- gem.version = "0.0.0"
13
+ gem.version = "0.1.0"
14
14
 
15
15
  gem.required_ruby_version = ">= 1.9.2"
16
16
 
@@ -1,4 +1,4 @@
1
- // Backbone.js 0.5.2
1
+ // Backbone.js 0.5.3
2
2
  // (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
3
3
  // Backbone may be freely distributed under the MIT license.
4
4
  // For all details and documentation:
@@ -25,7 +25,7 @@
25
25
  }
26
26
 
27
27
  // Current version of the library. Keep in sync with `package.json`.
28
- Backbone.VERSION = '0.5.2';
28
+ Backbone.VERSION = '0.5.3';
29
29
 
30
30
  // Require Underscore, if we're on the server, and it's not already present.
31
31
  var _ = root._;
@@ -41,7 +41,7 @@
41
41
  return this;
42
42
  };
43
43
 
44
- // Turn on `emulateHTTP` to use support legacy HTTP servers. Setting this option will
44
+ // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option will
45
45
  // fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and set a
46
46
  // `X-Http-Method-Override` header.
47
47
  Backbone.emulateHTTP = false;
@@ -641,7 +641,7 @@
641
641
  var methods = ['forEach', 'each', 'map', 'reduce', 'reduceRight', 'find', 'detect',
642
642
  'filter', 'select', 'reject', 'every', 'all', 'some', 'any', 'include',
643
643
  'contains', 'invoke', 'max', 'min', 'sortBy', 'sortedIndex', 'toArray', 'size',
644
- 'first', 'rest', 'last', 'without', 'indexOf', 'lastIndexOf', 'isEmpty'];
644
+ 'first', 'rest', 'last', 'without', 'indexOf', 'lastIndexOf', 'isEmpty', 'groupBy'];
645
645
 
646
646
  // Mix in each Underscore method as a proxy to `Collection#models`.
647
647
  _.each(methods, function(method) {
@@ -766,7 +766,7 @@
766
766
  fragment = window.location.hash;
767
767
  }
768
768
  }
769
- return fragment.replace(hashStrip, '');
769
+ return decodeURIComponent(fragment.replace(hashStrip, ''));
770
770
  },
771
771
 
772
772
  // Start the hash change handling, returning `true` if the current URL matches
@@ -812,7 +812,10 @@
812
812
  this.fragment = loc.hash.replace(hashStrip, '');
813
813
  window.history.replaceState({}, document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment);
814
814
  }
815
- return this.loadUrl();
815
+
816
+ if (!this.options.silent) {
817
+ return this.loadUrl();
818
+ }
816
819
  },
817
820
 
818
821
  // Add a route to be tested when the fragment changes. Routes added later may
@@ -949,6 +952,7 @@
949
952
  // not `change`, `submit`, and `reset` in Internet Explorer.
950
953
  delegateEvents : function(events) {
951
954
  if (!(events || (events = this.events))) return;
955
+ if (_.isFunction(events)) events = events.call(this);
952
956
  $(this.el).unbind('.delegateEvents' + this.cid);
953
957
  for (var key in events) {
954
958
  var method = this[events[key]];
@@ -1070,7 +1074,7 @@
1070
1074
  }
1071
1075
 
1072
1076
  // Don't process data on a non-GET request.
1073
- if (params.type !== 'GET') {
1077
+ if (params.type !== 'GET' && !Backbone.emulateJSON) {
1074
1078
  params.processData = false;
1075
1079
  }
1076
1080
 
@@ -1,5 +1,5 @@
1
- // Underscore.js 1.1.7
2
- // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
1
+ // Underscore.js 1.2.3
2
+ // (c) 2009-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,
5
5
  // Oliver Steele's Functional, and John Resig's Micro-Templating.
@@ -25,6 +25,7 @@
25
25
 
26
26
  // Create quick reference variables for speed access to core prototypes.
27
27
  var slice = ArrayProto.slice,
28
+ concat = ArrayProto.concat,
28
29
  unshift = ArrayProto.unshift,
29
30
  toString = ObjProto.toString,
30
31
  hasOwnProperty = ObjProto.hasOwnProperty;
@@ -48,19 +49,26 @@
48
49
  // Create a safe reference to the Underscore object for use below.
49
50
  var _ = function(obj) { return new wrapper(obj); };
50
51
 
51
- // Export the Underscore object for **CommonJS**, with backwards-compatibility
52
- // for the old `require()` API. If we're not in CommonJS, add `_` to the
53
- // global object.
54
- if (typeof module !== 'undefined' && module.exports) {
55
- module.exports = _;
56
- _._ = _;
52
+ // Export the Underscore object for **Node.js** and **"CommonJS"**, with
53
+ // backwards-compatibility for the old `require()` API. If we're not in
54
+ // CommonJS, add `_` to the global object.
55
+ if (typeof exports !== 'undefined') {
56
+ if (typeof module !== 'undefined' && module.exports) {
57
+ exports = module.exports = _;
58
+ }
59
+ exports._ = _;
60
+ } else if (typeof define === 'function' && define.amd) {
61
+ // Register as a named module with AMD.
62
+ define('underscore', function() {
63
+ return _;
64
+ });
57
65
  } else {
58
66
  // Exported as a string, for Closure Compiler "advanced" mode.
59
67
  root['_'] = _;
60
68
  }
61
69
 
62
70
  // Current version.
63
- _.VERSION = '1.1.7';
71
+ _.VERSION = '1.2.3';
64
72
 
65
73
  // Collection Functions
66
74
  // --------------------
@@ -100,7 +108,7 @@
100
108
  // **Reduce** builds up a single result from a list of values, aka `inject`,
101
109
  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
102
110
  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
103
- var initial = memo !== void 0;
111
+ var initial = arguments.length > 2;
104
112
  if (obj == null) obj = [];
105
113
  if (nativeReduce && obj.reduce === nativeReduce) {
106
114
  if (context) iterator = _.bind(iterator, context);
@@ -114,20 +122,22 @@
114
122
  memo = iterator.call(context, memo, value, index, list);
115
123
  }
116
124
  });
117
- if (!initial) throw new TypeError("Reduce of empty array with no initial value");
125
+ if (!initial) throw new TypeError('Reduce of empty array with no initial value');
118
126
  return memo;
119
127
  };
120
128
 
121
129
  // The right-associative version of reduce, also known as `foldr`.
122
130
  // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
123
131
  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
132
+ var initial = arguments.length > 2;
124
133
  if (obj == null) obj = [];
125
134
  if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
126
135
  if (context) iterator = _.bind(iterator, context);
127
- return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
136
+ return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
128
137
  }
129
- var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
130
- return _.reduce(reversed, iterator, memo, context);
138
+ var reversed = _.toArray(obj).reverse();
139
+ if (context && !initial) iterator = _.bind(iterator, context);
140
+ return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
131
141
  };
132
142
 
133
143
  // Return the first value which passes a truth test. Aliased as `detect`.
@@ -182,12 +192,12 @@
182
192
  // Delegates to **ECMAScript 5**'s native `some` if available.
183
193
  // Aliased as `any`.
184
194
  var any = _.some = _.any = function(obj, iterator, context) {
185
- iterator = iterator || _.identity;
195
+ iterator || (iterator = _.identity);
186
196
  var result = false;
187
197
  if (obj == null) return result;
188
198
  if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
189
199
  each(obj, function(value, index, list) {
190
- if (result |= iterator.call(context, value, index, list)) return breaker;
200
+ if (result || (result = iterator.call(context, value, index, list))) return breaker;
191
201
  });
192
202
  return !!result;
193
203
  };
@@ -198,8 +208,8 @@
198
208
  var found = false;
199
209
  if (obj == null) return found;
200
210
  if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
201
- any(obj, function(value) {
202
- if (found = value === target) return true;
211
+ found = any(obj, function(value) {
212
+ return value === target;
203
213
  });
204
214
  return found;
205
215
  };
@@ -220,6 +230,7 @@
220
230
  // Return the maximum element or (element-based computation).
221
231
  _.max = function(obj, iterator, context) {
222
232
  if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
233
+ if (!iterator && _.isEmpty(obj)) return -Infinity;
223
234
  var result = {computed : -Infinity};
224
235
  each(obj, function(value, index, list) {
225
236
  var computed = iterator ? iterator.call(context, value, index, list) : value;
@@ -231,6 +242,7 @@
231
242
  // Return the minimum element (or element-based computation).
232
243
  _.min = function(obj, iterator, context) {
233
244
  if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
245
+ if (!iterator && _.isEmpty(obj)) return Infinity;
234
246
  var result = {computed : Infinity};
235
247
  each(obj, function(value, index, list) {
236
248
  var computed = iterator ? iterator.call(context, value, index, list) : value;
@@ -239,6 +251,21 @@
239
251
  return result.value;
240
252
  };
241
253
 
254
+ // Shuffle an array.
255
+ _.shuffle = function(obj) {
256
+ var shuffled = [], rand;
257
+ each(obj, function(value, index, list) {
258
+ if (index == 0) {
259
+ shuffled[0] = value;
260
+ } else {
261
+ rand = Math.floor(Math.random() * (index + 1));
262
+ shuffled[index] = shuffled[rand];
263
+ shuffled[rand] = value;
264
+ }
265
+ });
266
+ return shuffled;
267
+ };
268
+
242
269
  // Sort the object's values by a criterion produced by an iterator.
243
270
  _.sortBy = function(obj, iterator, context) {
244
271
  return _.pluck(_.map(obj, function(value, index, list) {
@@ -252,9 +279,11 @@
252
279
  }), 'value');
253
280
  };
254
281
 
255
- // Groups the object's values by a criterion produced by an iterator
256
- _.groupBy = function(obj, iterator) {
282
+ // Groups the object's values by a criterion. Pass either a string attribute
283
+ // to group by, or a function that returns the criterion.
284
+ _.groupBy = function(obj, val) {
257
285
  var result = {};
286
+ var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
258
287
  each(obj, function(value, index) {
259
288
  var key = iterator(value, index);
260
289
  (result[key] || (result[key] = [])).push(value);
@@ -298,6 +327,24 @@
298
327
  return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
299
328
  };
300
329
 
330
+ // Returns everything but the last entry of the array. Especcialy useful on
331
+ // the arguments object. Passing **n** will return all the values in
332
+ // the array, excluding the last N. The **guard** check allows it to work with
333
+ // `_.map`.
334
+ _.initial = function(array, n, guard) {
335
+ return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
336
+ };
337
+
338
+ // Get the last element of an array. Passing **n** will return the last N
339
+ // values in the array. The **guard** check allows it to work with `_.map`.
340
+ _.last = function(array, n, guard) {
341
+ if ((n != null) && !guard) {
342
+ return slice.call(array, Math.max(array.length - n, 0));
343
+ } else {
344
+ return array[array.length - 1];
345
+ }
346
+ };
347
+
301
348
  // Returns everything but the first entry of the array. Aliased as `tail`.
302
349
  // Especially useful on the arguments object. Passing an **index** will return
303
350
  // the rest of the values in the array from that index onward. The **guard**
@@ -306,20 +353,15 @@
306
353
  return slice.call(array, (index == null) || guard ? 1 : index);
307
354
  };
308
355
 
309
- // Get the last element of an array.
310
- _.last = function(array) {
311
- return array[array.length - 1];
312
- };
313
-
314
356
  // Trim out all falsy values from an array.
315
357
  _.compact = function(array) {
316
358
  return _.filter(array, function(value){ return !!value; });
317
359
  };
318
360
 
319
361
  // Return a completely flattened version of an array.
320
- _.flatten = function(array) {
362
+ _.flatten = function(array, shallow) {
321
363
  return _.reduce(array, function(memo, value) {
322
- if (_.isArray(value)) return memo.concat(_.flatten(value));
364
+ if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
323
365
  memo[memo.length] = value;
324
366
  return memo;
325
367
  }, []);
@@ -333,17 +375,23 @@
333
375
  // Produce a duplicate-free version of the array. If the array has already
334
376
  // been sorted, you have the option of using a faster algorithm.
335
377
  // Aliased as `unique`.
336
- _.uniq = _.unique = function(array, isSorted) {
337
- return _.reduce(array, function(memo, el, i) {
338
- if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el;
378
+ _.uniq = _.unique = function(array, isSorted, iterator) {
379
+ var initial = iterator ? _.map(array, iterator) : array;
380
+ var result = [];
381
+ _.reduce(initial, function(memo, el, i) {
382
+ if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
383
+ memo[memo.length] = el;
384
+ result[result.length] = array[i];
385
+ }
339
386
  return memo;
340
387
  }, []);
388
+ return result;
341
389
  };
342
390
 
343
391
  // Produce an array that contains the union: each distinct element from all of
344
392
  // the passed-in arrays.
345
393
  _.union = function() {
346
- return _.uniq(_.flatten(arguments));
394
+ return _.uniq(_.flatten(arguments, true));
347
395
  };
348
396
 
349
397
  // Produce an array that contains every item shared between all the
@@ -357,10 +405,11 @@
357
405
  });
358
406
  };
359
407
 
360
- // Take the difference between one array and another.
408
+ // Take the difference between one array and a number of other arrays.
361
409
  // Only the elements present in just the first array will remain.
362
- _.difference = function(array, other) {
363
- return _.filter(array, function(value){ return !_.include(other, value); });
410
+ _.difference = function(array) {
411
+ var rest = _.flatten(slice.call(arguments, 1));
412
+ return _.filter(array, function(value){ return !_.include(rest, value); });
364
413
  };
365
414
 
366
415
  // Zip together multiple lists into a single array -- elements that share
@@ -387,17 +436,16 @@
387
436
  return array[i] === item ? i : -1;
388
437
  }
389
438
  if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
390
- for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
439
+ for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;
391
440
  return -1;
392
441
  };
393
442
 
394
-
395
443
  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
396
444
  _.lastIndexOf = function(array, item) {
397
445
  if (array == null) return -1;
398
446
  if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
399
447
  var i = array.length;
400
- while (i--) if (array[i] === item) return i;
448
+ while (i--) if (i in array && array[i] === item) return i;
401
449
  return -1;
402
450
  };
403
451
 
@@ -426,15 +474,25 @@
426
474
  // Function (ahem) Functions
427
475
  // ------------------
428
476
 
477
+ // Reusable constructor function for prototype setting.
478
+ var ctor = function(){};
479
+
429
480
  // Create a function bound to a given object (assigning `this`, and arguments,
430
481
  // optionally). Binding with arguments is also known as `curry`.
431
482
  // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
432
483
  // We check for `func.bind` first, to fail fast when `func` is undefined.
433
- _.bind = function(func, obj) {
484
+ _.bind = function bind(func, context) {
485
+ var bound, args;
434
486
  if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
435
- var args = slice.call(arguments, 2);
436
- return function() {
437
- return func.apply(obj, args.concat(slice.call(arguments)));
487
+ if (!_.isFunction(func)) throw new TypeError;
488
+ args = slice.call(arguments, 2);
489
+ return bound = function() {
490
+ if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
491
+ ctor.prototype = func.prototype;
492
+ var self = new ctor;
493
+ var result = func.apply(self, args.concat(slice.call(arguments)));
494
+ if (Object(result) === result) return result;
495
+ return self;
438
496
  };
439
497
  };
440
498
 
@@ -470,31 +528,43 @@
470
528
  return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
471
529
  };
472
530
 
473
- // Internal function used to implement `_.throttle` and `_.debounce`.
474
- var limit = function(func, wait, debounce) {
475
- var timeout;
531
+ // Returns a function, that, when invoked, will only be triggered at most once
532
+ // during a given window of time.
533
+ _.throttle = function(func, wait) {
534
+ var context, args, timeout, throttling, more;
535
+ var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
476
536
  return function() {
477
- var context = this, args = arguments;
478
- var throttler = function() {
537
+ context = this; args = arguments;
538
+ var later = function() {
479
539
  timeout = null;
480
- func.apply(context, args);
540
+ if (more) func.apply(context, args);
541
+ whenDone();
481
542
  };
482
- if (debounce) clearTimeout(timeout);
483
- if (debounce || !timeout) timeout = setTimeout(throttler, wait);
543
+ if (!timeout) timeout = setTimeout(later, wait);
544
+ if (throttling) {
545
+ more = true;
546
+ } else {
547
+ func.apply(context, args);
548
+ }
549
+ whenDone();
550
+ throttling = true;
484
551
  };
485
552
  };
486
553
 
487
- // Returns a function, that, when invoked, will only be triggered at most once
488
- // during a given window of time.
489
- _.throttle = function(func, wait) {
490
- return limit(func, wait, false);
491
- };
492
-
493
554
  // Returns a function, that, as long as it continues to be invoked, will not
494
555
  // be triggered. The function will be called after it stops being called for
495
556
  // N milliseconds.
496
557
  _.debounce = function(func, wait) {
497
- return limit(func, wait, true);
558
+ var timeout;
559
+ return function() {
560
+ var context = this, args = arguments;
561
+ var later = function() {
562
+ timeout = null;
563
+ func.apply(context, args);
564
+ };
565
+ clearTimeout(timeout);
566
+ timeout = setTimeout(later, wait);
567
+ };
498
568
  };
499
569
 
500
570
  // Returns a function that will be executed at most one time, no matter how
@@ -513,7 +583,7 @@
513
583
  // conditionally execute the original function.
514
584
  _.wrap = function(func, wrapper) {
515
585
  return function() {
516
- var args = [func].concat(slice.call(arguments));
586
+ var args = concat.apply([func], arguments);
517
587
  return wrapper.apply(this, args);
518
588
  };
519
589
  };
@@ -521,9 +591,9 @@
521
591
  // Returns a function that is the composition of a list of functions, each
522
592
  // consuming the return value of the function that follows.
523
593
  _.compose = function() {
524
- var funcs = slice.call(arguments);
594
+ var funcs = arguments;
525
595
  return function() {
526
- var args = slice.call(arguments);
596
+ var args = arguments;
527
597
  for (var i = funcs.length - 1; i >= 0; i--) {
528
598
  args = [funcs[i].apply(this, args)];
529
599
  }
@@ -533,12 +603,12 @@
533
603
 
534
604
  // Returns a function that will only be executed after being called N times.
535
605
  _.after = function(times, func) {
606
+ if (times <= 0) return func();
536
607
  return function() {
537
608
  if (--times < 1) { return func.apply(this, arguments); }
538
609
  };
539
610
  };
540
611
 
541
-
542
612
  // Object Functions
543
613
  // ----------------
544
614
 
@@ -588,6 +658,7 @@
588
658
 
589
659
  // Create a (shallow-cloned) duplicate of an object.
590
660
  _.clone = function(obj) {
661
+ if (!_.isObject(obj)) return obj;
591
662
  return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
592
663
  };
593
664
 
@@ -599,47 +670,101 @@
599
670
  return obj;
600
671
  };
601
672
 
602
- // Perform a deep comparison to check if two objects are equal.
603
- _.isEqual = function(a, b) {
604
- // Check object identity.
605
- if (a === b) return true;
606
- // Different types?
607
- var atype = typeof(a), btype = typeof(b);
608
- if (atype != btype) return false;
609
- // Basic equality test (watch out for coercions).
610
- if (a == b) return true;
611
- // One is falsy and the other truthy.
612
- if ((!a && b) || (a && !b)) return false;
673
+ // Internal recursive comparison function.
674
+ function eq(a, b, stack) {
675
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
676
+ // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
677
+ if (a === b) return a !== 0 || 1 / a == 1 / b;
678
+ // A strict comparison is necessary because `null == undefined`.
679
+ if (a == null || b == null) return a === b;
613
680
  // Unwrap any wrapped objects.
614
681
  if (a._chain) a = a._wrapped;
615
682
  if (b._chain) b = b._wrapped;
616
- // One of them implements an isEqual()?
617
- if (a.isEqual) return a.isEqual(b);
618
- if (b.isEqual) return b.isEqual(a);
619
- // Check dates' integer values.
620
- if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
621
- // Both are NaN?
622
- if (_.isNaN(a) && _.isNaN(b)) return false;
623
- // Compare regular expressions.
624
- if (_.isRegExp(a) && _.isRegExp(b))
625
- return a.source === b.source &&
626
- a.global === b.global &&
627
- a.ignoreCase === b.ignoreCase &&
628
- a.multiline === b.multiline;
629
- // If a is not an object by this point, we can't handle it.
630
- if (atype !== 'object') return false;
631
- // Check for different array lengths before comparing contents.
632
- if (a.length && (a.length !== b.length)) return false;
633
- // Nothing else worked, deep compare the contents.
634
- var aKeys = _.keys(a), bKeys = _.keys(b);
635
- // Different object sizes?
636
- if (aKeys.length != bKeys.length) return false;
637
- // Recursive comparison of contents.
638
- for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false;
639
- return true;
683
+ // Invoke a custom `isEqual` method if one is provided.
684
+ if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
685
+ if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
686
+ // Compare `[[Class]]` names.
687
+ var className = toString.call(a);
688
+ if (className != toString.call(b)) return false;
689
+ switch (className) {
690
+ // Strings, numbers, dates, and booleans are compared by value.
691
+ case '[object String]':
692
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
693
+ // equivalent to `new String("5")`.
694
+ return a == String(b);
695
+ case '[object Number]':
696
+ // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
697
+ // other numeric values.
698
+ return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
699
+ case '[object Date]':
700
+ case '[object Boolean]':
701
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
702
+ // millisecond representations. Note that invalid dates with millisecond representations
703
+ // of `NaN` are not equivalent.
704
+ return +a == +b;
705
+ // RegExps are compared by their source patterns and flags.
706
+ case '[object RegExp]':
707
+ return a.source == b.source &&
708
+ a.global == b.global &&
709
+ a.multiline == b.multiline &&
710
+ a.ignoreCase == b.ignoreCase;
711
+ }
712
+ if (typeof a != 'object' || typeof b != 'object') return false;
713
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
714
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
715
+ var length = stack.length;
716
+ while (length--) {
717
+ // Linear search. Performance is inversely proportional to the number of
718
+ // unique nested structures.
719
+ if (stack[length] == a) return true;
720
+ }
721
+ // Add the first object to the stack of traversed objects.
722
+ stack.push(a);
723
+ var size = 0, result = true;
724
+ // Recursively compare objects and arrays.
725
+ if (className == '[object Array]') {
726
+ // Compare array lengths to determine if a deep comparison is necessary.
727
+ size = a.length;
728
+ result = size == b.length;
729
+ if (result) {
730
+ // Deep compare the contents, ignoring non-numeric properties.
731
+ while (size--) {
732
+ // Ensure commutative equality for sparse arrays.
733
+ if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
734
+ }
735
+ }
736
+ } else {
737
+ // Objects with different constructors are not equivalent.
738
+ if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
739
+ // Deep compare objects.
740
+ for (var key in a) {
741
+ if (hasOwnProperty.call(a, key)) {
742
+ // Count the expected number of properties.
743
+ size++;
744
+ // Deep compare each member.
745
+ if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
746
+ }
747
+ }
748
+ // Ensure that both objects contain the same number of properties.
749
+ if (result) {
750
+ for (key in b) {
751
+ if (hasOwnProperty.call(b, key) && !(size--)) break;
752
+ }
753
+ result = !size;
754
+ }
755
+ }
756
+ // Remove the first object from the stack of traversed objects.
757
+ stack.pop();
758
+ return result;
759
+ }
760
+
761
+ // Perform a deep comparison to check if two objects are equal.
762
+ _.isEqual = function(a, b) {
763
+ return eq(a, b, []);
640
764
  };
641
765
 
642
- // Is a given array or object empty?
766
+ // Is a given array, string, or object empty?
767
+ // An "empty" object has no enumerable own-properties.
643
768
  _.isEmpty = function(obj) {
644
769
  if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
645
770
  for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
@@ -654,7 +779,7 @@
654
779
  // Is a given value an array?
655
780
  // Delegates to ECMA5's native Array.isArray
656
781
  _.isArray = nativeIsArray || function(obj) {
657
- return toString.call(obj) === '[object Array]';
782
+ return toString.call(obj) == '[object Array]';
658
783
  };
659
784
 
660
785
  // Is a given variable an object?
@@ -664,43 +789,48 @@
664
789
 
665
790
  // Is a given variable an arguments object?
666
791
  _.isArguments = function(obj) {
667
- return !!(obj && hasOwnProperty.call(obj, 'callee'));
792
+ return toString.call(obj) == '[object Arguments]';
668
793
  };
794
+ if (!_.isArguments(arguments)) {
795
+ _.isArguments = function(obj) {
796
+ return !!(obj && hasOwnProperty.call(obj, 'callee'));
797
+ };
798
+ }
669
799
 
670
800
  // Is a given value a function?
671
801
  _.isFunction = function(obj) {
672
- return !!(obj && obj.constructor && obj.call && obj.apply);
802
+ return toString.call(obj) == '[object Function]';
673
803
  };
674
804
 
675
805
  // Is a given value a string?
676
806
  _.isString = function(obj) {
677
- return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
807
+ return toString.call(obj) == '[object String]';
678
808
  };
679
809
 
680
810
  // Is a given value a number?
681
811
  _.isNumber = function(obj) {
682
- return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
812
+ return toString.call(obj) == '[object Number]';
683
813
  };
684
814
 
685
- // Is the given value `NaN`? `NaN` happens to be the only value in JavaScript
686
- // that does not equal itself.
815
+ // Is the given value `NaN`?
687
816
  _.isNaN = function(obj) {
817
+ // `NaN` is the only value for which `===` is not reflexive.
688
818
  return obj !== obj;
689
819
  };
690
820
 
691
821
  // Is a given value a boolean?
692
822
  _.isBoolean = function(obj) {
693
- return obj === true || obj === false;
823
+ return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
694
824
  };
695
825
 
696
826
  // Is a given value a date?
697
827
  _.isDate = function(obj) {
698
- return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
828
+ return toString.call(obj) == '[object Date]';
699
829
  };
700
830
 
701
831
  // Is the given value a regular expression?
702
832
  _.isRegExp = function(obj) {
703
- return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
833
+ return toString.call(obj) == '[object RegExp]';
704
834
  };
705
835
 
706
836
  // Is a given value equal to null?
@@ -733,6 +863,11 @@
733
863
  for (var i = 0; i < n; i++) iterator.call(context, i);
734
864
  };
735
865
 
866
+ // Escape a string for HTML interpolation.
867
+ _.escape = function(string) {
868
+ return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
869
+ };
870
+
736
871
  // Add your own custom functions to the Underscore object, ensuring that
737
872
  // they're correctly added to the OOP wrapper as well.
738
873
  _.mixin = function(obj) {
@@ -753,7 +888,8 @@
753
888
  // following template settings to use alternative delimiters.
754
889
  _.templateSettings = {
755
890
  evaluate : /<%([\s\S]+?)%>/g,
756
- interpolate : /<%=([\s\S]+?)%>/g
891
+ interpolate : /<%=([\s\S]+?)%>/g,
892
+ escape : /<%-([\s\S]+?)%>/g
757
893
  };
758
894
 
759
895
  // JavaScript micro-templating, similar to John Resig's implementation.
@@ -765,19 +901,25 @@
765
901
  'with(obj||{}){__p.push(\'' +
766
902
  str.replace(/\\/g, '\\\\')
767
903
  .replace(/'/g, "\\'")
904
+ .replace(c.escape, function(match, code) {
905
+ return "',_.escape(" + code.replace(/\\'/g, "'") + "),'";
906
+ })
768
907
  .replace(c.interpolate, function(match, code) {
769
908
  return "'," + code.replace(/\\'/g, "'") + ",'";
770
909
  })
771
910
  .replace(c.evaluate || null, function(match, code) {
772
911
  return "');" + code.replace(/\\'/g, "'")
773
- .replace(/[\r\n\t]/g, ' ') + "__p.push('";
912
+ .replace(/[\r\n\t]/g, ' ') + ";__p.push('";
774
913
  })
775
914
  .replace(/\r/g, '\\r')
776
915
  .replace(/\n/g, '\\n')
777
916
  .replace(/\t/g, '\\t')
778
917
  + "');}return __p.join('');";
779
- var func = new Function('obj', tmpl);
780
- return data ? func(data) : func;
918
+ var func = new Function('obj', '_', tmpl);
919
+ if (data) return func(data, _);
920
+ return function(data) {
921
+ return func.call(this, data, _);
922
+ };
781
923
  };
782
924
 
783
925
  // The OOP Wrapper
@@ -836,4 +978,4 @@
836
978
  return this._wrapped;
837
979
  };
838
980
 
839
- })();
981
+ }).call(this);
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appetizer-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-10 00:00:00.000000000Z
12
+ date: 2011-12-12 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: appetizer
16
- requirement: &70315760400600 !ruby/object:Gem::Requirement
16
+ requirement: &70137630941620 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70315760400600
24
+ version_requirements: *70137630941620
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: coffee-script
27
- requirement: &70315760400140 !ruby/object:Gem::Requirement
27
+ requirement: &70137630940840 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '2.2'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70315760400140
35
+ version_requirements: *70137630940840
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: eco
38
- requirement: &70315760399680 !ruby/object:Gem::Requirement
38
+ requirement: &70137630940280 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '1.0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70315760399680
46
+ version_requirements: *70137630940280
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rack-ssl
49
- requirement: &70315760399220 !ruby/object:Gem::Requirement
49
+ requirement: &70137630939820 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '1.3'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70315760399220
57
+ version_requirements: *70137630939820
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: sass
60
- requirement: &70315760398760 !ruby/object:Gem::Requirement
60
+ requirement: &70137630939200 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '3.1'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70315760398760
68
+ version_requirements: *70137630939200
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sinatra
71
- requirement: &70315760398300 !ruby/object:Gem::Requirement
71
+ requirement: &70137630938700 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '1.3'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *70315760398300
79
+ version_requirements: *70137630938700
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: sprockets
82
- requirement: &70315760397840 !ruby/object:Gem::Requirement
82
+ requirement: &70137630938240 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '2.1'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *70315760397840
90
+ version_requirements: *70137630938240
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: uglifier
93
- requirement: &70315760397380 !ruby/object:Gem::Requirement
93
+ requirement: &70137630937780 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ~>
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '1.0'
99
99
  type: :runtime
100
100
  prerelease: false
101
- version_requirements: *70315760397380
101
+ version_requirements: *70137630937780
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: yajl-ruby
104
- requirement: &70315760396920 !ruby/object:Gem::Requirement
104
+ requirement: &70137630937320 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ~>
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: '1.0'
110
110
  type: :runtime
111
111
  prerelease: false
112
- version_requirements: *70315760396920
112
+ version_requirements: *70137630937320
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: yui-compressor
115
- requirement: &70315760396460 !ruby/object:Gem::Requirement
115
+ requirement: &70137630936800 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ~>
@@ -120,7 +120,7 @@ dependencies:
120
120
  version: '0.9'
121
121
  type: :runtime
122
122
  prerelease: false
123
- version_requirements: *70315760396460
123
+ version_requirements: *70137630936800
124
124
  description: A painfully opinionated Appetizer extension for web apps.
125
125
  email:
126
126
  - tech@audiosocket.com